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