first commit
This commit is contained in:
21
GitHub Desktop-dev/extensions/idikgljglpfilbhaboonnpnnincjhjkd/LICENSE
Executable file
21
GitHub Desktop-dev/extensions/idikgljglpfilbhaboonnpnnincjhjkd/LICENSE
Executable file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Jason Costello
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
34
GitHub Desktop-dev/extensions/idikgljglpfilbhaboonnpnnincjhjkd/README.md
Executable file
34
GitHub Desktop-dev/extensions/idikgljglpfilbhaboonnpnnincjhjkd/README.md
Executable file
@@ -0,0 +1,34 @@
|
||||
# 
|
||||
|
||||
<a href="https://chrome.google.com/webstore/detail/chrome-lens/idikgljglpfilbhaboonnpnnincjhjkd">Chrome Web Store</a>
|
||||
|
||||
ChromeLens is a Google Chrome extension that provides a suite of tools to help
|
||||
with web accessibility development.
|
||||
|
||||
### Lens (Vision Simulator)
|
||||
|
||||
Interact with a website as a completely/partially blind or a colorblind person.
|
||||
|
||||
### Accessibility Audit
|
||||
|
||||
Run a website through an series of accessibility rules and easily discover
|
||||
elements in your website that do not comply with them.
|
||||
|
||||
### Tab-tracker
|
||||
|
||||
Key website features should be navigable solely via the keyboard (tab button),
|
||||
while not making the user jump through hoops to get to a feature. With the
|
||||
tab-tracker, you can visually track the flow of navigation through a website.
|
||||
|
||||
### Website
|
||||
|
||||
Find out more about ChromeLens, why we made it, and more about the extension at <a href="http://chromelens.xyz">chromelens.xyz</a>
|
||||
|
||||
### Credits
|
||||
- https://github.com/GoogleChrome/accessibility-developer-tools
|
||||
- https://github.com/niklasvh/html2canvas
|
||||
- https://github.com/Altreus/colourblind
|
||||
|
||||
### Reviews for ChromeLens
|
||||
- http://briancoords.com/tech/analyzing-accessibility-chromelens/
|
||||
- http://www.jaredrigby.co.uk/2016/07/11/accessibility-testing-with-chromelens.html
|
||||
2402
GitHub Desktop-dev/extensions/idikgljglpfilbhaboonnpnnincjhjkd/audit/axs_testing.js
Executable file
2402
GitHub Desktop-dev/extensions/idikgljglpfilbhaboonnpnnincjhjkd/audit/axs_testing.js
Executable file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
var base = document.getElementById("chrome-lens-base")
|
||||
if (base) { base.remove(); }
|
||||
236
GitHub Desktop-dev/extensions/idikgljglpfilbhaboonnpnnincjhjkd/audit/run_axs.js
Executable file
236
GitHub Desktop-dev/extensions/idikgljglpfilbhaboonnpnnincjhjkd/audit/run_axs.js
Executable file
@@ -0,0 +1,236 @@
|
||||
var BASE_Z = 999999;
|
||||
var WARNING_COUNT = 0;
|
||||
var idToWarningsMap = {};
|
||||
var STYLE = `<style>
|
||||
:host {
|
||||
all: initial;
|
||||
contain: style layout size;
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: ${BASE_Z};
|
||||
}
|
||||
.chrome-lens-warning {
|
||||
position: absolute;
|
||||
box-shadow: 0 0 4px 4px #f7983a;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.tooltip .tooltip-text {
|
||||
visibility: hidden;
|
||||
display: inline-block;
|
||||
background-color: #fffdfd;
|
||||
color: #212121;
|
||||
position: absolute;
|
||||
max-width: 300px;
|
||||
min-width: 200px;
|
||||
padding: 0px 10px 5px 10px;
|
||||
border-radius: 2px;
|
||||
border: 1px solid black;
|
||||
z-index: ${BASE_Z+1};
|
||||
}
|
||||
.tooltip .tooltip-text .severe {
|
||||
color: #c10f0f;
|
||||
font-weight: 900;
|
||||
}
|
||||
.tooltip .tooltip-text .warning {
|
||||
color: #e69808;
|
||||
font-weight: 700;
|
||||
}
|
||||
.tooltip:hover .tooltip-text {
|
||||
visibility: visible;
|
||||
}
|
||||
</style>`;
|
||||
|
||||
var CHROME_LENS_BASE_ID = 'chrome-lens-base'
|
||||
var CHROME_LENS_WARNING_CLASS = 'chrome-lens-warning'
|
||||
var WARNING_ATTR_NAME = 'chromelens-warning-id';
|
||||
|
||||
function initDom() {
|
||||
if (!document.getElementById(CHROME_LENS_BASE_ID)) {
|
||||
const div = document.createElement('div');
|
||||
div.id = CHROME_LENS_BASE_ID;
|
||||
var root = div.attachShadow({mode: 'open'});
|
||||
root.innerHTML = STYLE;
|
||||
document.body.appendChild(div);
|
||||
}
|
||||
}
|
||||
|
||||
function tooltipHeader(severity, code, url) {
|
||||
const el = document.createElement('p');
|
||||
const severityEl = document.createElement('span');
|
||||
if (severity === 'Severe') {
|
||||
severityEl.className = 'severe'
|
||||
} else if (severity === 'Warning') {
|
||||
severityEl.className = 'warning'
|
||||
}
|
||||
severityEl.innerText = severity;
|
||||
|
||||
const codeLink = document.createElement('a');
|
||||
codeLink.href = url;
|
||||
codeLink.innerText = code;
|
||||
codeLink.target = '_blank';
|
||||
|
||||
el.appendChild(severityEl);
|
||||
el.appendChild(document.createTextNode(' '));
|
||||
el.appendChild(codeLink);
|
||||
return el;
|
||||
}
|
||||
|
||||
function positionTooltip(tooltipText, el_top, el_left, el_height) {
|
||||
const {width, height} = tooltipText.getBoundingClientRect();
|
||||
if (height < el_top) {
|
||||
// tooltip cannot fit above, make it below
|
||||
tooltipText.style.bottom = el_height + 'px';
|
||||
} else {
|
||||
// tooltip goes above
|
||||
tooltipText.style.top = el_height + 'px';
|
||||
}
|
||||
if (el_left + width > document.documentElement.clientWidth) {
|
||||
// tooltip is wider than the el, right align el and tooltip
|
||||
tooltipText.style.right = 0 + 'px';
|
||||
}
|
||||
}
|
||||
|
||||
function tooltipTextNode(rule_violated) {
|
||||
const {code, heading, name, severity, url} = rule_violated;
|
||||
const tooltipText = document.createElement('div');
|
||||
tooltipText.className = 'tooltip-text';
|
||||
tooltipText.appendChild(tooltipHeader(severity, code, url));
|
||||
tooltipText.appendChild(document.createTextNode(heading));
|
||||
|
||||
suggestFix(rule_violated);
|
||||
return tooltipText;
|
||||
}
|
||||
|
||||
function getCoordinates(elem) {
|
||||
var box = elem.getBoundingClientRect();
|
||||
var body = document.body;
|
||||
var docEl = document.documentElement;
|
||||
|
||||
var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
|
||||
var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;
|
||||
|
||||
var clientTop = docEl.clientTop || body.clientTop || 0;
|
||||
var clientLeft = docEl.clientLeft || body.clientLeft || 0;
|
||||
|
||||
var top = box.top + scrollTop - clientTop;
|
||||
var left = box.left + scrollLeft - clientLeft;
|
||||
return { top, left, height: box.height, width: box.width }
|
||||
}
|
||||
|
||||
function tooltipNode(offendingEl) {
|
||||
const { top, left, height, width} = getCoordinates(offendingEl);
|
||||
|
||||
const div = document.createElement('div');
|
||||
div.className = CHROME_LENS_WARNING_CLASS;
|
||||
div.classList.add('tooltip');
|
||||
div.style.left = left + 'px';
|
||||
div.style.top = top + 'px';
|
||||
div.style.width = width + 'px';
|
||||
div.style.height = height + 'px';
|
||||
// this id will be useful if we want to reference specific warnings emitted
|
||||
div.id = 'chrome-lens-warning-' + WARNING_COUNT;
|
||||
|
||||
div.onmouseover = function() {
|
||||
chrome.runtime.sendMessage({
|
||||
type: 'HIGHLIGHT_REPORT',
|
||||
data: {
|
||||
warningId: div.id
|
||||
}
|
||||
})
|
||||
}
|
||||
div.onmouseout = function() {
|
||||
chrome.runtime.sendMessage({
|
||||
type: 'UNHIGHLIGHT_REPORT',
|
||||
data: {
|
||||
warningId: div.id
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return div;
|
||||
}
|
||||
|
||||
function suggestFix(ruleViolated) {
|
||||
const {code, heading, name, severity, url} = ruleViolated;
|
||||
if (code === 'AX_ARIA_10') {
|
||||
}
|
||||
}
|
||||
|
||||
function highlightElementForRuleViolation(frag, el, rule_violated) {
|
||||
const warningId = CHROME_LENS_WARNING_CLASS + '-' + (WARNING_COUNT++);
|
||||
idToWarningsMap[warningId] = {el: el, rule: rule_violated};
|
||||
el.setAttribute(WARNING_ATTR_NAME, warningId);
|
||||
|
||||
const { top, left, height, width } = getCoordinates(el);
|
||||
|
||||
// if this isn't visible let's not warn about
|
||||
if (top < 0 || left < 0) return;
|
||||
|
||||
const tooltipText = tooltipTextNode(rule_violated);
|
||||
const toolTip = tooltipNode(el);
|
||||
toolTip.appendChild(tooltipText);
|
||||
|
||||
frag.appendChild(toolTip);
|
||||
// we can only position after we append, because tooltipText has no
|
||||
// bounding client rect before it gets added to the DOM
|
||||
positionTooltip(tooltipText, top, left, height);
|
||||
}
|
||||
|
||||
function run() {
|
||||
const base = document.getElementById(CHROME_LENS_BASE_ID);
|
||||
if (base) {
|
||||
base.remove()
|
||||
}
|
||||
|
||||
var run_result = axs.Audit.run();
|
||||
initDom()
|
||||
|
||||
var frag = document.createDocumentFragment();
|
||||
|
||||
// we only want to highlight failures
|
||||
const failures = run_result.filter(v => v.result === 'FAIL');
|
||||
|
||||
failures.forEach(function(v) {
|
||||
v.elements.forEach(function(el) {
|
||||
highlightElementForRuleViolation(frag, el, v.rule);
|
||||
})
|
||||
})
|
||||
|
||||
var root = document.getElementById(CHROME_LENS_BASE_ID).shadowRoot;
|
||||
root.appendChild(frag);
|
||||
|
||||
chrome.runtime.sendMessage({
|
||||
type: 'AXS_COMPLETE',
|
||||
data: {
|
||||
result: failures,
|
||||
idToWarningsMap,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
run();
|
||||
|
||||
chrome.runtime.onMessage.addListener(function(message) {
|
||||
switch (message.type) {
|
||||
case 'HIGHLIGHT_WARNING': {
|
||||
const { warningId } = message.data;
|
||||
const warningTooltip = document.querySelector('#' + warningId + ' .tooltip-text');
|
||||
if (!warningTooltip) { return; }
|
||||
warningTooltip.style.visibility = 'visible';
|
||||
break;
|
||||
}
|
||||
case 'UNHIGHLIGHT_WARNING': {
|
||||
const { warningId } = message.data;
|
||||
const warningTooltip = document.querySelector('#' + warningId + ' .tooltip-text');
|
||||
if (!warningTooltip) { return; }
|
||||
// we must set to null so that CSS can take over
|
||||
warningTooltip.style.visibility = null;
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
116
GitHub Desktop-dev/extensions/idikgljglpfilbhaboonnpnnincjhjkd/background.js
Executable file
116
GitHub Desktop-dev/extensions/idikgljglpfilbhaboonnpnnincjhjkd/background.js
Executable file
@@ -0,0 +1,116 @@
|
||||
const messageType = {
|
||||
EXECUTE_SCRIPT: 'EXECUTE_SCRIPT',
|
||||
RUN_AXS: 'RUN_AXS',
|
||||
AXS_COMPLETE: 'AXS_COMPLETE',
|
||||
HIGHLIGHT_WARNING: 'HIGHLIGHT_WARNING',
|
||||
UNHIGHLIGHT_WARNING: 'UNHIGHLIGHT_WARNING',
|
||||
HIGHLIGHT_REPORT: 'HIGHLIGHT_REPORT',
|
||||
UNHIGHLIGHT_REPORT: 'UNHIGHLIGHT_REPORT',
|
||||
TRACE_TAB_PATH: 'TRACE_TAB_PATH',
|
||||
PNG_TAB_PATH: 'PNG_TAB_PATH',
|
||||
CLEAR_AXS: 'CLEAR_AXS'
|
||||
}
|
||||
|
||||
const auditDir = 'audit';
|
||||
const tracerDir = 'tracer';
|
||||
|
||||
var devtools = null;
|
||||
|
||||
const devToolsListener = function(message, sender, sendResponse) {
|
||||
switch (message.type) {
|
||||
case messageType.EXECUTE_SCRIPT: {
|
||||
const { scriptToInject } = message.data;
|
||||
// Inject a content script into the active tab
|
||||
chrome.tabs.executeScript({file: scriptToInject});
|
||||
break;
|
||||
}
|
||||
case messageType.RUN_AXS: {
|
||||
chrome.tabs.executeScript({ file: `${auditDir}/axs_testing.js` });
|
||||
chrome.tabs.executeScript({ file: `${auditDir}/run_axs.js` });
|
||||
break;
|
||||
}
|
||||
case messageType.CLEAR_AXS: {
|
||||
chrome.tabs.executeScript({ file: `${auditDir}/clear_axs.js`})
|
||||
break;
|
||||
}
|
||||
case messageType.AXS_COMPLETE: {
|
||||
const { result, idToWarningsMap } = message.data;
|
||||
if (devtools) {
|
||||
devtools.postMessage({
|
||||
type: 'AXS_SHOW_RESULTS',
|
||||
data: {
|
||||
idToWarningsMap: idToWarningsMap
|
||||
}
|
||||
})
|
||||
}
|
||||
break;
|
||||
}
|
||||
case messageType.HIGHLIGHT_WARNING: {
|
||||
const { warningId } = message.data;
|
||||
chrome.tabs.sendMessage({
|
||||
type: messageType.HIGHLIGHT_WARNING,
|
||||
data: {
|
||||
warningId: warningId
|
||||
}
|
||||
})
|
||||
break;
|
||||
}
|
||||
case messageType.UNHIGHLIGHT_WARNING: {
|
||||
const { warningId } = message.data;
|
||||
chrome.tabs.sendMessage({
|
||||
type: messageType.UNHIGHLIGHT_WARNING,
|
||||
data: {
|
||||
warningId: warningId
|
||||
}
|
||||
})
|
||||
break;
|
||||
}
|
||||
case messageType.HIGHLIGHT_REPORT: {
|
||||
const { warningId } = message.data;
|
||||
if (devtools) {
|
||||
devtools.postMessage({
|
||||
type: messageType.HIGHLIGHT_REPORT,
|
||||
data: {
|
||||
warningId: warningId
|
||||
}
|
||||
})
|
||||
}
|
||||
break;
|
||||
}
|
||||
case messageType.UNHIGHLIGHT_REPORT: {
|
||||
const { warningId } = message.data;
|
||||
if (devtools) {
|
||||
devtools.postMessage({
|
||||
type: messageType.UNHIGHLIGHT_REPORT,
|
||||
data: {
|
||||
warningId: warningId
|
||||
}
|
||||
})
|
||||
}
|
||||
break;
|
||||
}
|
||||
case messageType.TRACE_TAB_PATH: {
|
||||
chrome.tabs.executeScript({ file: `${tracerDir}/trace_tab_path.js` });
|
||||
break;
|
||||
}
|
||||
case messageType.PNG_TAB_PATH: {
|
||||
chrome.tabs.executeScript({ file: `${tracerDir}/html2canvas.js` });
|
||||
chrome.tabs.executeScript({ file: `${tracerDir}/png_tab_path.js` });
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
console.log(message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// might need to change this to be inside onConnect, and on devtools side
|
||||
// pass the port to panel
|
||||
chrome.runtime.onMessage.addListener(devToolsListener);
|
||||
chrome.runtime.onConnect.addListener(function(devToolsConnection) {
|
||||
// devToolsConnection.onMessage.addListener(devToolsListener);
|
||||
devtools = devToolsConnection;
|
||||
// assign the listener function to a variable so we can remove it later
|
||||
// add the listener
|
||||
})
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.9 KiB |
@@ -0,0 +1,11 @@
|
||||
var iDiv = document.createElement('div');
|
||||
iDiv.id = 'chromelens-colorFilters';
|
||||
iDiv.innerHTML = '<svg style="display: none" version="1.1" xmlns="http://www.w3.org/2000/svg" baseProfile="full"> ' +
|
||||
'<filter id="achromatomaly"> ' +
|
||||
'<feColorMatrix type="matrix" values="0.618,0.320,0.062,0,0,0.163,0.775,0.062,0,0,0.163,0.320,0.516,0,0,0,0,0,1,0" in="SourceGraphic" /> ' +
|
||||
'</filter> ' +
|
||||
'</svg>';
|
||||
|
||||
document.body.appendChild(iDiv);
|
||||
document.body.style.filter = "url(#achromatomaly)";
|
||||
document.body.style.webkitFilter = "url(#achromatomaly)";
|
||||
@@ -0,0 +1,11 @@
|
||||
var iDiv = document.createElement('div');
|
||||
iDiv.id = 'chromelens-colorFilters';
|
||||
iDiv.innerHTML = '<svg style="display: none" version="1.1" xmlns="http://www.w3.org/2000/svg" baseProfile="full"> ' +
|
||||
'<filter id="achromatopsia"> ' +
|
||||
'<feColorMatrix type="matrix" values="0.299,0.587,0.114,0,0,0.299,0.587,0.114,0,0,0.299,0.587,0.114,0,0,0,0,0,1,0" in="SourceGraphic" /> ' +
|
||||
'</filter> ' +
|
||||
'</svg>';
|
||||
|
||||
document.body.appendChild(iDiv);
|
||||
document.body.style.filter = "url(#achromatopsia)";
|
||||
document.body.style.webkitFilter = "url(#achromatopsia)";
|
||||
@@ -0,0 +1,11 @@
|
||||
var iDiv = document.createElement('div');
|
||||
iDiv.id = 'chromelens-colorFilters';
|
||||
iDiv.innerHTML = '<svg style="display: none" version="1.1" xmlns="http://www.w3.org/2000/svg" baseProfile="full"> ' +
|
||||
'<filter id="deuteranomaly"> ' +
|
||||
'<feColorMatrix type="matrix" values="0.8,0.2,0,0,0,0.258,0.742,0,0,0,0,0.142,0.858,0,0,0,0,0,1,0" in="SourceGraphic" /> ' +
|
||||
'</filter> ' +
|
||||
'</svg>';
|
||||
|
||||
document.body.appendChild(iDiv);
|
||||
document.body.style.filter = "url(#deuteranomaly)";
|
||||
document.body.style.webkitFilter = "url(#deuteranomaly)";
|
||||
@@ -0,0 +1,11 @@
|
||||
var iDiv = document.createElement('div');
|
||||
iDiv.id = 'chromelens-colorFilters';
|
||||
iDiv.innerHTML = '<svg style="display: none" version="1.1" xmlns="http://www.w3.org/2000/svg" baseProfile="full"> ' +
|
||||
'<filter id="deuteranopia"> ' +
|
||||
'<feColorMatrix type="matrix" values="0.625,0.375,0,0,0,0.7,0.3,0,0,0,0,0.3,0.7,0,0,0,0,0,1,0" in="SourceGraphic" /> ' +
|
||||
'</filter> ' +
|
||||
'</svg>';
|
||||
|
||||
document.body.appendChild(iDiv);
|
||||
document.body.style.filter = "url(#deuteranopia)";
|
||||
document.body.style.webkitFilter = "url(#deuteranopia)";
|
||||
@@ -0,0 +1,2 @@
|
||||
document.body.style.filter = "";
|
||||
document.body.style.webkitFilter = "";
|
||||
@@ -0,0 +1,20 @@
|
||||
delete document.body.style.filter;
|
||||
delete document.body.style.webkitFilter;
|
||||
|
||||
// z-index at upper bound of 32bit int
|
||||
var styles = `
|
||||
background-color: black;
|
||||
pointer-events: none;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
z-index: 2147483647;
|
||||
`
|
||||
|
||||
var iDiv = document.createElement('div');
|
||||
iDiv.id = 'chromelens-colorFilters';
|
||||
iDiv.innerHTML = `<div style="${styles}"></div>`;
|
||||
|
||||
document.body.appendChild(iDiv);
|
||||
@@ -0,0 +1,20 @@
|
||||
document.body.style.filter = "blur(3px)";
|
||||
document.body.style.webkitFilter = "blur(3px)";
|
||||
|
||||
// z-index at upper bound of 32bit int
|
||||
var styles = `
|
||||
background: rgba(50, 50, 50, 0.3);
|
||||
pointer-events: none;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
z-index: 2147483647;
|
||||
`
|
||||
|
||||
var iDiv = document.createElement('div');
|
||||
iDiv.id = 'chromelens-colorFilters';
|
||||
iDiv.innerHTML = `<div style="${styles}"></div>`;
|
||||
|
||||
document.body.appendChild(iDiv);
|
||||
@@ -0,0 +1,20 @@
|
||||
document.body.style.filter = "blur(2px)";
|
||||
document.body.style.webkitFilter = "blur(2px)";
|
||||
|
||||
// z-index at upper bound of 32bit int
|
||||
var styles = `
|
||||
background: rgba(50, 50, 50, 0.1);
|
||||
pointer-events: none;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
z-index: 2147483647;
|
||||
`
|
||||
|
||||
var iDiv = document.createElement('div');
|
||||
iDiv.id = 'chromelens-colorFilters';
|
||||
iDiv.innerHTML = `<div style="${styles}"></div>`;
|
||||
|
||||
document.body.appendChild(iDiv);
|
||||
@@ -0,0 +1,2 @@
|
||||
document.body.style.filter = "blur(1px)";
|
||||
document.body.style.webkitFilter = "blur(1px)";
|
||||
@@ -0,0 +1,20 @@
|
||||
document.body.style.filter = "blur(10px)";
|
||||
document.body.style.webkitFilter = "blur(10px)";
|
||||
|
||||
// z-index at upper bound of 32bit int
|
||||
var styles = `
|
||||
background: rgba(50, 50, 50, 0.5);
|
||||
pointer-events: none;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
z-index: 2147483647;
|
||||
`
|
||||
|
||||
var iDiv = document.createElement('div');
|
||||
iDiv.id = 'chromelens-colorFilters';
|
||||
iDiv.innerHTML = `<div style="${styles}"></div>`;
|
||||
|
||||
document.body.appendChild(iDiv);
|
||||
@@ -0,0 +1,11 @@
|
||||
var iDiv = document.createElement('div');
|
||||
iDiv.id = 'chromelens-colorFilters';
|
||||
iDiv.innerHTML = '<svg style="display: none" version="1.1" xmlns="http://www.w3.org/2000/svg" baseProfile="full"> ' +
|
||||
'<filter id="protanomaly"> ' +
|
||||
'<feColorMatrix type="matrix" values="0.817,0.183,0,0,0,0.333,0.667,0,0,0,0,0.125,0.875,0,0,0,0,0,1,0" in="SourceGraphic" /> ' +
|
||||
'</filter> ' +
|
||||
'</svg>';
|
||||
|
||||
document.body.appendChild(iDiv);
|
||||
document.body.style.filter = "url(#protanomaly)";
|
||||
document.body.style.webkitFilter = "url(#protanomaly)";
|
||||
@@ -0,0 +1,11 @@
|
||||
var iDiv = document.createElement('div');
|
||||
iDiv.id = 'chromelens-colorFilters';
|
||||
iDiv.innerHTML = '<svg style="display: none" version="1.1" xmlns="http://www.w3.org/2000/svg" baseProfile="full"> ' +
|
||||
'<filter id="protanopia"> ' +
|
||||
'<feColorMatrix type="matrix" values="0.567,0.433,0,0,0,0.558,0.442,0,0,0,0,0.242,0.758,0,0,0,0,0,1,0" in="SourceGraphic" /> ' +
|
||||
'</filter> ' +
|
||||
'</svg>';
|
||||
|
||||
document.body.appendChild(iDiv);
|
||||
document.body.style.filter = "url(#protanopia)";
|
||||
document.body.style.webkitFilter = "url(#protanopia)";
|
||||
@@ -0,0 +1,11 @@
|
||||
var iDiv = document.createElement('div');
|
||||
iDiv.id = 'chromelens-colorFilters';
|
||||
iDiv.innerHTML = '<svg style="display: none" version="1.1" xmlns="http://www.w3.org/2000/svg" baseProfile="full"> ' +
|
||||
'<filter id="tritanomaly"> ' +
|
||||
'<feColorMatrix type="matrix" values="0.967,0.033,0,0,0,0,0.733,0.267,0,0,0,0.183,0.817,0,0,0,0,0,1,0" in="SourceGraphic" /> ' +
|
||||
'</filter> ' +
|
||||
'</svg>';
|
||||
|
||||
document.body.appendChild(iDiv);
|
||||
document.body.style.filter = "url(#tritanomaly)";
|
||||
document.body.style.webkitFilter = "url(#tritanomaly)";
|
||||
@@ -0,0 +1,11 @@
|
||||
var iDiv = document.createElement('div');
|
||||
iDiv.id = 'chromelens-colorFilters';
|
||||
iDiv.innerHTML = '<svg style="display: none" version="1.1" xmlns="http://www.w3.org/2000/svg" baseProfile="full"> ' +
|
||||
'<filter id="tritanopia"> ' +
|
||||
'<feColorMatrix type="matrix" values="0.95,0.05,0,0,0,0,0.433,0.567,0,0,0,0.475,0.525,0,0,0,0,0,1,0" in="SourceGraphic" /> ' +
|
||||
'</filter> ' +
|
||||
'</svg>';
|
||||
|
||||
document.body.appendChild(iDiv);
|
||||
document.body.style.filter = "url(#tritanopia)";
|
||||
document.body.style.webkitFilter = "url(#tritanopia)";
|
||||
@@ -0,0 +1,4 @@
|
||||
var elem = document.getElementById("chromelens-colorFilters");
|
||||
if (elem) {
|
||||
elem.parentElement.removeChild(elem);
|
||||
}
|
||||
8
GitHub Desktop-dev/extensions/idikgljglpfilbhaboonnpnnincjhjkd/main.html
Executable file
8
GitHub Desktop-dev/extensions/idikgljglpfilbhaboonnpnnincjhjkd/main.html
Executable file
@@ -0,0 +1,8 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="main.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
46
GitHub Desktop-dev/extensions/idikgljglpfilbhaboonnpnnincjhjkd/main.js
Executable file
46
GitHub Desktop-dev/extensions/idikgljglpfilbhaboonnpnnincjhjkd/main.js
Executable file
@@ -0,0 +1,46 @@
|
||||
// Utilities
|
||||
function log(...s) {
|
||||
const string = JSON.stringify(s);
|
||||
chrome.devtools.inspectedWindow.eval('console.log(' + string + ')')
|
||||
};
|
||||
|
||||
// Create panel
|
||||
function createPanel() {
|
||||
chrome.devtools.panels.create('ChromeLens', '', 'panel.html', function(panel) {
|
||||
var _window;
|
||||
var backgroundPageConnection = chrome.runtime.connect();
|
||||
backgroundPageConnection.onMessage.addListener(function (message) {
|
||||
// Handle responses from the background page, if any
|
||||
switch (message.type) {
|
||||
case 'AXS_SHOW_RESULTS': {
|
||||
const { idToWarningsMap } = message.data;
|
||||
if (_window) {
|
||||
_window.showAxsResults(idToWarningsMap);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'HIGHLIGHT_REPORT': {
|
||||
const { warningId } = message.data;
|
||||
if (_window) {
|
||||
_window.highlightReportLine(warningId);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'UNHIGHLIGHT_REPORT': {
|
||||
const { warningId } = message.data;
|
||||
if (_window) {
|
||||
_window.unhighlightReportLine(warningId);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
panel.onShown.addListener(function(window) {
|
||||
_window = window;
|
||||
});
|
||||
panel.onHidden.addListener(function() {
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
createPanel();
|
||||
28
GitHub Desktop-dev/extensions/idikgljglpfilbhaboonnpnnincjhjkd/manifest.json
Executable file
28
GitHub Desktop-dev/extensions/idikgljglpfilbhaboonnpnnincjhjkd/manifest.json
Executable file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"update_url": "https://clients2.google.com/service/update2/crx",
|
||||
|
||||
"manifest_version": 2,
|
||||
"name": "ChromeLens",
|
||||
"description": "Visual impairment simulation and auditing tools to develop for accessibility.",
|
||||
"version": "0.0.10",
|
||||
"minimum_chrome_version": "42",
|
||||
"devtools_page": "main.html",
|
||||
|
||||
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
|
||||
"web_accessible_resources": [ "main.html", "panel.html", "build/backend.js"],
|
||||
|
||||
"background": {
|
||||
"scripts": [ "background.js" ]
|
||||
},
|
||||
|
||||
"icons": {
|
||||
"48": "icons/chromelens2-48.png",
|
||||
"128": "icons/chromelens2-128.png"
|
||||
},
|
||||
|
||||
"permissions": [
|
||||
"http://*/*",
|
||||
"https://*/*",
|
||||
"activeTab"
|
||||
]
|
||||
}
|
||||
120
GitHub Desktop-dev/extensions/idikgljglpfilbhaboonnpnnincjhjkd/panel.html
Executable file
120
GitHub Desktop-dev/extensions/idikgljglpfilbhaboonnpnnincjhjkd/panel.html
Executable file
@@ -0,0 +1,120 @@
|
||||
<!doctype html>
|
||||
<html style="display: flex">
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<style>
|
||||
h1 {
|
||||
color: rgb(70, 76, 88);
|
||||
font-size: 20px;
|
||||
line-height: 24px;
|
||||
font-weight: normal;
|
||||
margin-top: 0;
|
||||
}
|
||||
h2 {
|
||||
color: rgb(110, 116, 128);
|
||||
font-size: 16px;
|
||||
line-height: 20px;
|
||||
font-weight: normal;
|
||||
margin-top: 0;
|
||||
}
|
||||
body {
|
||||
padding: 16px;
|
||||
background-color: white;
|
||||
}
|
||||
.warning {
|
||||
color: #e69808;
|
||||
}
|
||||
.severe {
|
||||
color: #c10f0f;
|
||||
}
|
||||
.vbox {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.sidebar {
|
||||
overflow-x: hidden;
|
||||
background: #f3f3f3;
|
||||
max-width: 330px;
|
||||
min-width: 170px;
|
||||
}
|
||||
.f {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
button {
|
||||
background-image: linear-gradient(hsl(0, 0%, 93%), hsl(0, 0%, 93%) 38%, hsl(0, 0%, 87%));
|
||||
border: 1px solid hsla(0, 0%, 0%, 0.25);
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 1px 0 hsla(0, 0%, 0%, 0.08), inset 0 1px 2px hsla(0, 100%, 100%, 0.75);
|
||||
color: hsl(0, 0%, 27%);
|
||||
font-size: 12px;
|
||||
margin: 0 1px 0 0;
|
||||
text-shadow: 0 1px 0 hsl(0, 0%, 94%);
|
||||
min-height: 2em !important;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
-webkit-user-select: none;
|
||||
flex: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>ChromeLens</h1>
|
||||
<p>A tool for accessibility development</p>
|
||||
|
||||
<section class="f">
|
||||
<h2>Lenses</h2>
|
||||
<p>See how the page looks like through the eyes of someone with vision issues.</p>
|
||||
<input id="lensEnabledCheckbox" type="checkbox"><span>Enable lens</span></input>
|
||||
|
||||
<select id="lensSelector" disabled="true">
|
||||
<option value="full_blindness">Full blindness</option>
|
||||
<option value="partial_blindness_mild">Partial blindness (mild)</option>
|
||||
<option value="partial_blindness_medium">Partial blindness (medium)</option>
|
||||
<option value="partial_blindness_serious">Partial blindness (serious)</option>
|
||||
<option value="protanomaly">Protanomaly (red-weak)</option>
|
||||
<option value="protanopia">Protanopia (red-blind)</option>
|
||||
<option value="deuteranomaly">Deuteranomaly (green-weak)</option>
|
||||
<option value="deuteranopia">Deuteranopia (green-blind)</option>
|
||||
<option value="tritanomaly">Tritanomaly (blue-weak)</option>
|
||||
<option value="tritanopia">Tritanopia (blue-blind)</option>
|
||||
<option value="achromatomaly">Achromatomaly (RGB-weak)</option>
|
||||
<option value="achromatopsia">Achromatopsia (RGB-blind)</option>
|
||||
</select>
|
||||
|
||||
<div id="lensDetail"></div>
|
||||
<div id="statsDetail"></div>
|
||||
</section>
|
||||
|
||||
<section class="f">
|
||||
<h2>Accessibility checks</h2>
|
||||
<p>Audits the current page using Google's accessibility developer tools.</p>
|
||||
<button id='runAxs'>
|
||||
Run accessibility checks
|
||||
</button>
|
||||
|
||||
<button id='clearAxs' style='visibility: hidden'>
|
||||
Clear checks
|
||||
</button>
|
||||
|
||||
<div id="axs-results">
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="f">
|
||||
<h2>Trace tab path</h2>
|
||||
<p>
|
||||
Key website features should be keyboard-navigable with the tab button.
|
||||
Trace the path of your tab navigation flow graphically with this tool.
|
||||
</p>
|
||||
<button id='traceTabPath'>
|
||||
Start trace
|
||||
</button>
|
||||
|
||||
<button id='pngTabPath' style="visibility: hidden">
|
||||
Download PNG
|
||||
</button>
|
||||
</section>
|
||||
|
||||
<script src="panel.js" type="text/javascript" charset="utf-8"></script>
|
||||
</body>
|
||||
</html>
|
||||
319
GitHub Desktop-dev/extensions/idikgljglpfilbhaboonnpnnincjhjkd/panel.js
Executable file
319
GitHub Desktop-dev/extensions/idikgljglpfilbhaboonnpnnincjhjkd/panel.js
Executable file
@@ -0,0 +1,319 @@
|
||||
// Utilities
|
||||
//
|
||||
function log(...s) {
|
||||
const string = JSON.stringify(s);
|
||||
chrome.devtools.inspectedWindow.eval('console.log(' + string + ')')
|
||||
};
|
||||
|
||||
const messageType = {
|
||||
EXECUTE_SCRIPT: 'EXECUTE_SCRIPT',
|
||||
RUN_AXS: 'RUN_AXS',
|
||||
HIGHLIGHT_WARNING: 'HIGHLIGHT_WARNING',
|
||||
UNHIGHLIGHT_WARNING: 'UNHIGHLIGHT_WARNING',
|
||||
TRACE_TAB_PATH: 'TRACE_TAB_PATH',
|
||||
PNG_TAB_PATH: 'PNG_TAB_PATH',
|
||||
CLEAR_AXS: 'CLEAR_AXS'
|
||||
}
|
||||
|
||||
const WARNING_ATTR_NAME = 'chromelens-warning-id';
|
||||
|
||||
const lensType = {
|
||||
ACHROMATOMALY: {
|
||||
name: 'Achromatomaly',
|
||||
file: 'lens_achromatomaly.js',
|
||||
stats: { },
|
||||
description: 'Absence of most colors.'
|
||||
},
|
||||
ACHROMATOPSIA: {
|
||||
name: 'Achromatopsia',
|
||||
file: 'lens_achromatopsia.js',
|
||||
stats: { },
|
||||
description: 'No colors at all.'
|
||||
},
|
||||
DEUTERANOMALY: {
|
||||
name: 'Deuteranomaly',
|
||||
file: 'lens_deuteranomaly.js',
|
||||
stats: {
|
||||
male: 5,
|
||||
female: 0.35
|
||||
},
|
||||
description: 'Low amounts of green color.'
|
||||
},
|
||||
DEUTERANOPIA: {
|
||||
name: 'Deuteranopia',
|
||||
file: 'lens_deuteranopia.js',
|
||||
stats: {
|
||||
male: 1,
|
||||
female: 0.1
|
||||
},
|
||||
description: 'No green color at all.'
|
||||
},
|
||||
EMPTY: {
|
||||
name: 'Normal vision',
|
||||
file: 'lens_empty.js',
|
||||
stats: { },
|
||||
description: 'Normal vision.'
|
||||
},
|
||||
FULL_BLINDNESS: {
|
||||
name: 'Full blindness',
|
||||
file: 'lens_fullblindness.js',
|
||||
stats: {
|
||||
count: '39 million (WHO)'
|
||||
},
|
||||
description: 'No vision at all.'
|
||||
},
|
||||
PARTIAL_BLINDNESS_MILD: {
|
||||
name: 'Partial blindness (mild)',
|
||||
file: 'lens_partialblindness_mild.js',
|
||||
stats: {
|
||||
count: '246 million (WHO)'
|
||||
},
|
||||
description: 'Limited vision (mild).'
|
||||
},
|
||||
PARTIAL_BLINDNESS_MEDIUM: {
|
||||
name: 'Partial blindness (medium)',
|
||||
file: 'lens_partialblindness_medium.js',
|
||||
stats: {
|
||||
count: '246 million (WHO)'
|
||||
},
|
||||
description: 'Limited vision (medium).'
|
||||
},
|
||||
PARTIAL_BLINDNESS_SERIOUS: {
|
||||
name: 'Partial blindness (serious)',
|
||||
file: 'lens_partialblindness_serious.js',
|
||||
stats: {
|
||||
count: '246 million (WHO)'
|
||||
},
|
||||
description: 'Limited vision (serious). Able to differentiate light vs dark.'
|
||||
},
|
||||
PROTANOMALY: {
|
||||
name: 'Protanomaly',
|
||||
file: 'lens_protanomaly.js',
|
||||
stats: {
|
||||
male: 1.08,
|
||||
female: 0.03
|
||||
},
|
||||
description: 'Low amounts of red color.',
|
||||
},
|
||||
PROTANOPIA: {
|
||||
name: 'Protanopia',
|
||||
file: 'lens_protanopia.js',
|
||||
stats: {
|
||||
male: 1.01,
|
||||
female: 0.02
|
||||
},
|
||||
description: 'No red color at all.'
|
||||
},
|
||||
TRITANOMALY: {
|
||||
name: 'Tritanomaly',
|
||||
file: 'lens_tritanomaly.js',
|
||||
stats: { },
|
||||
description: 'Low amounts of blue color.'
|
||||
},
|
||||
TRITANOPIA: {
|
||||
name: 'Tritanopia',
|
||||
file: 'lens_tritanopia.js',
|
||||
stats: { },
|
||||
description: 'No blue color at all.'
|
||||
}
|
||||
}
|
||||
|
||||
// Global state
|
||||
const lensDir = 'lenses/filters/';
|
||||
|
||||
const changeLens = (lens) => {
|
||||
// Remove any lens div
|
||||
chrome.runtime.sendMessage({
|
||||
type: messageType.EXECUTE_SCRIPT,
|
||||
data: {
|
||||
tabId: chrome.devtools.inspectedWindow.tabId,
|
||||
scriptToInject: lensDir + 'reset.js'
|
||||
}
|
||||
});
|
||||
chrome.runtime.sendMessage({
|
||||
type: messageType.EXECUTE_SCRIPT,
|
||||
data: {
|
||||
tabId: chrome.devtools.inspectedWindow.tabId,
|
||||
scriptToInject: lensDir + lens.file
|
||||
}
|
||||
});
|
||||
const { description, stats } = lens;
|
||||
|
||||
const lensDetail = document.getElementById('lensDetail');
|
||||
lensDetail.innerHTML = description;
|
||||
|
||||
const statsDetail = document.getElementById('statsDetail');
|
||||
statsDetail.innerHTML = `
|
||||
Affects: <br />
|
||||
Population % - Male: ${stats.male || 'unknown'}, Female: ${stats.female || 'unknown'} <br />
|
||||
Population count: ${stats.count}
|
||||
`;
|
||||
|
||||
// http://www.colourblindawareness.org/colour-blindness/types-of-colour-blindness/
|
||||
// http://www.color-blindness.com/
|
||||
}
|
||||
|
||||
const addEventListeners = () => {
|
||||
const lensSelector = document.getElementById('lensSelector');
|
||||
const getSelectedLens = () => {
|
||||
const { options, selectedIndex } = lensSelector;
|
||||
const { value } = options[selectedIndex];
|
||||
const lens = lensType[value.toUpperCase()];
|
||||
return lens;
|
||||
}
|
||||
const setSelectedLens = () => lensEnabledCheckbox.checked ?
|
||||
changeLens(getSelectedLens()) : changeLens(lensType.EMPTY);
|
||||
|
||||
lensSelector.onchange = setSelectedLens;
|
||||
|
||||
const lensEnabledCheckbox = document.getElementById('lensEnabledCheckbox');
|
||||
lensEnabledCheckbox.onclick = function() {
|
||||
lensSelector.disabled = !this.checked;
|
||||
setSelectedLens();
|
||||
}
|
||||
|
||||
// Maintain lens across navigations
|
||||
chrome.devtools.network.onNavigated.addListener(setSelectedLens);
|
||||
|
||||
const runAxsButton = document.getElementById('runAxs');
|
||||
const clearAxsButton = document.getElementById('clearAxs');
|
||||
runAxsButton.onclick = function() {
|
||||
chrome.runtime.sendMessage({
|
||||
type: messageType.RUN_AXS,
|
||||
data: {
|
||||
tabId: chrome.devtools.inspectedWindow.tabId
|
||||
}
|
||||
})
|
||||
clearAxsButton.style.visibility = null;
|
||||
};
|
||||
|
||||
clearAxsButton.onclick = function() {
|
||||
chrome.runtime.sendMessage({
|
||||
type: messageType.CLEAR_AXS,
|
||||
data: {
|
||||
tabId: chrome.devtools.inspectedWindow.tabId
|
||||
}
|
||||
})
|
||||
const resultRoot = document.getElementById('axs-results');
|
||||
removeChildren(resultRoot);
|
||||
clearAxsButton.style.visibility = 'hidden';
|
||||
}
|
||||
|
||||
const traceTabPathButton = document.getElementById('traceTabPath');
|
||||
const pngTabPathButton = document.getElementById('pngTabPath');
|
||||
|
||||
traceTabPathButton.onclick = function() {
|
||||
chrome.runtime.sendMessage({
|
||||
type: messageType.TRACE_TAB_PATH,
|
||||
data: {
|
||||
tabId: chrome.devtools.inspectedWindow.tabId
|
||||
}
|
||||
})
|
||||
pngTabPathButton.style.visibility = null;
|
||||
};
|
||||
|
||||
pngTabPathButton.onclick = function() {
|
||||
chrome.runtime.sendMessage({
|
||||
type: messageType.PNG_TAB_PATH,
|
||||
data: {
|
||||
tabId: chrome.devtools.inspectedWindow.tabId
|
||||
}
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
function removeChildren(el) {
|
||||
if (!el) { return; }
|
||||
while (el.children.length > 0) {
|
||||
el.children[0].remove()
|
||||
}
|
||||
}
|
||||
|
||||
function severityNode(severity) {
|
||||
var span = document.createElement('span');
|
||||
span.classList.add( severity.toLowerCase());
|
||||
span.innerText = severity;
|
||||
return span;
|
||||
}
|
||||
|
||||
function showAxsResults(idToWarningsMap) {
|
||||
const resultRoot = document.querySelector('#axs-results');
|
||||
removeChildren(resultRoot);
|
||||
if (Object.keys(idToWarningsMap).length === 0) {
|
||||
const p = document.createElement('p');
|
||||
p.textContent = 'No failures found';
|
||||
resultRoot.appendChild(p);
|
||||
return;
|
||||
}
|
||||
|
||||
const ul = document.createElement('ul');
|
||||
for (i in idToWarningsMap) {
|
||||
var div = document.createElement('li');
|
||||
div.classList.add('result-line');
|
||||
div.id = i;
|
||||
|
||||
var s_el = severityNode(idToWarningsMap[i].rule.severity);
|
||||
div.appendChild(s_el);
|
||||
div.appendChild(document.createTextNode(' '));
|
||||
|
||||
var div_note = idToWarningsMap[i].rule.heading;
|
||||
div.appendChild(document.createTextNode(div_note))
|
||||
|
||||
var link = document.createElement('a');
|
||||
link.href = idToWarningsMap[i].rule.url;
|
||||
link.target = '_blank';
|
||||
link.innerText = idToWarningsMap[i].rule.code;
|
||||
|
||||
div.appendChild(document.createTextNode(' '));
|
||||
div.appendChild(link);
|
||||
|
||||
div.onmouseover = function() {
|
||||
_highlight(this);
|
||||
chrome.runtime.sendMessage({
|
||||
type: messageType.HIGHLIGHT_WARNING,
|
||||
data: {
|
||||
tabId: chrome.devtools.inspectedWindow.tabId,
|
||||
warningId: i
|
||||
}
|
||||
});
|
||||
};
|
||||
div.onmouseout = function() {
|
||||
_unhighlight(this);
|
||||
chrome.runtime.sendMessage({
|
||||
type: messageType.UNHIGHLIGHT_WARNING,
|
||||
data: {
|
||||
tabId: chrome.devtools.inspectedWindow.tabId,
|
||||
warningId: i
|
||||
}
|
||||
});
|
||||
};
|
||||
let evalString = `var node = document.querySelector("[${WARNING_ATTR_NAME}='${i}']"); inspect(node)`
|
||||
div.onmousedown = function() {
|
||||
chrome.devtools.inspectedWindow.eval(evalString)
|
||||
};
|
||||
|
||||
ul.appendChild(div);
|
||||
}
|
||||
|
||||
resultRoot.appendChild(ul);
|
||||
}
|
||||
|
||||
function highlightReportLine(warningId) {
|
||||
const line = document.getElementById(warningId);
|
||||
if (line) { _highlight(line); }
|
||||
}
|
||||
|
||||
function unhighlightReportLine(warningId) {
|
||||
const line = document.getElementById(warningId);
|
||||
if (line) { _unhighlight(line); }
|
||||
}
|
||||
|
||||
function _highlight(lineEl) {
|
||||
lineEl.style.border = '2px solid blue';
|
||||
}
|
||||
|
||||
function _unhighlight(lineEl) {
|
||||
lineEl.style.border = null;
|
||||
}
|
||||
|
||||
addEventListeners();
|
||||
3375
GitHub Desktop-dev/extensions/idikgljglpfilbhaboonnpnnincjhjkd/tracer/html2canvas.js
Executable file
3375
GitHub Desktop-dev/extensions/idikgljglpfilbhaboonnpnnincjhjkd/tracer/html2canvas.js
Executable file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
||||
html2canvas(document.body).then(function(canvas) {
|
||||
canvas.toBlob(function(blob) {
|
||||
var a = document.createElement('a');
|
||||
var url = URL.createObjectURL(blob);
|
||||
a.href = url;
|
||||
a.download = 'png.png';
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
})
|
||||
});
|
||||
@@ -0,0 +1,88 @@
|
||||
// Delete any applied filters
|
||||
delete document.body.style.filter;
|
||||
delete document.body.style.webkitFilter;
|
||||
|
||||
var body = document.body;
|
||||
var html = document.documentElement;
|
||||
|
||||
function drawLine(ctx, x, y) {
|
||||
ctx.lineTo(x, y);
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
function drawDot(ctx, x, y) {
|
||||
ctx.arc(x, y, 3, 0, 2 * Math.PI, false);
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
function getCoordinates(elem) {
|
||||
var box = elem.getBoundingClientRect();
|
||||
var body = document.body;
|
||||
var docEl = document.documentElement;
|
||||
var halfWidth = box.width / 2;
|
||||
var halfHeight = box.height / 2;
|
||||
|
||||
var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
|
||||
var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;
|
||||
|
||||
var clientTop = docEl.clientTop || body.clientTop || 0;
|
||||
var clientLeft = docEl.clientLeft || body.clientLeft || 0;
|
||||
|
||||
var top = box.top + scrollTop - clientTop;
|
||||
var left = box.left + scrollLeft - clientLeft;
|
||||
|
||||
return {
|
||||
top: Math.round(top + halfHeight),
|
||||
left: Math.round(left + halfWidth)
|
||||
};
|
||||
}
|
||||
|
||||
var height = Math.max(
|
||||
body.scrollHeight,
|
||||
body.offsetHeight,
|
||||
html.clientHeight,
|
||||
html.scrollHeight,
|
||||
html.offsetHeight
|
||||
);
|
||||
|
||||
var width = Math.max(
|
||||
body.scrollWidth,
|
||||
body.offsetWidth,
|
||||
html.clientWidth,
|
||||
html.scrollWidth,
|
||||
html.offsetWidth
|
||||
);
|
||||
|
||||
var canvas = document.createElement("canvas");
|
||||
canvas.id = 'chrome-lens-canvas';
|
||||
canvas.style.pointerEvents = 'none';
|
||||
canvas.style.top = 0;
|
||||
canvas.style.left = 0;
|
||||
canvas.height = height;
|
||||
canvas.width = width;
|
||||
canvas.style.position = 'absolute';
|
||||
canvas.style.zIndex = 2147483647;
|
||||
|
||||
var ctx = canvas.getContext('2d');
|
||||
ctx.strokeStyle = 'red';
|
||||
ctx.lineWidth = 2;
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(0, 0);
|
||||
|
||||
if (document.activeElement !== document.body) {
|
||||
const { top: y, left: x } = getCoordinates(document.activeElement);
|
||||
drawLine(ctx, x, y);
|
||||
}
|
||||
|
||||
document.body.appendChild(canvas);
|
||||
|
||||
document.body.onkeyup = function (e) {
|
||||
e = e || window.event;
|
||||
if (e.keyCode === 9) {
|
||||
// Tab
|
||||
const { top: y, left: x } = getCoordinates(e.target);
|
||||
drawLine(ctx, x, y);
|
||||
drawDot(ctx, x, y);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user