Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Unified Diff: third_party/WebKit/Source/devtools/front_end/accessibility/ARIAAttributesView.js

Issue 2058323002: Add ARIA panel to accessibility sidebar pane (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Preliminary cleanup Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/devtools/front_end/accessibility/ARIAAttributesView.js
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/ARIAAttributesView.js b/third_party/WebKit/Source/devtools/front_end/accessibility/ARIAAttributesView.js
new file mode 100644
index 0000000000000000000000000000000000000000..c5f19c058a5534f2c94afe81da5a4bfc68dd9a76
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/accessibility/ARIAAttributesView.js
@@ -0,0 +1,316 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @extends {WebInspector.AccessibilitySubPane}
+ */
+WebInspector.AXARIAAttributesSubPane = function()
dgozman 2016/07/18 22:38:19 ARIAAttributesPane
aboxhall 2016/07/19 17:20:54 Done.
+{
+ WebInspector.AccessibilitySubPane.call(this, WebInspector.UIString("ARIA Attributes"));
+
+ this._noPropertiesInfo = this.createInfo(WebInspector.UIString("No ARIA attributes"));
+ this._treeOutline = this.createTreeOutline();
+};
+
+
+WebInspector.AXARIAAttributesSubPane.prototype = {
+ /**
+ * @override
+ * @param {?WebInspector.DOMNode} node
+ */
+ setNode: function(node)
+ {
+ WebInspector.AccessibilitySubPane.prototype.setNode.call(this, node);
+ this._treeOutline.removeChildren();
+ if (!this.node())
+ return;
+ var target = this.node().target();
+ var foundARIAAttr = false;
dgozman 2016/07/18 22:38:19 Avoid abbreviations: attr -> attribute. I'd call t
aboxhall 2016/07/19 17:20:54 Done.
+ var attributes = node.attributes();
+ for (var i = 0; i < attributes.length; ++i) {
+ var attribute = attributes[i];
+ if (WebInspector.AXARIAAttributesSubPane.ARIAAttributes.indexOf(attribute.name) < 0)
+ continue;
+ this._treeOutline.appendChild(new WebInspector.ARIAAttributesTreeElement(this, attribute, target));
+ foundARIAAttr = true;
+ }
+
+ if (foundARIAAttr) {
dgozman 2016/07/18 22:38:20 Can just check |this._treeOutline.rootElement().ch
aboxhall 2016/07/19 17:20:53 Done.
+ this._noPropertiesInfo.classList.add("hidden");
+ this._treeOutline.element.classList.remove("hidden");
+ } else {
+ this._noPropertiesInfo.classList.remove("hidden");
+ this._treeOutline.element.classList.add("hidden");
dgozman 2016/07/18 22:38:19 Use toggle instead: this._treeOutline.element.clas
aboxhall 2016/07/19 17:20:54 Nice, TIL. Done.
+ }
+ },
+
+ __proto__: WebInspector.AccessibilitySubPane.prototype
+};
+
+/**
+ * @constructor
+ * @extends {WebInspector.AXNodePropertyTreeElement}
+ * @param {!WebInspector.AXARIAAttributesSubPane} parentPane
+ * @param {!Object} attribute
dgozman 2016/07/18 22:38:19 Let's make it a typedef. I've found that DOMNode.a
aboxhall 2016/07/19 17:20:53 Done.
+ * @param {!WebInspector.Target} target
+ */
+WebInspector.ARIAAttributesTreeElement = function(parentPane, attribute, target)
+{
+ WebInspector.AXNodePropertyTreeElement.call(this, target);
+
+ this._parentPane = parentPane;
+ this._attribute = attribute;
+};
+
+WebInspector.ARIAAttributesTreeElement.prototype = {
+ /**
+ * @override
+ */
+ onattach: function()
+ {
+ this._populateListItem();
+ this.listItemElement.addEventListener("click", this._mouseClick.bind(this));
+ },
+
+ _populateListItem: function() {
dgozman 2016/07/18 22:38:20 { on next line
aboxhall 2016/07/19 17:20:54 Done.
+ this.listItemElement.removeChildren();
+ this.appendNameElement(this._attribute.name);
+ this.listItemElement.createChild("span", "separator").textContent = ":\u00A0";
+ this.appendAttributeValueElement(this._attribute.value);
+ },
+
+ /**
+ * @override
+ * @param {string} name
+ */
+ appendNameElement: function(name)
+ {
+ this.nameElement = createElement("span");
dgozman 2016/07/18 22:38:20 _nameElement
aboxhall 2016/07/19 17:20:54 Done.
+ this.nameElement.textContent = name;
+ this.nameElement.classList.add("ax-name");
+ this.nameElement.classList.add("monospace");
+ this.listItemElement.appendChild(this.nameElement);
+ },
+
+ /**
+ * @param {string} value
+ * @return {?Element}
dgozman 2016/07/18 22:38:19 - !Element - Is it used at all? Let's not return a
aboxhall 2016/07/19 17:20:54 Done.
+ */
+ appendAttributeValueElement: function(value)
+ {
+ this.valueElement = WebInspector.ARIAAttributesTreeElement.createARIAValueElement(value);
dgozman 2016/07/18 22:38:19 _valueElement
aboxhall 2016/07/19 17:20:53 Done.
+ this.listItemElement.appendChild(this.valueElement);
+ return this.valueElement;
+ },
+
+ _mouseClick: function(event)
dgozman 2016/07/18 22:38:20 Annotate please.
aboxhall 2016/07/19 17:20:54 Done.
+ {
+ event.consume(true);
+
+ if (event.target === this.listItemElement)
+ return;
+
+ this.startEditing();
+ },
+
+ startEditing: function()
dgozman 2016/07/18 22:38:19 All these editing methods should be private.
aboxhall 2016/07/19 17:20:54 Done.
+ {
+ var valueElement = this.valueElement;
+
+ if (WebInspector.isBeingEdited(valueElement))
+ return;
+
+ var previousContent = valueElement.textContent;
+
+ if (valueElement.parentElement)
+ valueElement.parentElement.classList.add("child-editing");
+
+ /**
+ * @param {string} previousContent
+ * @param {!Event} event
+ * @this {WebInspector.ARIAAttributesTreeElement}
+ */
+ function blurListener(previousContent, event)
+ {
+ var text = event.target.textContent;
+ text = this.value || text;
dgozman 2016/07/18 22:38:20 What is |this.value| ?
aboxhall 2016/07/19 17:20:54 Ugh, should have been this._attribute.value, but I
+ this.editingCommitted(text, previousContent);
+ }
+
+ this._prompt = new WebInspector.AXARIAAttributesSubPane.ARIAAttributePrompt(this);
+ this._prompt.setAutocompletionTimeout(0);
+ var proxyElement = this._prompt.attachAndStartEditing(valueElement, blurListener.bind(this, previousContent));
+
+ proxyElement.addEventListener("keydown", this._editingValueKeyDown.bind(this, previousContent), false);
+
+ valueElement.getComponentSelection().setBaseAndExtent(valueElement, 0, valueElement, 1);
+ },
+
+ _removePrompt: function()
+ {
+ if (!this._prompt)
+ return;
+ this._prompt.detach();
+ delete this._prompt;
+ },
+
dgozman 2016/07/18 22:38:19 nit: extra blank line
aboxhall 2016/07/19 17:20:53 Done.
+
+ /**
+ * @param {string} userInput
+ * @param {string} previousContent
+ */
+ editingCommitted: function(userInput, previousContent)
+ {
+ this._removePrompt();
+ this.editingEnded();
+
+ // Make the changes to the attribute
+ if (userInput !== previousContent) {
+ var newText = this._attribute.name + '="' + userInput + '"';
+ this._parentPane.node().setAttribute(this._attribute.name, newText);
dgozman 2016/07/18 22:38:19 Let's use setAttributeValue to not craft html here
aboxhall 2016/07/19 17:20:54 Done.
+ }
+ },
+
+ editingEnded: function()
+ {
+ var editedElement = this.valueElement;
+ // The proxyElement has been deleted, no need to remove listener.
+ if (editedElement.parentElement)
+ editedElement.parentElement.classList.remove("child-editing");
dgozman 2016/07/18 22:38:20 Is "child-editing" used anywhere?
aboxhall 2016/07/19 17:20:54 Hm, doesn't look like it.
+ },
+
+ editingCancelled: function()
+ {
+ this._removePrompt();
+ this._populateListItem();
+ this.editingEnded();
+ },
+
+ /**
+ * @param {string} previousContent
+ * @param {!Event} event
+ */
+ _editingValueKeyDown: function(previousContent, event)
+ {
+ if (event.handled)
+ return;
+
+ var result;
+
+ if (isEnterKey(event)) {
+ result = "commit";
+ event.preventDefault();
+ } else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || event.keyIdentifier === "U+001B") {
+ result = "cancel";
+ }
+
+ if (result) {
+ switch (result) {
+ case "cancel":
+ this.editingCancelled();
dgozman 2016/07/18 22:38:19 Just call this instead of |result = "commit"|.
aboxhall 2016/07/19 17:20:54 Done.
+ break;
+ case "commit":
+ this.editingCommitted(event.target.textContent, result);
dgozman 2016/07/18 22:38:19 Same for cancel.
aboxhall 2016/07/19 17:20:54 Done.
+ break;
+ }
+
+ event.consume();
dgozman 2016/07/18 22:38:20 And consume in both cases. Note: consume(true) wil
aboxhall 2016/07/19 17:20:53 Done.
+ return;
+ }
+ },
+
+ __proto__: WebInspector.AXNodePropertyTreeElement.prototype
+};
+
+/**
+ * @param {string} value
+ * @return {!Element}
+ */
+WebInspector.ARIAAttributesTreeElement.createARIAValueElement = function(value)
+{
+ var valueElement = createElementWithClass("span", "monospace");
+ // TODO(aboxhall): quotation marks?
+ valueElement.setTextContentTruncatedIfNeeded(value || "");
+ return valueElement;
+};
+
+/**
+ * @constructor
+ * TODO: completions; see StylesSidebarPane.js
+ * @extends {WebInspector.TextPrompt}
+ * @param {!WebInspector.ARIAAttributesTreeElement} treeElement
+ */
+WebInspector.AXARIAAttributesSubPane.ARIAAttributePrompt = function(treeElement)
+{
+ WebInspector.TextPrompt.call(this, this._buildPropertyCompletions.bind(this));
+
+ this._treeElement = treeElement;
+};
+
+WebInspector.AXARIAAttributesSubPane.ARIAAttributePrompt.prototype = {
+ /**
+ * @param {!Element} proxyElement
+ * @param {string} text
+ * @param {number} cursorOffset
+ * @param {!Range} wordRange
+ * @param {boolean} force
+ * @param {function(!Array.<string>, number=)} completionsReadyCallback
+ */
+ _buildPropertyCompletions: function(proxyElement, text, cursorOffset, wordRange, force, completionsReadyCallback)
+ {
+ // TODO(aboxhall): replace placeholder implementation with real implementation
+
+ var prefix = wordRange.toString().toLowerCase();
dgozman 2016/07/18 22:38:20 Let's remove this code for now, until we have an i
aboxhall 2016/07/19 17:20:54 Done.
+ if (!prefix && !force && (proxyElement.textContent.length)) {
+ completionsReadyCallback([]);
+ return;
+ }
+
+ var results = [];
+ completionsReadyCallback(results, 0);
+ },
+
+ __proto__: WebInspector.TextPrompt.prototype
+}
+
+
+WebInspector.AXARIAAttributesSubPane.ARIAAttributes = [
dgozman 2016/07/18 22:38:20 WebInspector.ARIAAttributesPane._attributes
aboxhall 2016/07/19 17:20:54 Done.
+ "role",
+ "aria-busy",
+ "aria-checked",
+ "aria-disabled",
+ "aria-expanded",
+ "aria-grabbed",
+ "aria-hidden",
+ "aria-invalid",
+ "aria-pressed",
+ "aria-selected",
+ "aria-activedescendant",
+ "aria-atomic",
+ "aria-autocomplete",
+ "aria-controls",
+ "aria-describedby",
+ "aria-dropeffect",
+ "aria-flowto",
+ "aria-haspopup",
+ "aria-label",
+ "aria-labelledby",
+ "aria-level",
+ "aria-live",
+ "aria-multiline",
+ "aria-multiselectable",
+ "aria-orientation",
+ "aria-owns",
+ "aria-posinset",
+ "aria-readonly",
+ "aria-relevant",
+ "aria-required",
+ "aria-setsize",
+ "aria-sort",
+ "aria-valuemax",
+ "aria-valuemin",
+ "aria-valuenow",
+ "aria-valuetext",
+];

Powered by Google App Engine
This is Rietveld 408576698