diff --git a/lib/accessibility-element-view.js b/lib/accessibility-element-view.js
index b8af706..f4b5581 100644
--- a/lib/accessibility-element-view.js
+++ b/lib/accessibility-element-view.js
@@ -1,12 +1,14 @@
'use strict'
const SelectableView = require('./selectable-view')
+const Eval = require('./eval')
class AccessibilityElementView extends SelectableView {
constructor (element, parent) {
super('element-row')
- this.path = element
+ this.path = element.selector
+ this.pathId = element.id
parent.appendChild(this.element)
this.render()
this.handleEvents(parent)
@@ -19,6 +21,13 @@ class AccessibilityElementView extends SelectableView {
render () {
this.selectorPath.textContent = this.path
+
+ // Add a click-handler that will select the element.
+ // Uses the `accessibilityAuditMap` defined in accessibility.js
+ this.selectorPath.onclick = (evt) => {
+ evt.stopPropagation()
+ Eval.execute(`inspect(window.__devtron.accessibilityAuditMap.get(${this.pathId}))`)
+ }
}
filter (searchText) {
diff --git a/lib/accessibility.js b/lib/accessibility.js
index 80b6f0f..fe78e6b 100644
--- a/lib/accessibility.js
+++ b/lib/accessibility.js
@@ -2,9 +2,23 @@ const Eval = require('./eval')
exports.audit = () => {
return Eval.execute(function () {
- const {axs} = window.__devtron
+ const {axs} = window.__devtron // defined in browser-globals.js
const config = new axs.AuditConfiguration({showUnsupportedRulesWarning: false})
- return axs.Audit.run(config).map(function (result) {
+ const results = axs.Audit.run(config)
+
+ // Create a lookup map so users can click on an element to inspect it
+ let idCounter = 0
+ window.__devtron.accessibilityAuditMap = new Map()
+ results.forEach(function (result) {
+ const elements = result.elements || []
+ elements.forEach(function (element) {
+ const id = idCounter++
+ element.__accessibilityAuditId = id
+ window.__devtron.accessibilityAuditMap.set(id, element)
+ })
+ })
+
+ return results.map(function (result) {
const elements = result.elements || []
let status = 'N/A'
if (result.result === 'PASS') {
@@ -19,7 +33,14 @@ exports.audit = () => {
title: result.rule.heading,
url: result.rule.url,
elements: elements.map(function (element) {
- return window.__devtron.axs.utils.getQuerySelectorText(element)
+ let selector = element.tagName.toLowerCase()
+ if (element.className) {
+ selector += '.' + element.className.split(' ').join('.')
+ }
+ return {
+ selector: selector,
+ id: element.__accessibilityAuditId
+ }
})
}
}).sort(function (resultA, resultB) {
diff --git a/lib/browser-globals.js b/lib/browser-globals.js
new file mode 100644
index 0000000..b56f52e
--- /dev/null
+++ b/lib/browser-globals.js
@@ -0,0 +1,8 @@
+// This defines globals that will be used in the browser context
+// (via the content_scripts definition in manifest.json)
+//
+// It is generated via `npm run-script prepublish`
+const axs = require('accessibility-developer-tools')
+
+window.__devtron = window.__devtron || {}
+window.__devtron.axs = axs
diff --git a/manifest.json b/manifest.json
index ef4c62a..24613a4 100644
--- a/manifest.json
+++ b/manifest.json
@@ -5,7 +5,7 @@
"content_scripts": [
{
"matches": ["*"],
- "js": ["vendor/axs.js"]
+ "js": ["out/browser-globals.js"]
}
]
}
diff --git a/package.json b/package.json
index 63c7dd0..cdee958 100644
--- a/package.json
+++ b/package.json
@@ -4,8 +4,8 @@
"description": "Electron DevTools Extension",
"main": "./api.js",
"scripts": {
- "prepublish": "browserify lib/*.js -o out/index.js --ignore-missing --entry lib/index.js",
- "start": "watchify lib/*.js -o out/index.js --ignore-missing --entry lib/index.js --verbose",
+ "prepublish": "browserify lib/*.js -o out/index.js --ignore-missing --entry lib/index.js && browserify lib/browser-globals.js -o out/browser-globals.js",
+ "start": "browserify lib/browser-globals.js -o out/browser-globals.js && watchify lib/*.js -o out/index.js --ignore-missing --entry lib/index.js --verbose",
"test": "mocha test/unit/*-test.js test/integration/*-test.js && standard"
},
"repository": {
@@ -39,6 +39,7 @@
"watchify": "^3.7.0"
},
"dependencies": {
+ "accessibility-developer-tools": "^2.11.0",
"highlight.js": "^9.3.0",
"humanize-plus": "^1.8.1"
},
diff --git a/static/devtron.css b/static/devtron.css
index 5c9d1de..8284887 100644
--- a/static/devtron.css
+++ b/static/devtron.css
@@ -130,6 +130,13 @@ tbody:focus,
padding-left: 45px;
}
+.row-element-path a {
+ cursor: pointer;
+}
+tr.active .row-element-path a {
+ color: white;
+}
+
.active .sidebar-icon {
background-color: white;
}
diff --git a/static/index.html b/static/index.html
index 8e12752..d4fd3ee 100644
--- a/static/index.html
+++ b/static/index.html
@@ -90,7 +90,7 @@
|
|
-
+
|
diff --git a/vendor/axs.js b/vendor/axs.js
deleted file mode 100644
index 2df078e..0000000
--- a/vendor/axs.js
+++ /dev/null
@@ -1,2284 +0,0 @@
-/*
- * Copyright 2016 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Generated from http://github.com/GoogleChrome/accessibility-developer-tools/tree/582ba71c124ed834d640ce2109dcd91b7864922f
- *
- * See project README for build steps.
- */
-
-// AUTO-GENERATED CONTENT BELOW: DO NOT EDIT! See above for details.
-
-window.__devtron = window.__devtron || {}
-
-window.__devtron.axs = (function() {
- var COMPILED = !0, goog = goog || {};
-goog.global = this;
-goog.isDef = function(a) {
- return void 0 !== a;
-};
-goog.exportPath_ = function(a, b, c) {
- a = a.split(".");
- c = c || goog.global;
- a[0] in c || !c.execScript || c.execScript("var " + a[0]);
- for (var d;a.length && (d = a.shift());) {
- !a.length && goog.isDef(b) ? c[d] = b : c = c[d] ? c[d] : c[d] = {};
- }
-};
-goog.define = function(a, b) {
- var c = b;
- COMPILED || (goog.global.CLOSURE_UNCOMPILED_DEFINES && Object.prototype.hasOwnProperty.call(goog.global.CLOSURE_UNCOMPILED_DEFINES, a) ? c = goog.global.CLOSURE_UNCOMPILED_DEFINES[a] : goog.global.CLOSURE_DEFINES && Object.prototype.hasOwnProperty.call(goog.global.CLOSURE_DEFINES, a) && (c = goog.global.CLOSURE_DEFINES[a]));
- goog.exportPath_(a, c);
-};
-goog.DEBUG = !0;
-goog.LOCALE = "en";
-goog.TRUSTED_SITE = !0;
-goog.STRICT_MODE_COMPATIBLE = !1;
-goog.provide = function(a) {
- if (!COMPILED) {
- if (goog.isProvided_(a)) {
- throw Error('Namespace "' + a + '" already declared.');
- }
- delete goog.implicitNamespaces_[a];
- for (var b = a;(b = b.substring(0, b.lastIndexOf("."))) && !goog.getObjectByName(b);) {
- goog.implicitNamespaces_[b] = !0;
- }
- }
- goog.exportPath_(a);
-};
-goog.setTestOnly = function(a) {
- if (COMPILED && !goog.DEBUG) {
- throw a = a || "", Error("Importing test-only code into non-debug environment" + a ? ": " + a : ".");
- }
-};
-goog.forwardDeclare = function(a) {
-};
-COMPILED || (goog.isProvided_ = function(a) {
- return !goog.implicitNamespaces_[a] && goog.isDefAndNotNull(goog.getObjectByName(a));
-}, goog.implicitNamespaces_ = {});
-goog.getObjectByName = function(a, b) {
- for (var c = a.split("."), d = b || goog.global, e;e = c.shift();) {
- if (goog.isDefAndNotNull(d[e])) {
- d = d[e];
- } else {
- return null;
- }
- }
- return d;
-};
-goog.globalize = function(a, b) {
- var c = b || goog.global, d;
- for (d in a) {
- c[d] = a[d];
- }
-};
-goog.addDependency = function(a, b, c) {
- if (goog.DEPENDENCIES_ENABLED) {
- var d;
- a = a.replace(/\\/g, "/");
- for (var e = goog.dependencies_, f = 0;d = b[f];f++) {
- e.nameToPath[d] = a, a in e.pathToNames || (e.pathToNames[a] = {}), e.pathToNames[a][d] = !0;
- }
- for (d = 0;b = c[d];d++) {
- a in e.requires || (e.requires[a] = {}), e.requires[a][b] = !0;
- }
- }
-};
-goog.ENABLE_DEBUG_LOADER = !0;
-goog.require = function(a) {
- if (!COMPILED && !goog.isProvided_(a)) {
- if (goog.ENABLE_DEBUG_LOADER) {
- var b = goog.getPathFromDeps_(a);
- if (b) {
- goog.included_[b] = !0;
- goog.writeScripts_();
- return;
- }
- }
- a = "goog.require could not find: " + a;
- goog.global.console && goog.global.console.error(a);
- throw Error(a);
- }
-};
-goog.basePath = "";
-goog.nullFunction = function() {
-};
-goog.identityFunction = function(a, b) {
- return a;
-};
-goog.abstractMethod = function() {
- throw Error("unimplemented abstract method");
-};
-goog.addSingletonGetter = function(a) {
- a.getInstance = function() {
- if (a.instance_) {
- return a.instance_;
- }
- goog.DEBUG && (goog.instantiatedSingletons_[goog.instantiatedSingletons_.length] = a);
- return a.instance_ = new a;
- };
-};
-goog.instantiatedSingletons_ = [];
-goog.DEPENDENCIES_ENABLED = !COMPILED && goog.ENABLE_DEBUG_LOADER;
-goog.DEPENDENCIES_ENABLED && (goog.included_ = {}, goog.dependencies_ = {pathToNames:{}, nameToPath:{}, requires:{}, visited:{}, written:{}}, goog.inHtmlDocument_ = function() {
- var a = goog.global.document;
- return "undefined" != typeof a && "write" in a;
-}, goog.findBasePath_ = function() {
- if (goog.global.CLOSURE_BASE_PATH) {
- goog.basePath = goog.global.CLOSURE_BASE_PATH;
- } else {
- if (goog.inHtmlDocument_()) {
- for (var a = goog.global.document.getElementsByTagName("script"), b = a.length - 1;0 <= b;--b) {
- var c = a[b].src, d = c.lastIndexOf("?"), d = -1 == d ? c.length : d;
- if ("base.js" == c.substr(d - 7, 7)) {
- goog.basePath = c.substr(0, d - 7);
- break;
- }
- }
- }
- }
-}, goog.importScript_ = function(a) {
- var b = goog.global.CLOSURE_IMPORT_SCRIPT || goog.writeScriptTag_;
- !goog.dependencies_.written[a] && b(a) && (goog.dependencies_.written[a] = !0);
-}, goog.writeScriptTag_ = function(a) {
- if (goog.inHtmlDocument_()) {
- var b = goog.global.document;
- if ("complete" == b.readyState) {
- if (/\bdeps.js$/.test(a)) {
- return !1;
- }
- throw Error('Cannot write "' + a + '" after document load');
- }
- b.write('