| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 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 * @const | |
| 9 */ | |
| 10 var global = this; | |
| 11 | |
| 12 /** | |
| 13 * Alias for document.getElementById. | |
| 14 * @param {string} id The ID of the element to find. | |
| 15 * @return {HTMLElement} The found element or null if not found. | |
| 16 */ | |
| 17 function $(id) { | |
| 18 return document.getElementById(id); | |
| 19 } | |
| 20 | |
| 21 /** | |
| 22 * Calls chrome.send with a callback and restores the original afterwards. | |
| 23 * @param {string} name The name of the message to send. | |
| 24 * @param {!Array} params The parameters to send. | |
| 25 * @param {string} callbackName The name of the function that the backend calls. | |
| 26 * @param {!Function} callback The function to call. | |
| 27 */ | |
| 28 function chromeSend(name, params, callbackName, callback) { | |
| 29 var old = global[callbackName]; | |
| 30 global[callbackName] = function() { | |
| 31 // restore | |
| 32 global[callbackName] = old; | |
| 33 | |
| 34 var args = Array.prototype.slice.call(arguments); | |
| 35 return callback.apply(global, args); | |
| 36 }; | |
| 37 chrome.send(name, params); | |
| 38 } | |
| 39 | |
| 40 /** | |
| 41 * Generates a CSS url string. | |
| 42 * @param {string} s The URL to generate the CSS url for. | |
| 43 * @return {string} The CSS url string. | |
| 44 */ | |
| 45 function url(s) { | |
| 46 // http://www.w3.org/TR/css3-values/#uris | |
| 47 // Parentheses, commas, whitespace characters, single quotes (') and double | |
| 48 // quotes (") appearing in a URI must be escaped with a backslash | |
| 49 var s2 = s.replace(/(\(|\)|\,|\s|\'|\"|\\)/g, '\\$1'); | |
| 50 // WebKit has a bug when it comes to URLs that end with \ | |
| 51 // https://bugs.webkit.org/show_bug.cgi?id=28885 | |
| 52 if (/\\\\$/.test(s2)) { | |
| 53 // Add a space to work around the WebKit bug. | |
| 54 s2 += ' '; | |
| 55 } | |
| 56 return 'url("' + s2 + '")'; | |
| 57 } | |
| 58 | |
| 59 /** | |
| 60 * Parses query parameters from Location. | |
| 61 * @param {string} location The URL to generate the CSS url for. | |
| 62 * @return {object} Dictionary containing name value pairs for URL | |
| 63 */ | |
| 64 function parseQueryParams(location) { | |
| 65 var params = {}; | |
| 66 var query = unescape(location.search.substring(1)); | |
| 67 var vars = query.split('&'); | |
| 68 for (var i = 0; i < vars.length; i++) { | |
| 69 var pair = vars[i].split('='); | |
| 70 params[pair[0]] = pair[1]; | |
| 71 } | |
| 72 return params; | |
| 73 } | |
| 74 | |
| 75 function findAncestorByClass(el, className) { | |
| 76 return findAncestor(el, function(el) { | |
| 77 if (el.classList) | |
| 78 return el.classList.contains(className); | |
| 79 return null; | |
| 80 }); | |
| 81 } | |
| 82 | |
| 83 /** | |
| 84 * Return the first ancestor for which the {@code predicate} returns true. | |
| 85 * @param {Node} node The node to check. | |
| 86 * @param {function(Node) : boolean} predicate The function that tests the | |
| 87 * nodes. | |
| 88 * @return {Node} The found ancestor or null if not found. | |
| 89 */ | |
| 90 function findAncestor(node, predicate) { | |
| 91 var last = false; | |
| 92 while (node != null && !(last = predicate(node))) { | |
| 93 node = node.parentNode; | |
| 94 } | |
| 95 return last ? node : null; | |
| 96 } | |
| 97 | |
| 98 function swapDomNodes(a, b) { | |
| 99 var afterA = a.nextSibling; | |
| 100 if (afterA == b) { | |
| 101 swapDomNodes(b, a); | |
| 102 return; | |
| 103 } | |
| 104 var aParent = a.parentNode; | |
| 105 b.parentNode.replaceChild(a, b); | |
| 106 aParent.insertBefore(b, afterA); | |
| 107 } | |
| 108 | |
| 109 /** | |
| 110 * Disables text selection and dragging, with optional whitelist callbacks. | |
| 111 * @param {function(Event):boolean=} opt_allowSelectStart Unless this function | |
| 112 * is defined and returns true, the onselectionstart event will be | |
| 113 * surpressed. | |
| 114 * @param {function(Event):boolean=} opt_allowDragStart Unless this function | |
| 115 * is defined and returns true, the ondragstart event will be surpressed. | |
| 116 */ | |
| 117 function disableTextSelectAndDrag(opt_allowSelectStart, opt_allowDragStart) { | |
| 118 // Disable text selection. | |
| 119 document.onselectstart = function(e) { | |
| 120 if (!(opt_allowSelectStart && opt_allowSelectStart.call(this, e))) | |
| 121 e.preventDefault(); | |
| 122 }; | |
| 123 | |
| 124 // Disable dragging. | |
| 125 document.ondragstart = function(e) { | |
| 126 if (!(opt_allowDragStart && opt_allowDragStart.call(this, e))) | |
| 127 e.preventDefault(); | |
| 128 }; | |
| 129 } | |
| 130 | |
| 131 /** | |
| 132 * Call this to stop clicks on <a href="#"> links from scrolling to the top of | |
| 133 * the page (and possibly showing a # in the link). | |
| 134 */ | |
| 135 function preventDefaultOnPoundLinkClicks() { | |
| 136 document.addEventListener('click', function(e) { | |
| 137 var anchor = findAncestor(e.target, function(el) { | |
| 138 return el.tagName == 'A'; | |
| 139 }); | |
| 140 // Use getAttribute() to prevent URL normalization. | |
| 141 if (anchor && anchor.getAttribute('href') == '#') | |
| 142 e.preventDefault(); | |
| 143 }); | |
| 144 } | |
| 145 | |
| 146 /** | |
| 147 * Check the directionality of the page. | |
| 148 * @return {boolean} True if Chrome is running an RTL UI. | |
| 149 */ | |
| 150 function isRTL() { | |
| 151 return document.documentElement.dir == 'rtl'; | |
| 152 } | |
| 153 | |
| 154 /** | |
| 155 * Simple common assertion API | |
| 156 * @param {*} condition The condition to test. Note that this may be used to | |
| 157 * test whether a value is defined or not, and we don't want to force a | |
| 158 * cast to Boolean. | |
| 159 * @param {string=} opt_message A message to use in any error. | |
| 160 */ | |
| 161 function assert(condition, opt_message) { | |
| 162 'use strict'; | |
| 163 if (!condition) { | |
| 164 var msg = 'Assertion failed'; | |
| 165 if (opt_message) | |
| 166 msg = msg + ': ' + opt_message; | |
| 167 throw new Error(msg); | |
| 168 } | |
| 169 } | |
| 170 | |
| 171 /** | |
| 172 * Get an element that's known to exist by its ID. We use this instead of just | |
| 173 * calling getElementById and not checking the result because this lets us | |
| 174 * satisfy the JSCompiler type system. | |
| 175 * @param {string} id The identifier name. | |
| 176 * @return {!Element} the Element. | |
| 177 */ | |
| 178 function getRequiredElement(id) { | |
| 179 var element = $(id); | |
| 180 assert(element, 'Missing required element: ' + id); | |
| 181 return element; | |
| 182 } | |
| 183 | |
| 184 // Handle click on a link. If the link points to a chrome: or file: url, then | |
| 185 // call into the browser to do the navigation. | |
| 186 document.addEventListener('click', function(e) { | |
| 187 // Allow preventDefault to work. | |
| 188 if (!e.returnValue) | |
| 189 return; | |
| 190 | |
| 191 var el = e.target; | |
| 192 if (el.nodeType == Node.ELEMENT_NODE && | |
| 193 el.webkitMatchesSelector('A, A *')) { | |
| 194 while (el.tagName != 'A') { | |
| 195 el = el.parentElement; | |
| 196 } | |
| 197 | |
| 198 if ((el.protocol == 'file:' || el.protocol == 'about:') && | |
| 199 (e.button == 0 || e.button == 1)) { | |
| 200 chrome.send('navigateToUrl', [ | |
| 201 el.href, | |
| 202 el.target, | |
| 203 e.button, | |
| 204 e.altKey, | |
| 205 e.ctrlKey, | |
| 206 e.metaKey, | |
| 207 e.shiftKey | |
| 208 ]); | |
| 209 e.preventDefault(); | |
| 210 } | |
| 211 } | |
| 212 }); | |
| 213 | |
| 214 /** | |
| 215 * Creates a new URL which is the old URL with a GET param of key=value. | |
| 216 * @param {string} url The base URL. There is not sanity checking on the URL so | |
| 217 * it must be passed in a proper format. | |
| 218 * @param {string} key The key of the param. | |
| 219 * @param {string} value The value of the param. | |
| 220 * @return {string} The new URL. | |
| 221 */ | |
| 222 function appendParam(url, key, value) { | |
| 223 var param = encodeURIComponent(key) + '=' + encodeURIComponent(value); | |
| 224 | |
| 225 if (url.indexOf('?') == -1) | |
| 226 return url + '?' + param; | |
| 227 return url + '&' + param; | |
| 228 } | |
| OLD | NEW |