From 1798e84fc6c05fde5f281d524fdec0e727dba2a5 Mon Sep 17 00:00:00 2001 From: Aditi Ohri Date: Fri, 1 Apr 2022 12:16:19 -0500 Subject: [PATCH 1/5] fix(clipboard): add isSecureContext check --- elements/pfe-clipboard/pfe-clipboard.ts | 63 +++++++++++++++++++------ 1 file changed, 48 insertions(+), 15 deletions(-) diff --git a/elements/pfe-clipboard/pfe-clipboard.ts b/elements/pfe-clipboard/pfe-clipboard.ts index 16420496ec..aa632000e6 100644 --- a/elements/pfe-clipboard/pfe-clipboard.ts +++ b/elements/pfe-clipboard/pfe-clipboard.ts @@ -76,6 +76,7 @@ export class PfeClipboard extends LitElement { static readonly styles = [style]; + /** * Optional boolean attribute that, when present, removes the icon from the template. */ @@ -104,6 +105,17 @@ export class PfeClipboard extends LitElement { @property({ type: String, reflect: true, attribute: 'copy-from' }) copyFrom: string|'url'|'property' = 'url'; + /** + * Specify if current site is behind [https] + */ + @state() private _secure = window.isSecureContext; // is there a way to test this without manually setting this var to false? + + /** + * Specify the copy type to be used depending on security and browser support + */ + @property({ type: String || null }) copyType: 'navigator'|'queryCommand'| null = null; + + /** * A setter to set the content you would like to copy. * Only works if copy-from attribute is set to property. @@ -137,6 +149,8 @@ export class PfeClipboard extends LitElement { this.dispatchEvent(deprecatedCustomEvent('pfe-clipboard:connected', { component: this })); + this._setCopyType(); + // This prevents a regression, default text used to be "Copy URL". // Now that component can copy _anything_ that's not ideal default text if (this.copyFrom === 'url' && !this.slots.hasSlotted('text')) { @@ -229,6 +243,25 @@ export class PfeClipboard extends LitElement { } } + /** + * Sets copy type depending on whether or not the current site is secure + */ + @bound private _setCopyType() { + if (navigator.clipboard) { + if (this._secure) { + this.copyType = 'navigator'; + } else { + this.setAttribute('hidden', ''); + throw new Error('Browser supports navigator.clipboard API but current website is not behind [https] required by the specification. https://developer.mozilla.org/en-US/docs/Web/API/Clipboard'); + } + } else if (document.queryCommandEnabled('copy')) { + this.copyType = 'queryCommand'; + } else { + this.setAttribute('hidden', ''); + throw new Error('Browser does not support copying to the clipboard.'); + } + } + /** * Event handler for any activation of the copy button */ @@ -374,22 +407,22 @@ export class PfeClipboard extends LitElement { if (!text) { this.logger.error('Copy function called, but no text was given to copy.'); } - if (navigator.clipboard) { - // If the Clipboard API is available then use that - await navigator.clipboard.writeText(text); - return text; - } else if (document.queryCommandEnabled('copy')) { - // If execCommand("copy") exists then use that method - const dummy = document.createElement('input'); - document.body.appendChild(dummy); - dummy.value = text; - dummy.select(); - document.execCommand('copy'); - document.body.removeChild(dummy); - return text; - } else { - throw new Error('Current browser does not support copying to the clipboard.'); + + switch (this.copyType) { + case 'navigator': + await navigator.clipboard.writeText(text); + break; + case 'queryCommand': { + const dummy = document.createElement('input'); + document.body.appendChild(dummy); + dummy.value = text; + dummy.select(); + document.execCommand('copy'); + document.body.removeChild(dummy); + break; + } } + return text; } } From c5d4679588d399816b40f2ef5d71bb4ac092f556 Mon Sep 17 00:00:00 2001 From: Aditi Ohri Date: Mon, 4 Apr 2022 15:56:45 -0500 Subject: [PATCH 2/5] fix(clipboard): hide button from screenreader if visually hidden --- elements/pfe-clipboard/pfe-clipboard.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/elements/pfe-clipboard/pfe-clipboard.ts b/elements/pfe-clipboard/pfe-clipboard.ts index aa632000e6..2962b104ce 100644 --- a/elements/pfe-clipboard/pfe-clipboard.ts +++ b/elements/pfe-clipboard/pfe-clipboard.ts @@ -108,7 +108,7 @@ export class PfeClipboard extends LitElement { /** * Specify if current site is behind [https] */ - @state() private _secure = window.isSecureContext; // is there a way to test this without manually setting this var to false? + @state() private _secure = window.isSecureContext; /** * Specify the copy type to be used depending on security and browser support @@ -252,12 +252,14 @@ export class PfeClipboard extends LitElement { this.copyType = 'navigator'; } else { this.setAttribute('hidden', ''); + this._ariaDisabled = true; throw new Error('Browser supports navigator.clipboard API but current website is not behind [https] required by the specification. https://developer.mozilla.org/en-US/docs/Web/API/Clipboard'); } } else if (document.queryCommandEnabled('copy')) { this.copyType = 'queryCommand'; } else { this.setAttribute('hidden', ''); + this._ariaDisabled = true; throw new Error('Browser does not support copying to the clipboard.'); } } From 4f93dfc3877086acf66c43081ce251524ce4edf5 Mon Sep 17 00:00:00 2001 From: Steven Spriggs Date: Thu, 14 Apr 2022 09:48:28 -0400 Subject: [PATCH 3/5] style(clipboard): linting --- elements/pfe-clipboard/pfe-clipboard.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/elements/pfe-clipboard/pfe-clipboard.ts b/elements/pfe-clipboard/pfe-clipboard.ts index 2962b104ce..d3f7c2a27a 100644 --- a/elements/pfe-clipboard/pfe-clipboard.ts +++ b/elements/pfe-clipboard/pfe-clipboard.ts @@ -76,7 +76,6 @@ export class PfeClipboard extends LitElement { static readonly styles = [style]; - /** * Optional boolean attribute that, when present, removes the icon from the template. */ @@ -113,7 +112,7 @@ export class PfeClipboard extends LitElement { /** * Specify the copy type to be used depending on security and browser support */ - @property({ type: String || null }) copyType: 'navigator'|'queryCommand'| null = null; + @property({ type: String }) copyType: 'navigator' | 'queryCommand' | null = null; /** From e240c4b135d2b455e4bfa0675df0b849a2cdd7c8 Mon Sep 17 00:00:00 2001 From: Steven Spriggs Date: Thu, 14 Apr 2022 12:29:14 -0400 Subject: [PATCH 4/5] fix(clipboard): failover to execCommand, remove decorators --- elements/pfe-clipboard/pfe-clipboard.ts | 27 ++++++++----------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/elements/pfe-clipboard/pfe-clipboard.ts b/elements/pfe-clipboard/pfe-clipboard.ts index d3f7c2a27a..1580ec3968 100644 --- a/elements/pfe-clipboard/pfe-clipboard.ts +++ b/elements/pfe-clipboard/pfe-clipboard.ts @@ -107,13 +107,12 @@ export class PfeClipboard extends LitElement { /** * Specify if current site is behind [https] */ - @state() private _secure = window.isSecureContext; + private _secure = window.isSecureContext; /** * Specify the copy type to be used depending on security and browser support */ - @property({ type: String }) copyType: 'navigator' | 'queryCommand' | null = null; - + private _copyType: 'navigator' | 'queryCommand' | null = null; /** * A setter to set the content you would like to copy. @@ -226,7 +225,7 @@ export class PfeClipboard extends LitElement { /** * Checks to make sure the thing we may copy exists */ - @bound private _checkForCopyTarget() { + private _checkForCopyTarget() { if (this.copyFrom === 'property') { if (!this.contentToCopy) { this.setAttribute('disabled', ''); @@ -245,21 +244,11 @@ export class PfeClipboard extends LitElement { /** * Sets copy type depending on whether or not the current site is secure */ - @bound private _setCopyType() { - if (navigator.clipboard) { - if (this._secure) { - this.copyType = 'navigator'; - } else { - this.setAttribute('hidden', ''); - this._ariaDisabled = true; - throw new Error('Browser supports navigator.clipboard API but current website is not behind [https] required by the specification. https://developer.mozilla.org/en-US/docs/Web/API/Clipboard'); - } - } else if (document.queryCommandEnabled('copy')) { - this.copyType = 'queryCommand'; + private _setCopyType() { + if (this._secure && navigator.clipboard) { + this._copyType = 'navigator'; } else { - this.setAttribute('hidden', ''); - this._ariaDisabled = true; - throw new Error('Browser does not support copying to the clipboard.'); + this._copyType = 'queryCommand'; } } @@ -409,7 +398,7 @@ export class PfeClipboard extends LitElement { this.logger.error('Copy function called, but no text was given to copy.'); } - switch (this.copyType) { + switch (this._copyType) { case 'navigator': await navigator.clipboard.writeText(text); break; From 7e42bdb9eb3d0687ac726c4b3a94876cb823fd76 Mon Sep 17 00:00:00 2001 From: heyMP Date: Thu, 14 Apr 2022 13:49:23 -0400 Subject: [PATCH 5/5] chore: add changeset --- .changeset/real-forks-type.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/real-forks-type.md diff --git a/.changeset/real-forks-type.md b/.changeset/real-forks-type.md new file mode 100644 index 0000000000..46940edf23 --- /dev/null +++ b/.changeset/real-forks-type.md @@ -0,0 +1,5 @@ +--- +"@patternfly/pfe-clipboard": patch +--- + +pfe-clipboard: add fallback check for http traffic on browsers that support navigator.