fix(docs-infra): preserve focus on copy (and prevent scrolling to bottom on IE11) (#38244)
The `CopierService` is used for copying text to the user's clipboard. It is, for example, used in `CodeComponent` to copy example code snippets. This is implemented by creating a temporary, hidden `<textarea>` elements, setting its value to the text that needs to be copied, executing the `copy` command and finally removing the element from the DOM. Previously, as a result of `CopierService`'s implementation, the focused element would lose focus, while the temporary `<textarea>` element would implicitly gain focus when selecting its contents. This had an even worse side-effect on IE11, which seems to scroll to the bottom of the containing element (here `<body>`) when the focused element is removed. This commit fixes these issues by keeping track of the previously focused element and restoring its focus after the copy operation. NOTE: This fix is inspired by Angular CDK's [PendingCopy][1] class. [1]: https://github.com/angular/components/blob/89b5fa89d1437c3054c5/src/cdk/clipboard/pending-copy.ts Fixes #37796 PR Close #38244
This commit is contained in:
parent
a86754b4c4
commit
f6d2af17fc
@ -5,6 +5,9 @@
|
|||||||
* - https://github.com/zenorocha/clipboard.js/
|
* - https://github.com/zenorocha/clipboard.js/
|
||||||
*
|
*
|
||||||
* Both released under MIT license - © Zeno Rocha
|
* Both released under MIT license - © Zeno Rocha
|
||||||
|
*
|
||||||
|
* It is also influenced by the Angular CDK `PendingCopy` class:
|
||||||
|
* https://github.com/angular/components/blob/master/src/cdk/clipboard/pending-copy.ts
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -18,6 +21,8 @@ export class CopierService {
|
|||||||
* @return Whether the copy operation was successful.
|
* @return Whether the copy operation was successful.
|
||||||
*/
|
*/
|
||||||
private copyTextArea(textArea: HTMLTextAreaElement): boolean {
|
private copyTextArea(textArea: HTMLTextAreaElement): boolean {
|
||||||
|
const currentFocus = document.activeElement as HTMLOrSVGElement | null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
textArea.select();
|
textArea.select();
|
||||||
textArea.setSelectionRange(0, textArea.value.length);
|
textArea.setSelectionRange(0, textArea.value.length);
|
||||||
@ -25,6 +30,10 @@ export class CopierService {
|
|||||||
return document.execCommand('copy');
|
return document.execCommand('copy');
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
|
} finally {
|
||||||
|
// Calling `.select()` on the `<textarea>` element may have also focused it.
|
||||||
|
// Change the focus back to the previously focused element.
|
||||||
|
currentFocus?.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user