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
9ebd461a22
commit
d96824acdb
|
@ -5,6 +5,9 @@
|
|||
* - https://github.com/zenorocha/clipboard.js/
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
private copyTextArea(textArea: HTMLTextAreaElement): boolean {
|
||||
const currentFocus = document.activeElement as HTMLOrSVGElement | null;
|
||||
|
||||
try {
|
||||
textArea.select();
|
||||
textArea.setSelectionRange(0, textArea.value.length);
|
||||
|
@ -25,6 +30,10 @@ export class CopierService {
|
|||
return document.execCommand('copy');
|
||||
} catch {
|
||||
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…
Reference in New Issue