Skip to content

Commit f6d2af1

Browse files
gkalpakSplaktar
authored andcommitted
fix(docs-infra): preserve focus on copy (and prevent scrolling to bottom on IE11) (angular#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 angular#37796 PR Close angular#38244
1 parent a86754b commit f6d2af1

File tree

1 file changed

+9
-0
lines changed

1 file changed

+9
-0
lines changed

aio/src/app/shared/copier.service.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
* - https://github.com/zenorocha/clipboard.js/
66
*
77
* Both released under MIT license - © Zeno Rocha
8+
*
9+
* It is also influenced by the Angular CDK `PendingCopy` class:
10+
* https://github.com/angular/components/blob/master/src/cdk/clipboard/pending-copy.ts
811
*/
912

1013

@@ -18,13 +21,19 @@ export class CopierService {
1821
* @return Whether the copy operation was successful.
1922
*/
2023
private copyTextArea(textArea: HTMLTextAreaElement): boolean {
24+
const currentFocus = document.activeElement as HTMLOrSVGElement | null;
25+
2126
try {
2227
textArea.select();
2328
textArea.setSelectionRange(0, textArea.value.length);
2429

2530
return document.execCommand('copy');
2631
} catch {
2732
return false;
33+
} finally {
34+
// Calling `.select()` on the `<textarea>` element may have also focused it.
35+
// Change the focus back to the previously focused element.
36+
currentFocus?.focus();
2837
}
2938
}
3039

0 commit comments

Comments
 (0)