Skip to content

Commit 66e57da

Browse files
authored
[A11y] Improve copy button accessibility (#8808)
The previous fix (#8758) seems to have broken after the latest Windows update. This new fix aligns with GitHub's solution to this problem. This solution "flashes" the aria label of the focused item, causing the screen reader to re-announce it. Addresses #8809
1 parent ce803dc commit 66e57da

4 files changed

Lines changed: 37 additions & 20 deletions

File tree

src/NuGetGallery/Scripts/gallery/page-display-package-v2.js

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,23 +50,31 @@
5050
// Configure package manager copy buttons
5151
function configureCopyButton(id) {
5252
var copyButton = $('#' + id + '-button');
53-
copyButton.popover({
54-
trigger: 'manual',
55-
// Windows Narrator does not announce popovers' content. See: https://github.com/twbs/bootstrap/issues/18618
56-
// We can force Narrator to announce the content by changing
57-
// the popover's role from 'tooltip' to 'status'.
58-
// Modified from: https://github.com/twbs/bootstrap/blob/f17f882df292b29323f1e1da515bd16f326cee4a/js/popover.js#L28
59-
template: '<div class="popover" role="status"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
60-
});
53+
var copyButtonDom = copyButton.get(0);
54+
copyButton.popover({ trigger: 'manual' });
6155

6256
copyButton.click(function () {
6357
var text = $('#' + id + '-text').text().trim();
6458
window.nuget.copyTextToClipboard(text, copyButton);
6559

6660
copyButton.popover('show');
61+
62+
// Windows Narrator does not announce popovers' content. See: https://github.com/twbs/bootstrap/issues/18618
63+
// We can force Narrator to announce the popover's content by "flashing"
64+
// the copy button's ARIA label.
65+
var originalLabel = copyButtonDom.ariaLabel;
66+
copyButtonDom.ariaLabel = "";
67+
6768
setTimeout(function () {
6869
copyButton.popover('destroy');
69-
}, 1000);
70+
71+
// We need to restore the copy button's original ARIA label.
72+
// Wait 0.15 seconds for the popover to fade away first.
73+
// Otherwise, the screen reader will re-announce the popover's content.
74+
setTimeout(function () {
75+
copyButtonDom.ariaLabel = originalLabel;
76+
}, 200);
77+
}, 1500);
7078

7179
window.nuget.sendMetric("CopyInstallCommand", 1, {
7280
ButtonId: id,

src/NuGetGallery/Scripts/gallery/page-display-package.js

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -90,22 +90,31 @@ $(function () {
9090
// Configure package manager copy buttons
9191
function configureCopyButton(id) {
9292
var copyButton = $('#' + id + '-button');
93-
copyButton.popover({
94-
trigger: 'manual',
95-
// Windows Narrator does not announce popovers' content. See: https://github.com/twbs/bootstrap/issues/18618
96-
// We can force Narrator to announce the content by changing
97-
// the popover's role from 'tooltip' to 'status'.
98-
// Modified from: https://github.com/twbs/bootstrap/blob/f17f882df292b29323f1e1da515bd16f326cee4a/js/popover.js#L28
99-
template: '<div class="popover" role="status"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
100-
});
93+
var copyButtonDom = copyButton.get(0);
94+
copyButton.popover({ trigger: 'manual' });
10195

10296
copyButton.click(function () {
10397
var text = $('#' + id + '-text').text().trim();
10498
window.nuget.copyTextToClipboard(text, copyButton);
10599
copyButton.popover('show');
100+
101+
// Windows Narrator does not announce popovers' content. See: https://github.com/twbs/bootstrap/issues/18618
102+
// We can force Narrator to announce the popover's content by "flashing"
103+
// the copy button's ARIA label.
104+
var originalLabel = copyButtonDom.ariaLabel;
105+
copyButtonDom.ariaLabel = "";
106+
106107
setTimeout(function () {
107108
copyButton.popover('destroy');
108-
}, 1000);
109+
110+
// We need to restore the copy button's original ARIA label.
111+
// Wait 0.15 seconds for the popover to fade away first.
112+
// Otherwise, the screen reader will re-announce the popover's content.
113+
setTimeout(function () {
114+
copyButtonDom.ariaLabel = originalLabel;
115+
}, 200);
116+
}, 1500);
117+
109118
window.nuget.sendMetric("CopyInstallCommand", 1, {
110119
ButtonId: id,
111120
PackageId: packageId,

src/NuGetGallery/Views/Packages/DisplayPackage.cshtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@
195195
<div class="copy-button">
196196
<button id="@packageManager.Id-button" class="btn btn-default btn-warning" type="button"
197197
data-toggle="popover" data-placement="bottom" data-content="Copied."
198-
aria-label="@packageManager.CopyLabel" aria-live="polite" role="button">
198+
aria-label="@packageManager.CopyLabel" role="button">
199199
<span class="ms-Icon ms-Icon--Copy" aria-hidden="true"></span>
200200
</button>
201201
</div>

src/NuGetGallery/Views/Packages/DisplayPackageV2.cshtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@
191191
<div class="copy-button">
192192
<button id="@packageManager.Id-button" class="btn btn-default btn-warning" type="button"
193193
data-toggle="popover" data-placement="bottom" data-content="Copied."
194-
aria-label="@packageManager.CopyLabel" aria-live="polite" role="button">
194+
aria-label="@packageManager.CopyLabel" role="button">
195195
<span class="ms-Icon ms-Icon--Copy" aria-hidden="true"></span>
196196
</button>
197197
</div>

0 commit comments

Comments
 (0)