11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright (c) 2014 The Chromium Authors. All rights reserved. 21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be 31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file. 41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivar mode; 61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivar enabled = false; 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivar scheme = ''; 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivar timeoutId = null; 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivar filterMap = { 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci '0': 'url("#hc_extension_off")', 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci '1': 'url("#hc_extension_highcontrast")', 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci '2': 'url("#hc_extension_grayscale")', 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci '3': 'url("#hc_extension_invert")', 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci '4': 'url("#hc_extension_invert_grayscale")', 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci '5': 'url("#hc_extension_yellow_on_black")' 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}; 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivar svgContent = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1"><defs><filter id="hc_extension_off"><feComponentTransfer><feFuncR type="table" tableValues="0 1"/><feFuncG type="table" tableValues="0 1"/><feFuncB type="table" tableValues="0 1"/></feComponentTransfer></filter><filter id="hc_extension_highcontrast"><feComponentTransfer><feFuncR type="gamma" exponent="3.0"/><feFuncG type="gamma" exponent="3.0"/><feFuncB type="gamma" exponent="3.0"/></feComponentTransfer></filter><filter id="hc_extension_highcontrast_back"><feComponentTransfer><feFuncR type="gamma" exponent="0.33"/><feFuncG type="gamma" exponent="0.33"/><feFuncB type="gamma" exponent="0.33"/></feComponentTransfer></filter><filter id="hc_extension_grayscale"><feColorMatrix type="matrix" values="0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0 0 0 1 0"/><feComponentTransfer><feFuncR type="gamma" exponent="3"/><feFuncG type="gamma" exponent="3"/><feFuncB type="gamma" exponent="3"/></feComponentTransfer></filter><filter id="hc_extension_grayscale_back"><feComponentTransfer><feFuncR type="gamma" exponent="0.33"/><feFuncG type="gamma" exponent="0.33"/><feFuncB type="gamma" exponent="0.33"/></feComponentTransfer></filter><filter id="hc_extension_invert"><feComponentTransfer><feFuncR type="gamma" amplitude="-1" exponent="3" offset="1"/><feFuncG type="gamma" amplitude="-1" exponent="3" offset="1"/><feFuncB type="gamma" amplitude="-1" exponent="3" offset="1"/></feComponentTransfer></filter><filter id="hc_extension_invert_back"><feComponentTransfer><feFuncR type="table" tableValues="1 0"/><feFuncG type="table" tableValues="1 0"/><feFuncB type="table" tableValues="1 0"/></feComponentTransfer><feComponentTransfer><feFuncR type="gamma" exponent="1.7"/><feFuncG type="gamma" exponent="1.7"/><feFuncB type="gamma" exponent="1.7"/></feComponentTransfer></filter><filter id="hc_extension_invert_grayscale"><feColorMatrix type="matrix" values="0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0 0 0 1 0"/><feComponentTransfer><feFuncR type="gamma" amplitude="-1" exponent="3" offset="1"/><feFuncG type="gamma" amplitude="-1" exponent="3" offset="1"/><feFuncB type="gamma" amplitude="-1" exponent="3" offset="1"/></feComponentTransfer></filter><filter id="hc_extension_yellow_on_black"><feComponentTransfer><feFuncR type="gamma" amplitude="-1" exponent="3" offset="1"/><feFuncG type="gamma" amplitude="-1" exponent="3" offset="1"/><feFuncB type="gamma" amplitude="-1" exponent="3" offset="1"/></feComponentTransfer><feColorMatrix type="matrix" values="0.3 0.5 0.2 0 0 0.3 0.5 0.2 0 0 0 0 0 0 0 0 0 0 1 0"/></filter><filter id="hc_extension_yellow_on_black_back"><feComponentTransfer><feFuncR type="table" tableValues="1 0"/><feFuncG type="table" tableValues="1 0"/><feFuncB type="table" tableValues="1 0"/></feComponentTransfer><feComponentTransfer><feFuncR type="gamma" exponent="0.33"/><feFuncG type="gamma" exponent="0.33"/><feFuncB type="gamma" exponent="0.33"/></feComponentTransfer></filter></defs></svg>'; 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccifunction addSvgIfMissing() { 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci var wrap = document.getElementById('hc_extension_svg_filters'); 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (wrap) 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci wrap = document.createElement('span'); 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci wrap.id = 'hc_extension_svg_filters'; 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci wrap.setAttribute('hidden', ''); 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci wrap.innerHTML = svgContent; 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci document.body.appendChild(wrap); 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccifunction update() { 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci var html = document.documentElement; 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (enabled) { 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!document.body) { 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci window.setTimeout(update, 100); 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci addSvgIfMissing(); 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (html.getAttribute('hc') != mode + scheme) 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci html.setAttribute('hc', mode + scheme); 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (html.getAttribute('hcx') != scheme) 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci html.setAttribute('hcx', scheme); 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (window == window.top) { 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci window.scrollBy(0, 1); 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci window.scrollBy(0, -1); 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /** 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (mode == 'a') { 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci html.style.webkitFilter = filterMap[scheme]; 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci else { 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci html.style.webkitFilter = 'none'; 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci }**/ 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci html.setAttribute('hc', mode + '0'); 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci html.setAttribute('hcx', '0'); 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci window.setTimeout(function() { 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci html.removeAttribute('hc'); 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci html.removeAttribute('hcx'); 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci }, 0); 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccifunction onExtensionMessage(request) { 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (enabled != request.enabled || scheme != request.scheme) { 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci enabled = request.enabled; 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scheme = request.scheme; 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci update(); 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccifunction onEvent(evt) { 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (evt.keyCode == 122 /* F11 */ && 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci evt.shiftKey) { 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci chrome.extension.sendRequest({'toggle_global': true}); 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci evt.stopPropagation(); 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci evt.preventDefault(); 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (evt.keyCode == 123 /* F12 */ && 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci evt.shiftKey) { 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci chrome.extension.sendRequest({'toggle_site': true}); 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci evt.stopPropagation(); 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci evt.preventDefault(); 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccifunction init() { 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (window == window.top) { 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci mode = 'a'; 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci mode = 'b'; 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci chrome.extension.onRequest.addListener(onExtensionMessage); 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci chrome.extension.sendRequest({'init': true}, onExtensionMessage); 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci document.addEventListener('keydown', onEvent, false); 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Work around bug that causes filter to be lost when the HTML element's attributes change. 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci var html = document.documentElement; 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci var config = { attributes: true, childList: false, characterData: false }; 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci var observer = new MutationObserver(function(mutations) { 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci observer.disconnect(); 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci html.removeAttribute('hc'); 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci html.removeAttribute('hcx'); 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci window.setTimeout(function() { 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci update(); 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci window.setTimeout(function() { 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci observer.observe(html, config); 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci }, 0); 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci }, 0); 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci }); 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci observer.observe(html, config); 1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciinit(); 122