DevTools: Make Preview Pane Accessible
This is a reland of 58040a832bb68a52529638518de36be17c65547f
The failing aXe tests were removed and will be added again after
invesigation
Original change's description:
> DevTools: Make Preview Pane Accessible
>
> The preview pane previously lacked keyboard controls for navigating
> through the JSON and XML views, the Font view unnecessarily read out the
> content of the view (the alphabet) when accessed via screen reader, and
> the Image view did not allow a screen reader user to access the size and
> mime type of the image.
>
> This patch fixes these issues by making the JSON and XML treeOutlines
> selectable so they can be accessed via keyboard and by displaying
> keyboard focus within the treeOutline. In the Font view, the element
> containing the sample text is marked so that a screen reader will not
> read the contents, but rather will read the source url of the font. In
> the Image view, a tab stop was moved from a parent element to the image
> itself and a label was added that reads the source url of the image.
>
> JSON view before: https://imgur.com/BWczsAL
> JSON view after, without keyboard focus: (same as before)
> JSON view after, with keyboard focus: https://imgur.com/gD0rNSB
>
> XML view before: https://imgur.com/Ec9b5kf
> XML view after, without focus: https://imgur.com/NEqUgpt
> XML view after, with focus: https://imgur.com/0csIpQ3
>
> Change-Id: Id8bacdc593a5b562069fddb70452902ebad934e0
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1551384
> Commit-Queue: Amanda Baker <[email protected]>
> Reviewed-by: Erik Luo <[email protected]>
> Cr-Commit-Position: refs/heads/master@{#663263}
Change-Id: If544cc7a83d031c42cb538f6e89b9df9d3ec1dc0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1633989
Reviewed-by: Erik Luo <[email protected]>
Commit-Queue: Amanda Baker <[email protected]>
Cr-Original-Commit-Position: refs/heads/master@{#666949}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: ffc8de5717812a6e5803c9f005a4159a58ff0824
diff --git a/front_end/source_frame/FontView.js b/front_end/source_frame/FontView.js
index d9030c6..2278603 100644
--- a/front_end/source_frame/FontView.js
+++ b/front_end/source_frame/FontView.js
@@ -39,6 +39,7 @@
this.registerRequiredCSS('source_frame/fontView.css');
this.element.classList.add('font-view');
this._url = contentProvider.contentURL();
+ UI.ARIAUtils.setAccessibleName(this.element, ls`Preview of font from ${this._url}`);
this._mimeType = mimeType;
this._contentProvider = contentProvider;
this._mimeTypeLabel = new UI.ToolbarText(mimeType);
@@ -79,6 +80,7 @@
fontPreview.createTextChild(SourceFrame.FontView._fontPreviewLines[i]);
}
this.fontPreviewElement = fontPreview.cloneNode(true);
+ UI.ARIAUtils.markAsHidden(this.fontPreviewElement);
this.fontPreviewElement.style.overflow = 'hidden';
this.fontPreviewElement.style.setProperty('font-family', uniqueFontName);
this.fontPreviewElement.style.setProperty('visibility', 'hidden');
diff --git a/front_end/source_frame/ImageView.js b/front_end/source_frame/ImageView.js
index b69709b..c6f5e86 100644
--- a/front_end/source_frame/ImageView.js
+++ b/front_end/source_frame/ImageView.js
@@ -37,6 +37,7 @@
constructor(mimeType, contentProvider) {
super(Common.UIString('Image'));
this.registerRequiredCSS('source_frame/imageView.css');
+ this.element.tabIndex = 0;
this.element.classList.add('image-view');
this._url = contentProvider.contentURL();
this._parsedURL = new Common.ParsedURL(this._url);
@@ -58,6 +59,7 @@
this._container = this.element.createChild('div', 'image');
this._imagePreviewElement = this._container.createChild('img', 'resource-image-view');
this._imagePreviewElement.addEventListener('contextmenu', this._contextMenu.bind(this), true);
+ this._imagePreviewElement.alt = ls`Image from ${this._url}`;
}
/**
diff --git a/front_end/source_frame/JSONView.js b/front_end/source_frame/JSONView.js
index 7199d3e..53fe818 100644
--- a/front_end/source_frame/JSONView.js
+++ b/front_end/source_frame/JSONView.js
@@ -68,7 +68,6 @@
searchableView.setPlaceholder(Common.UIString('Find'));
jsonView._searchableView = searchableView;
jsonView.show(searchableView.element);
- jsonView.element.setAttribute('tabIndex', 0);
return searchableView;
}
@@ -172,6 +171,7 @@
this._treeOutline.setEditable(false);
this._treeOutline.expand();
this.element.appendChild(this._treeOutline.element);
+ this._treeOutline.firstChild().select(true /* omitFocus */, false /* selectedByUser */);
}
/**
diff --git a/front_end/source_frame/XMLView.js b/front_end/source_frame/XMLView.js
index cc0434b..ad6a40a 100644
--- a/front_end/source_frame/XMLView.js
+++ b/front_end/source_frame/XMLView.js
@@ -27,6 +27,7 @@
this._searchConfig;
SourceFrame.XMLView.Node.populate(this._treeOutline, parsedXML, this);
+ this._treeOutline.firstChild().select(true /* omitFocus */, false /* selectedByUser */);
}
/**
@@ -39,7 +40,6 @@
searchableView.setPlaceholder(Common.UIString('Find'));
xmlView._searchableView = searchableView;
xmlView.show(searchableView.element);
- xmlView.contentElement.setAttribute('tabIndex', 0);
return searchableView;
}
@@ -223,7 +223,7 @@
super('', !closeTag && !!node.childElementCount);
this._node = node;
this._closeTag = closeTag;
- this.selectable = false;
+ this.selectable = true;
/** @type {!Array.<!Object>} */
this._highlightChanges = [];
this._xmlView = xmlView;
diff --git a/front_end/source_frame/source_frame_strings.grdp b/front_end/source_frame/source_frame_strings.grdp
index a1d41c7..9be107a 100644
--- a/front_end/source_frame/source_frame_strings.grdp
+++ b/front_end/source_frame/source_frame_strings.grdp
@@ -18,12 +18,18 @@
<message name="IDS_DEVTOOLS_4cfa6c981549e990fe2344e4c805405e" desc="">
Find
</message>
+ <message name="IDS_DEVTOOLS_53cd8180752335dce4f9b9ed493ef58d" desc="">
+ Image from <ph name="THIS__URL">$1s</ph>
+ </message>
<message name="IDS_DEVTOOLS_59cc7cb8dfb2491cc5dfe8ebc546d797" desc="">
Pretty print
</message>
<message name="IDS_DEVTOOLS_5ada9c9e1dad2e7e20aaa7688d7bd6c7" desc="">
Line <ph name="LOCATION_______">$1s</ph>, Column <ph name="LOCATION_______">$2s</ph>
</message>
+ <message name="IDS_DEVTOOLS_69614e5ef242926a61b58cebd303d4f4" desc="">
+ Preview of font from <ph name="THIS__URL">$1s</ph>
+ </message>
<message name="IDS_DEVTOOLS_6efb3f8d955fc3395726044acec66129" desc="">
<ph name="THIS__IMAGEPREVIEWELEMENT_NATURALWIDTH">$1d</ph> × <ph name="THIS__IMAGEPREVIEWELEMENT_NATURALHEIGHT">$2d</ph>
</message>
diff --git a/front_end/ui/UIUtils.js b/front_end/ui/UIUtils.js
index d2aa44d..03d4a52 100644
--- a/front_end/ui/UIUtils.js
+++ b/front_end/ui/UIUtils.js
@@ -2037,6 +2037,11 @@
* @return {!DocumentFragment}
*/
UI.createExpandableText = function(text, maxLength) {
+ const clickHandler = () => {
+ if (expandElement.parentElement)
+ expandElement.parentElement.insertBefore(createTextNode(text.slice(maxLength)), expandElement);
+ expandElement.remove();
+ };
const fragment = createDocumentFragment();
fragment.textContent = text.slice(0, maxLength);
const expandElement = fragment.createChild('span');
@@ -2044,11 +2049,13 @@
if (text.length < 10000000) {
expandElement.setAttribute('data-text', ls`Show more (${totalBytes})`);
expandElement.classList.add('expandable-inline-button');
- expandElement.addEventListener('click', () => {
- if (expandElement.parentElement)
- expandElement.parentElement.insertBefore(createTextNode(text.slice(maxLength)), expandElement);
- expandElement.remove();
+ expandElement.addEventListener('click', clickHandler);
+ expandElement.addEventListener('keydown', event => {
+ if (event.key === 'Enter' || event.key === ' ')
+ clickHandler();
});
+ UI.ARIAUtils.markAsButton(expandElement);
+
} else {
expandElement.setAttribute('data-text', ls`long text was truncated (${totalBytes})`);
expandElement.classList.add('undisplayable-text');
@@ -2059,6 +2066,11 @@
copyButton.addEventListener('click', () => {
InspectorFrontendHost.copyText(text);
});
+ copyButton.addEventListener('keydown', event => {
+ if (event.key === 'Enter' || event.key === ' ')
+ InspectorFrontendHost.copyText(text);
+ });
+ UI.ARIAUtils.markAsButton(copyButton);
return fragment;
};
diff --git a/front_end/ui/inspectorCommon.css b/front_end/ui/inspectorCommon.css
index 525ae58..038351f 100644
--- a/front_end/ui/inspectorCommon.css
+++ b/front_end/ui/inspectorCommon.css
@@ -428,6 +428,10 @@
background-color: #d5d5d5;
}
+.expandable-inline-button[data-keyboard-focus="true"] {
+ background-color: #bbbbbb;
+}
+
::selection {
background-color: #bbdefb;
}