Home | History | Annotate | Download | only in js
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 /**
      6  * The global object.
      7  * @type {!Object}
      8  */
      9 const global = this;
     10 
     11 // TODO(estade): This should be removed and calls replaced with cr.isMac
     12 const IS_MAC = /^Mac/.test(navigator.platform);
     13 
     14 /**
     15  * Alias for document.getElementById.
     16  * @param {string} id The ID of the element to find.
     17  * @return {HTMLElement} The found element or null if not found.
     18  */
     19 function $(id) {
     20   return document.getElementById(id);
     21 }
     22 
     23 /**
     24  * Calls chrome.send with a callback and restores the original afterwards.
     25  * @param {string} name The name of the message to send.
     26  * @param {!Array} params The parameters to send.
     27  * @param {string} callbackName The name of the function that the backend calls.
     28  * @param {!Function} The function to call.
     29  */
     30 function chromeSend(name, params, callbackName, callback) {
     31   var old = global[callbackName];
     32   global[callbackName] = function() {
     33     // restore
     34     global[callbackName] = old;
     35 
     36     var args = Array.prototype.slice.call(arguments);
     37     return callback.apply(global, args);
     38   };
     39   chrome.send(name, params);
     40 }
     41 
     42 /**
     43  * Generates a CSS url string.
     44  * @param {string} s The URL to generate the CSS url for.
     45  * @return {string} The CSS url string.
     46  */
     47 function url(s) {
     48   // http://www.w3.org/TR/css3-values/#uris
     49   // Parentheses, commas, whitespace characters, single quotes (') and double
     50   // quotes (") appearing in a URI must be escaped with a backslash
     51   var s2 = s.replace(/(\(|\)|\,|\s|\'|\"|\\)/g, '\\$1');
     52   // WebKit has a bug when it comes to URLs that end with \
     53   // https://bugs.webkit.org/show_bug.cgi?id=28885
     54   if (/\\\\$/.test(s2)) {
     55     // Add a space to work around the WebKit bug.
     56     s2 += ' ';
     57   }
     58   return 'url("' + s2 + '")';
     59 }
     60 
     61 /**
     62  * Parses query parameters from Location.
     63  * @param {string} s The URL to generate the CSS url for.
     64  * @return {object} Dictionary containing name value pairs for URL
     65  */
     66 function parseQueryParams(location) {
     67   var params = {};
     68   var query = unescape(location.search.substring(1));
     69   var vars = query.split("&");
     70   for (var i=0; i < vars.length; i++) {
     71     var pair = vars[i].split("=");
     72     params[pair[0]] = pair[1];
     73   }
     74   return params;
     75 }
     76 
     77 function findAncestorByClass(el, className) {
     78   return findAncestor(el, function(el) {
     79     if (el.classList)
     80       return el.classList.contains(className);
     81     return null;
     82   });
     83 }
     84 
     85 /**
     86  * Return the first ancestor for which the {@code predicate} returns true.
     87  * @param {Node} node The node to check.
     88  * @param {function(Node) : boolean} predicate The function that tests the
     89  *     nodes.
     90  * @return {Node} The found ancestor or null if not found.
     91  */
     92 function findAncestor(node, predicate) {
     93   var last = false;
     94   while (node != null && !(last = predicate(node))) {
     95     node = node.parentNode;
     96   }
     97   return last ? node : null;
     98 }
     99 
    100 function swapDomNodes(a, b) {
    101   var afterA = a.nextSibling;
    102   if (afterA == b) {
    103     swapDomNodes(b, a);
    104     return;
    105   }
    106   var aParent = a.parentNode;
    107   b.parentNode.replaceChild(a, b);
    108   aParent.insertBefore(b, afterA);
    109 }
    110 
    111 // Handle click on a link. If the link points to a chrome: or file: url, then
    112 // call into the browser to do the navigation.
    113 document.addEventListener('click', function(e) {
    114   // Allow preventDefault to work.
    115   if (!e.returnValue)
    116     return;
    117 
    118   var el = e.target;
    119   if (el.nodeType == Node.ELEMENT_NODE &&
    120       el.webkitMatchesSelector('A, A *')) {
    121     while (el.tagName != 'A') {
    122       el = el.parentElement;
    123     }
    124 
    125     if ((el.protocol == 'file:' || el.protocol == 'about:') &&
    126         (e.button == 0 || e.button == 1)) {
    127       chrome.send('navigateToUrl', [
    128         el.href,
    129         el.target,
    130         e.button,
    131         e.altKey,
    132         e.ctrlKey,
    133         e.metaKey,
    134         e.shiftKey
    135       ]);
    136       e.preventDefault();
    137     }
    138   }
    139 });
    140