Skip to content

Commit

Permalink
Copy text as HTML
Browse files Browse the repository at this point in the history
  • Loading branch information
Mohandasveena98 committed Feb 7, 2024
1 parent 4a4d2ce commit 069da75
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 19 deletions.
4 changes: 2 additions & 2 deletions projects/ngx-clipboard/src/lib/ngx-clipboard.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class ClipboardDirective implements OnInit, OnDestroy {
// https://github.com/maxisam/ngx-clipboard/issues/239#issuecomment-623330624
// eslint-disable-next-line @angular-eslint/no-input-rename
@Input('ngxClipboard')
public targetElm: HTMLInputElement | HTMLTextAreaElement | undefined | '';
public targetElm: HTMLInputElement | HTMLDivElement | undefined | '';
@Input()
public container: HTMLElement;

Expand Down Expand Up @@ -64,7 +64,7 @@ export class ClipboardDirective implements OnInit, OnDestroy {
if (!this.clipboardSrv.isSupported) {
this.handleResult(false, undefined, event);
} else if (this.targetElm && this.clipboardSrv.isTargetValid(this.targetElm)) {
this.handleResult(this.clipboardSrv.copyFromInputElement(this.targetElm), this.targetElm.value, event);
this.handleResult(this.clipboardSrv.copyFromInputElement(this.targetElm), this.cbContent, event);
} else if (this.cbContent) {
this.handleResult(this.clipboardSrv.copyFromContent(this.cbContent, this.container), this.cbContent, event);
}
Expand Down
51 changes: 34 additions & 17 deletions projects/ngx-clipboard/src/lib/ngx-clipboard.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export class ClipboardService {
private copySubject = new Subject<IClipboardResponse>();
public copyResponse$: Observable<IClipboardResponse> = this.copySubject.asObservable();
private tempTextArea: HTMLTextAreaElement | undefined;
private tempDivArea: HTMLDivElement | undefined;
private config: ClipboardParams = {};

constructor(
Expand Down Expand Up @@ -40,7 +41,7 @@ export class ClipboardService {
return !!this.document.queryCommandSupported && !!this.document.queryCommandSupported('copy') && !!this.window;
}

public isTargetValid(element: HTMLInputElement | HTMLTextAreaElement): boolean {
public isTargetValid(element: HTMLInputElement | HTMLDivElement): boolean {
if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {
if (element.hasAttribute('disabled')) {
throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');
Expand All @@ -53,9 +54,9 @@ export class ClipboardService {
/**
* Attempts to copy from an input `targetElm`
*/
public copyFromInputElement(targetElm: HTMLInputElement | HTMLTextAreaElement, isFocus = true): boolean {
public copyFromInputElement(targetElm: HTMLInputElement | HTMLDivElement, isFocus = true): boolean {
try {
this.selectTarget(targetElm);
//this.selectTarget(targetElm);
let re = this.copyText(targetElm);
this.clearSelection(isFocus ? targetElm : undefined, this.window);
return re && this.isCopySuccessInIE11();
Expand Down Expand Up @@ -84,22 +85,32 @@ export class ClipboardService {
public copyFromContent(content: string, container: HTMLElement = this.document.body): boolean {
// check if the temp textarea still belongs to the current container.
// In case we have multiple places using ngx-clipboard, one is in a modal using container but the other one is not.
if (this.tempTextArea && !container.contains(this.tempTextArea)) {
this.destroy(this.tempTextArea.parentElement || undefined);
if (this.tempDivArea && !container.contains(this.tempDivArea)) {
this.destroy(this.tempDivArea.parentElement || undefined);
}
// this.tempDivArea = document.createElement('div');
// this.tempDivArea.innerHTML = content;
// console.log(this.tempDivArea)
// document.body.appendChild(this.tempDivArea)
// navigator.clipboard.write([new ClipboardItem({
// 'text/plain': new Blob([this.tempDivArea.innerText], {type: 'text/plain'}),
// 'text/html': new Blob([this.tempDivArea.innerHTML], {type: 'text/html'})
// })])
// document.body.removeChild(this.tempDivArea)
if (!this.tempDivArea) {
this.tempDivArea = this.createTempTextArea(this.document, this.window);

if (!this.tempTextArea) {
this.tempTextArea = this.createTempTextArea(this.document, this.window);
try {
container.appendChild(this.tempTextArea);
container.appendChild(this.tempDivArea);
} catch (error) {
throw new Error('Container should be a Dom element');
}
}
this.tempTextArea.value = content;
const toReturn = this.copyFromInputElement(this.tempTextArea, false);
//this.tempTextArea.value = content;
this.tempDivArea.innerHTML = content;
const toReturn = this.copyFromInputElement(this.tempDivArea, false);
if (this.config.cleanUpAfterCopy) {
this.destroy(this.tempTextArea.parentElement || undefined);
this.destroy(this.tempDivArea.parentElement || undefined);
}
return toReturn;
}
Expand All @@ -124,26 +135,32 @@ export class ClipboardService {
return inputElement.value.length;
}

private copyText(targetElm: HTMLInputElement | HTMLTextAreaElement): boolean {
navigator.clipboard.writeText(targetElm.value);
private copyText(targetElm: HTMLInputElement | HTMLDivElement): boolean {
//navigator.clipboard.writeText(targetElm.value);
navigator.clipboard.write([
new ClipboardItem({
'text/plain': new Blob([targetElm.innerText], { type: 'text/plain' }),
'text/html': new Blob([targetElm.innerHTML], { type: 'text/html' })
})
]);
return true; //this.document.execCommand('copy');
}

/**
* Moves focus away from `target` and back to the trigger, removes current selection.
*/
private clearSelection(inputElement: HTMLInputElement | HTMLTextAreaElement | undefined, window: Window): void {
private clearSelection(inputElement: HTMLInputElement | HTMLDivElement | undefined, window: Window): void {
inputElement && inputElement.focus();
window.getSelection()?.removeAllRanges();
}

/**
* Creates a fake textarea for copy command.
*/
private createTempTextArea(doc: Document, window: Window): HTMLTextAreaElement {
private createTempTextArea(doc: Document, window: Window): HTMLDivElement {
const isRTL = doc.documentElement.getAttribute('dir') === 'rtl';
let ta: HTMLTextAreaElement;
ta = doc.createElement('textarea');
let ta: HTMLDivElement;
ta = doc.createElement('div');
// Prevent zooming on iOS
ta.style.fontSize = '12pt';
// Reset box model
Expand Down

0 comments on commit 069da75

Please sign in to comment.