Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(361)

Side by Side Diff: netlog_viewer/ui_webui_resources_js_util.js

Issue 2162963002: [polymer] Merge of master into polymer10-migration (Closed) Base URL: git@github.com:catapult-project/catapult.git@polymer10-migration
Patch Set: Merge polymer10-migration int polymer10-merge Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « netlog_viewer/top_mid_bottom_view.js ('k') | netlog_viewer/util.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 // <include src="assert.js">
6
7 /**
8 * Alias for document.getElementById. Found elements must be HTMLElements.
9 * @param {string} id The ID of the element to find.
10 * @return {HTMLElement} The found element or null if not found.
11 */
12 function $(id) {
13 var el = document.getElementById(id);
14 return el ? assertInstanceof(el, HTMLElement) : null;
15 }
16
17 // TODO(devlin): This should return SVGElement, but closure compiler is missing
18 // those externs.
19 /**
20 * Alias for document.getElementById. Found elements must be SVGElements.
21 * @param {string} id The ID of the element to find.
22 * @return {Element} The found element or null if not found.
23 */
24 function getSVGElement(id) {
25 var el = document.getElementById(id);
26 return el ? assertInstanceof(el, Element) : null;
27 }
28
29 /**
30 * Add an accessible message to the page that will be announced to
31 * users who have spoken feedback on, but will be invisible to all
32 * other users. It's removed right away so it doesn't clutter the DOM.
33 * @param {string} msg The text to be pronounced.
34 */
35 function announceAccessibleMessage(msg) {
36 var element = document.createElement('div');
37 element.setAttribute('aria-live', 'polite');
38 element.style.position = 'relative';
39 element.style.left = '-9999px';
40 element.style.height = '0px';
41 element.innerText = msg;
42 document.body.appendChild(element);
43 window.setTimeout(function() {
44 document.body.removeChild(element);
45 }, 0);
46 }
47
48 /**
49 * Generates a CSS url string.
50 * @param {string} s The URL to generate the CSS url for.
51 * @return {string} The CSS url string.
52 */
53 function url(s) {
54 // http://www.w3.org/TR/css3-values/#uris
55 // Parentheses, commas, whitespace characters, single quotes (') and double
56 // quotes (") appearing in a URI must be escaped with a backslash
57 var s2 = s.replace(/(\(|\)|\,|\s|\'|\"|\\)/g, '\\$1');
58 // WebKit has a bug when it comes to URLs that end with \
59 // https://bugs.webkit.org/show_bug.cgi?id=28885
60 if (/\\\\$/.test(s2)) {
61 // Add a space to work around the WebKit bug.
62 s2 += ' ';
63 }
64 return 'url("' + s2 + '")';
65 }
66
67 /**
68 * Parses query parameters from Location.
69 * @param {Location} location The URL to generate the CSS url for.
70 * @return {Object} Dictionary containing name value pairs for URL
71 */
72 function parseQueryParams(location) {
73 var params = {};
74 var query = unescape(location.search.substring(1));
75 var vars = query.split('&');
76 for (var i = 0; i < vars.length; i++) {
77 var pair = vars[i].split('=');
78 params[pair[0]] = pair[1];
79 }
80 return params;
81 }
82
83 /**
84 * Creates a new URL by appending or replacing the given query key and value.
85 * Not supporting URL with username and password.
86 * @param {Location} location The original URL.
87 * @param {string} key The query parameter name.
88 * @param {string} value The query parameter value.
89 * @return {string} The constructed new URL.
90 */
91 function setQueryParam(location, key, value) {
92 var query = parseQueryParams(location);
93 query[encodeURIComponent(key)] = encodeURIComponent(value);
94
95 var newQuery = '';
96 for (var q in query) {
97 newQuery += (newQuery ? '&' : '?') + q + '=' + query[q];
98 }
99
100 return location.origin + location.pathname + newQuery + location.hash;
101 }
102
103 /**
104 * @param {Node} el A node to search for ancestors with |className|.
105 * @param {string} className A class to search for.
106 * @return {Element} A node with class of |className| or null if none is found.
107 */
108 function findAncestorByClass(el, className) {
109 return /** @type {Element} */(findAncestor(el, function(el) {
110 return el.classList && el.classList.contains(className);
111 }));
112 }
113
114 /**
115 * Return the first ancestor for which the {@code predicate} returns true.
116 * @param {Node} node The node to check.
117 * @param {function(Node):boolean} predicate The function that tests the
118 * nodes.
119 * @return {Node} The found ancestor or null if not found.
120 */
121 function findAncestor(node, predicate) {
122 var last = false;
123 while (node != null && !(last = predicate(node))) {
124 node = node.parentNode;
125 }
126 return last ? node : null;
127 }
128
129 function swapDomNodes(a, b) {
130 var afterA = a.nextSibling;
131 if (afterA == b) {
132 swapDomNodes(b, a);
133 return;
134 }
135 var aParent = a.parentNode;
136 b.parentNode.replaceChild(a, b);
137 aParent.insertBefore(b, afterA);
138 }
139
140 /**
141 * Disables text selection and dragging, with optional whitelist callbacks.
142 * @param {function(Event):boolean=} opt_allowSelectStart Unless this function
143 * is defined and returns true, the onselectionstart event will be
144 * surpressed.
145 * @param {function(Event):boolean=} opt_allowDragStart Unless this function
146 * is defined and returns true, the ondragstart event will be surpressed.
147 */
148 function disableTextSelectAndDrag(opt_allowSelectStart, opt_allowDragStart) {
149 // Disable text selection.
150 document.onselectstart = function(e) {
151 if (!(opt_allowSelectStart && opt_allowSelectStart.call(this, e)))
152 e.preventDefault();
153 };
154
155 // Disable dragging.
156 document.ondragstart = function(e) {
157 if (!(opt_allowDragStart && opt_allowDragStart.call(this, e)))
158 e.preventDefault();
159 };
160 }
161
162 /**
163 * TODO(dbeam): DO NOT USE. THIS IS DEPRECATED. Use an action-link instead.
164 * Call this to stop clicks on <a href="#"> links from scrolling to the top of
165 * the page (and possibly showing a # in the link).
166 */
167 function preventDefaultOnPoundLinkClicks() {
168 document.addEventListener('click', function(e) {
169 var anchor = findAncestor(/** @type {Node} */(e.target), function(el) {
170 return el.tagName == 'A';
171 });
172 // Use getAttribute() to prevent URL normalization.
173 if (anchor && anchor.getAttribute('href') == '#')
174 e.preventDefault();
175 });
176 }
177
178 /**
179 * Check the directionality of the page.
180 * @return {boolean} True if Chrome is running an RTL UI.
181 */
182 function isRTL() {
183 return document.documentElement.dir == 'rtl';
184 }
185
186 /**
187 * Get an element that's known to exist by its ID. We use this instead of just
188 * calling getElementById and not checking the result because this lets us
189 * satisfy the JSCompiler type system.
190 * @param {string} id The identifier name.
191 * @return {!HTMLElement} the Element.
192 */
193 function getRequiredElement(id) {
194 return assertInstanceof($(id), HTMLElement,
195 'Missing required element: ' + id);
196 }
197
198 /**
199 * Query an element that's known to exist by a selector. We use this instead of
200 * just calling querySelector and not checking the result because this lets us
201 * satisfy the JSCompiler type system.
202 * @param {string} selectors CSS selectors to query the element.
203 * @param {(!Document|!DocumentFragment|!Element)=} opt_context An optional
204 * context object for querySelector.
205 * @return {!HTMLElement} the Element.
206 */
207 function queryRequiredElement(selectors, opt_context) {
208 var element = (opt_context || document).querySelector(selectors);
209 return assertInstanceof(element, HTMLElement,
210 'Missing required element: ' + selectors);
211 }
212
213 // Handle click on a link. If the link points to a chrome: or file: url, then
214 // call into the browser to do the navigation.
215 document.addEventListener('click', function(e) {
216 if (e.defaultPrevented)
217 return;
218
219 var el = e.target;
220 if (el.nodeType == Node.ELEMENT_NODE &&
221 el.webkitMatchesSelector('A, A *')) {
222 while (el.tagName != 'A') {
223 el = el.parentElement;
224 }
225
226 if ((el.protocol == 'file:' || el.protocol == 'about:') &&
227 (e.button == 0 || e.button == 1)) {
228 chrome.send('navigateToUrl', [
229 el.href,
230 el.target,
231 e.button,
232 e.altKey,
233 e.ctrlKey,
234 e.metaKey,
235 e.shiftKey
236 ]);
237 e.preventDefault();
238 }
239 }
240 });
241
242 /**
243 * Creates a new URL which is the old URL with a GET param of key=value.
244 * @param {string} url The base URL. There is not sanity checking on the URL so
245 * it must be passed in a proper format.
246 * @param {string} key The key of the param.
247 * @param {string} value The value of the param.
248 * @return {string} The new URL.
249 */
250 function appendParam(url, key, value) {
251 var param = encodeURIComponent(key) + '=' + encodeURIComponent(value);
252
253 if (url.indexOf('?') == -1)
254 return url + '?' + param;
255 return url + '&' + param;
256 }
257
258 /**
259 * Creates an element of a specified type with a specified class name.
260 * @param {string} type The node type.
261 * @param {string} className The class name to use.
262 * @return {Element} The created element.
263 */
264 function createElementWithClassName(type, className) {
265 var elm = document.createElement(type);
266 elm.className = className;
267 return elm;
268 }
269
270 /**
271 * webkitTransitionEnd does not always fire (e.g. when animation is aborted
272 * or when no paint happens during the animation). This function sets up
273 * a timer and emulate the event if it is not fired when the timer expires.
274 * @param {!HTMLElement} el The element to watch for webkitTransitionEnd.
275 * @param {number=} opt_timeOut The maximum wait time in milliseconds for the
276 * webkitTransitionEnd to happen. If not specified, it is fetched from |el|
277 * using the transitionDuration style value.
278 */
279 function ensureTransitionEndEvent(el, opt_timeOut) {
280 if (opt_timeOut === undefined) {
281 var style = getComputedStyle(el);
282 opt_timeOut = parseFloat(style.transitionDuration) * 1000;
283
284 // Give an additional 50ms buffer for the animation to complete.
285 opt_timeOut += 50;
286 }
287
288 var fired = false;
289 el.addEventListener('webkitTransitionEnd', function f(e) {
290 el.removeEventListener('webkitTransitionEnd', f);
291 fired = true;
292 });
293 window.setTimeout(function() {
294 if (!fired)
295 cr.dispatchSimpleEvent(el, 'webkitTransitionEnd', true);
296 }, opt_timeOut);
297 }
298
299 /**
300 * Alias for document.scrollTop getter.
301 * @param {!HTMLDocument} doc The document node where information will be
302 * queried from.
303 * @return {number} The Y document scroll offset.
304 */
305 function scrollTopForDocument(doc) {
306 return doc.documentElement.scrollTop || doc.body.scrollTop;
307 }
308
309 /**
310 * Alias for document.scrollTop setter.
311 * @param {!HTMLDocument} doc The document node where information will be
312 * queried from.
313 * @param {number} value The target Y scroll offset.
314 */
315 function setScrollTopForDocument(doc, value) {
316 doc.documentElement.scrollTop = doc.body.scrollTop = value;
317 }
318
319 /**
320 * Alias for document.scrollLeft getter.
321 * @param {!HTMLDocument} doc The document node where information will be
322 * queried from.
323 * @return {number} The X document scroll offset.
324 */
325 function scrollLeftForDocument(doc) {
326 return doc.documentElement.scrollLeft || doc.body.scrollLeft;
327 }
328
329 /**
330 * Alias for document.scrollLeft setter.
331 * @param {!HTMLDocument} doc The document node where information will be
332 * queried from.
333 * @param {number} value The target X scroll offset.
334 */
335 function setScrollLeftForDocument(doc, value) {
336 doc.documentElement.scrollLeft = doc.body.scrollLeft = value;
337 }
338
339 /**
340 * Replaces '&', '<', '>', '"', and ''' characters with their HTML encoding.
341 * @param {string} original The original string.
342 * @return {string} The string with all the characters mentioned above replaced.
343 */
344 function HTMLEscape(original) {
345 return original.replace(/&/g, '&amp;')
346 .replace(/</g, '&lt;')
347 .replace(/>/g, '&gt;')
348 .replace(/"/g, '&quot;')
349 .replace(/'/g, '&#39;');
350 }
351
352 /**
353 * Shortens the provided string (if necessary) to a string of length at most
354 * |maxLength|.
355 * @param {string} original The original string.
356 * @param {number} maxLength The maximum length allowed for the string.
357 * @return {string} The original string if its length does not exceed
358 * |maxLength|. Otherwise the first |maxLength| - 1 characters with '...'
359 * appended.
360 */
361 function elide(original, maxLength) {
362 if (original.length <= maxLength)
363 return original;
364 return original.substring(0, maxLength - 1) + '\u2026';
365 }
366
367 /**
368 * Quote a string so it can be used in a regular expression.
369 * @param {string} str The source string.
370 * @return {string} The escaped string.
371 */
372 function quoteString(str) {
373 return str.replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, '\\$1');
374 }
OLDNEW
« no previous file with comments | « netlog_viewer/top_mid_bottom_view.js ('k') | netlog_viewer/util.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698