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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/platform/DOMExtension.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2007 Apple Inc. All rights reserved. 2 * Copyright (C) 2007 Apple Inc. All rights reserved.
3 * Copyright (C) 2012 Google Inc. All rights reserved. 3 * Copyright (C) 2012 Google Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 8 *
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 11 matching lines...) Expand all
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * 28 *
29 * Contains diff method based on Javascript Diff Algorithm By John Resig 29 * Contains diff method based on Javascript Diff Algorithm By John Resig
30 * http://ejohn.org/files/jsdiff.js (released under the MIT license). 30 * http://ejohn.org/files/jsdiff.js (released under the MIT license).
31 */ 31 */
32
33 /** 32 /**
34 * @param {number} offset 33 * @param {number} offset
35 * @param {string} stopCharacters 34 * @param {string} stopCharacters
36 * @param {!Node} stayWithinNode 35 * @param {!Node} stayWithinNode
37 * @param {string=} direction 36 * @param {string=} direction
38 * @return {!Range} 37 * @return {!Range}
39 */ 38 */
40 Node.prototype.rangeOfWord = function(offset, stopCharacters, stayWithinNode, di rection) 39 Node.prototype.rangeOfWord = function(offset, stopCharacters, stayWithinNode, di rection) {
41 { 40 var startNode;
42 var startNode; 41 var startOffset = 0;
43 var startOffset = 0; 42 var endNode;
44 var endNode; 43 var endOffset = 0;
45 var endOffset = 0;
46 44
47 if (!stayWithinNode) 45 if (!stayWithinNode)
48 stayWithinNode = this; 46 stayWithinNode = this;
49 47
50 if (!direction || direction === "backward" || direction === "both") { 48 if (!direction || direction === 'backward' || direction === 'both') {
51 var node = this; 49 var node = this;
52 while (node) { 50 while (node) {
53 if (node === stayWithinNode) { 51 if (node === stayWithinNode) {
54 if (!startNode) 52 if (!startNode)
55 startNode = stayWithinNode; 53 startNode = stayWithinNode;
56 break; 54 break;
57 } 55 }
58 56
59 if (node.nodeType === Node.TEXT_NODE) { 57 if (node.nodeType === Node.TEXT_NODE) {
60 var start = (node === this ? (offset - 1) : (node.nodeValue.leng th - 1)); 58 var start = (node === this ? (offset - 1) : (node.nodeValue.length - 1)) ;
61 for (var i = start; i >= 0; --i) { 59 for (var i = start; i >= 0; --i) {
62 if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) { 60 if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) {
63 startNode = node; 61 startNode = node;
64 startOffset = i + 1; 62 startOffset = i + 1;
65 break; 63 break;
66 } 64 }
67 } 65 }
68 } 66 }
69 67
70 if (startNode) 68 if (startNode)
71 break; 69 break;
72 70
73 node = node.traversePreviousNode(stayWithinNode); 71 node = node.traversePreviousNode(stayWithinNode);
74 }
75
76 if (!startNode) {
77 startNode = stayWithinNode;
78 startOffset = 0;
79 }
80 } else {
81 startNode = this;
82 startOffset = offset;
83 } 72 }
84 73
85 if (!direction || direction === "forward" || direction === "both") { 74 if (!startNode) {
86 node = this; 75 startNode = stayWithinNode;
87 while (node) { 76 startOffset = 0;
88 if (node === stayWithinNode) { 77 }
89 if (!endNode) 78 } else {
90 endNode = stayWithinNode; 79 startNode = this;
91 break; 80 startOffset = offset;
92 } 81 }
93 82
94 if (node.nodeType === Node.TEXT_NODE) { 83 if (!direction || direction === 'forward' || direction === 'both') {
95 var start = (node === this ? offset : 0); 84 node = this;
96 for (var i = start; i < node.nodeValue.length; ++i) { 85 while (node) {
97 if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) { 86 if (node === stayWithinNode) {
98 endNode = node; 87 if (!endNode)
99 endOffset = i; 88 endNode = stayWithinNode;
100 break; 89 break;
101 } 90 }
102 }
103 }
104 91
105 if (endNode) 92 if (node.nodeType === Node.TEXT_NODE) {
106 break; 93 var start = (node === this ? offset : 0);
94 for (var i = start; i < node.nodeValue.length; ++i) {
95 if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) {
96 endNode = node;
97 endOffset = i;
98 break;
99 }
100 }
101 }
107 102
108 node = node.traverseNextNode(stayWithinNode); 103 if (endNode)
109 } 104 break;
110 105
111 if (!endNode) { 106 node = node.traverseNextNode(stayWithinNode);
112 endNode = stayWithinNode;
113 endOffset = stayWithinNode.nodeType === Node.TEXT_NODE ? stayWithinN ode.nodeValue.length : stayWithinNode.childNodes.length;
114 }
115 } else {
116 endNode = this;
117 endOffset = offset;
118 } 107 }
119 108
120 var result = this.ownerDocument.createRange(); 109 if (!endNode) {
121 result.setStart(startNode, startOffset); 110 endNode = stayWithinNode;
122 result.setEnd(endNode, endOffset); 111 endOffset = stayWithinNode.nodeType === Node.TEXT_NODE ? stayWithinNode.no deValue.length :
112 stayWithinNode.ch ildNodes.length;
113 }
114 } else {
115 endNode = this;
116 endOffset = offset;
117 }
123 118
124 return result; 119 var result = this.ownerDocument.createRange();
120 result.setStart(startNode, startOffset);
121 result.setEnd(endNode, endOffset);
122
123 return result;
125 }; 124 };
126 125
127 /** 126 /**
128 * @param {!Node=} stayWithin 127 * @param {!Node=} stayWithin
129 * @return {?Node} 128 * @return {?Node}
130 */ 129 */
131 Node.prototype.traverseNextTextNode = function(stayWithin) 130 Node.prototype.traverseNextTextNode = function(stayWithin) {
132 { 131 var node = this.traverseNextNode(stayWithin);
133 var node = this.traverseNextNode(stayWithin); 132 if (!node)
134 if (!node) 133 return null;
135 return null; 134 var nonTextTags = {'STYLE': 1, 'SCRIPT': 1};
136 var nonTextTags = { "STYLE": 1, "SCRIPT": 1 }; 135 while (node && (node.nodeType !== Node.TEXT_NODE || nonTextTags[node.parentEle ment.nodeName]))
137 while (node && (node.nodeType !== Node.TEXT_NODE || nonTextTags[node.parentE lement.nodeName])) 136 node = node.traverseNextNode(stayWithin);
138 node = node.traverseNextNode(stayWithin);
139 137
140 return node; 138 return node;
141 }; 139 };
142 140
143 /** 141 /**
144 * @param {number|undefined} x 142 * @param {number|undefined} x
145 * @param {number|undefined} y 143 * @param {number|undefined} y
146 * @param {!Element=} relativeTo 144 * @param {!Element=} relativeTo
147 */ 145 */
148 Element.prototype.positionAt = function(x, y, relativeTo) 146 Element.prototype.positionAt = function(x, y, relativeTo) {
149 { 147 var shift = {x: 0, y: 0};
150 var shift = {x: 0, y: 0}; 148 if (relativeTo)
151 if (relativeTo) 149 shift = relativeTo.boxInWindow(this.ownerDocument.defaultView);
152 shift = relativeTo.boxInWindow(this.ownerDocument.defaultView);
153 150
154 if (typeof x === "number") 151 if (typeof x === 'number')
155 this.style.setProperty("left", (shift.x + x) + "px"); 152 this.style.setProperty('left', (shift.x + x) + 'px');
156 else 153 else
157 this.style.removeProperty("left"); 154 this.style.removeProperty('left');
158 155
159 if (typeof y === "number") 156 if (typeof y === 'number')
160 this.style.setProperty("top", (shift.y + y) + "px"); 157 this.style.setProperty('top', (shift.y + y) + 'px');
161 else 158 else
162 this.style.removeProperty("top"); 159 this.style.removeProperty('top');
163 160
164 if (typeof x === "number" || typeof y === "number") 161 if (typeof x === 'number' || typeof y === 'number')
165 this.style.setProperty("position", "absolute"); 162 this.style.setProperty('position', 'absolute');
166 else 163 else
167 this.style.removeProperty("position"); 164 this.style.removeProperty('position');
168 }; 165 };
169 166
170 /** 167 /**
171 * @return {boolean} 168 * @return {boolean}
172 */ 169 */
173 Element.prototype.isScrolledToBottom = function() 170 Element.prototype.isScrolledToBottom = function() {
174 { 171 // This code works only for 0-width border.
175 // This code works only for 0-width border. 172 // The scrollTop, clientHeight and scrollHeight are computed in double values internally.
176 // The scrollTop, clientHeight and scrollHeight are computed in double value s internally. 173 // However, they are exposed to javascript differently, each being either roun ded (via
177 // However, they are exposed to javascript differently, each being either ro unded (via 174 // round, ceil or floor functions) or left intouch.
178 // round, ceil or floor functions) or left intouch. 175 // This adds up a total error up to 2.
179 // This adds up a total error up to 2. 176 return Math.abs(this.scrollTop + this.clientHeight - this.scrollHeight) <= 2;
180 return Math.abs(this.scrollTop + this.clientHeight - this.scrollHeight) <= 2 ;
181 }; 177 };
182 178
183 /** 179 /**
184 * @param {!Array.<string>} nameArray 180 * @param {!Array.<string>} nameArray
185 * @return {?Node} 181 * @return {?Node}
186 */ 182 */
187 Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = function(nameArray) 183 Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = function(nameArray) {
188 { 184 for (var node = this; node && node !== this.ownerDocument; node = node.parentN odeOrShadowHost()) {
189 for (var node = this; node && node !== this.ownerDocument; node = node.paren tNodeOrShadowHost()) { 185 for (var i = 0; i < nameArray.length; ++i) {
190 for (var i = 0; i < nameArray.length; ++i) { 186 if (node.nodeName.toLowerCase() === nameArray[i].toLowerCase())
191 if (node.nodeName.toLowerCase() === nameArray[i].toLowerCase()) 187 return node;
192 return node;
193 }
194 } 188 }
195 return null; 189 }
190 return null;
196 }; 191 };
197 192
198 /** 193 /**
199 * @param {string} nodeName 194 * @param {string} nodeName
200 * @return {?Node} 195 * @return {?Node}
201 */ 196 */
202 Node.prototype.enclosingNodeOrSelfWithNodeName = function(nodeName) 197 Node.prototype.enclosingNodeOrSelfWithNodeName = function(nodeName) {
203 { 198 return this.enclosingNodeOrSelfWithNodeNameInArray([nodeName]);
204 return this.enclosingNodeOrSelfWithNodeNameInArray([nodeName]);
205 }; 199 };
206 200
207 /** 201 /**
208 * @param {string} className 202 * @param {string} className
209 * @param {!Element=} stayWithin 203 * @param {!Element=} stayWithin
210 * @return {?Element} 204 * @return {?Element}
211 */ 205 */
212 Node.prototype.enclosingNodeOrSelfWithClass = function(className, stayWithin) 206 Node.prototype.enclosingNodeOrSelfWithClass = function(className, stayWithin) {
213 { 207 return this.enclosingNodeOrSelfWithClassList([className], stayWithin);
214 return this.enclosingNodeOrSelfWithClassList([className], stayWithin);
215 }; 208 };
216 209
217 /** 210 /**
218 * @param {!Array.<string>} classNames 211 * @param {!Array.<string>} classNames
219 * @param {!Element=} stayWithin 212 * @param {!Element=} stayWithin
220 * @return {?Element} 213 * @return {?Element}
221 */ 214 */
222 Node.prototype.enclosingNodeOrSelfWithClassList = function(classNames, stayWithi n) 215 Node.prototype.enclosingNodeOrSelfWithClassList = function(classNames, stayWithi n) {
223 { 216 for (var node = this; node && node !== stayWithin && node !== this.ownerDocume nt;
224 for (var node = this; node && node !== stayWithin && node !== this.ownerDocu ment; node = node.parentNodeOrShadowHost()) { 217 node = node.parentNodeOrShadowHost()) {
225 if (node.nodeType === Node.ELEMENT_NODE) { 218 if (node.nodeType === Node.ELEMENT_NODE) {
226 var containsAll = true; 219 var containsAll = true;
227 for (var i = 0; i < classNames.length && containsAll; ++i) { 220 for (var i = 0; i < classNames.length && containsAll; ++i) {
228 if (!node.classList.contains(classNames[i])) 221 if (!node.classList.contains(classNames[i]))
229 containsAll = false; 222 containsAll = false;
230 } 223 }
231 if (containsAll) 224 if (containsAll)
232 return /** @type {!Element} */ (node); 225 return /** @type {!Element} */ (node);
233 }
234 } 226 }
235 return null; 227 }
228 return null;
236 }; 229 };
237 230
238 /** 231 /**
239 * @return {?Element} 232 * @return {?Element}
240 */ 233 */
241 Node.prototype.parentElementOrShadowHost = function() 234 Node.prototype.parentElementOrShadowHost = function() {
242 { 235 var node = this.parentNode;
243 var node = this.parentNode; 236 if (!node)
244 if (!node)
245 return null;
246 if (node.nodeType === Node.ELEMENT_NODE)
247 return /** @type {!Element} */ (node);
248 if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE)
249 return /** @type {!Element} */ (node.host);
250 return null; 237 return null;
238 if (node.nodeType === Node.ELEMENT_NODE)
239 return /** @type {!Element} */ (node);
240 if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE)
241 return /** @type {!Element} */ (node.host);
242 return null;
251 }; 243 };
252 244
253 /** 245 /**
254 * @return {?Node} 246 * @return {?Node}
255 */ 247 */
256 Node.prototype.parentNodeOrShadowHost = function() 248 Node.prototype.parentNodeOrShadowHost = function() {
257 { 249 return this.parentNode || this.host || null;
258 return this.parentNode || this.host || null;
259 }; 250 };
260 251
261 /** 252 /**
262 * @return {?Selection} 253 * @return {?Selection}
263 */ 254 */
264 Node.prototype.getComponentSelection = function() 255 Node.prototype.getComponentSelection = function() {
265 { 256 var parent = this.parentNode;
266 var parent = this.parentNode; 257 while (parent && parent.nodeType !== Node.DOCUMENT_FRAGMENT_NODE)
267 while (parent && parent.nodeType !== Node.DOCUMENT_FRAGMENT_NODE) 258 parent = parent.parentNode;
268 parent = parent.parentNode; 259 return parent instanceof ShadowRoot ? parent.getSelection() : this.window().ge tSelection();
269 return parent instanceof ShadowRoot ? parent.getSelection() : this.window(). getSelection();
270 };
271
272
273 /**
274 * @return {boolean}
275 */
276 Node.prototype.isComponentSelectionCollapsed = function()
277 {
278 // FIXME: crbug.com/447523, use selection.isCollapsed when it is fixed for s hadow dom.
279 var selection = this.getComponentSelection();
280 var range = selection && selection.rangeCount ? selection.getRangeAt(0) : nu ll;
281 return range ? range.collapsed : true;
282 }; 260 };
283 261
284 /** 262 /**
285 * @return {boolean} 263 * @return {boolean}
286 */ 264 */
287 Node.prototype.hasSelection = function() 265 Node.prototype.isComponentSelectionCollapsed = function() {
288 { 266 // FIXME: crbug.com/447523, use selection.isCollapsed when it is fixed for sha dow dom.
289 if (this.isComponentSelectionCollapsed()) 267 var selection = this.getComponentSelection();
290 return false; 268 var range = selection && selection.rangeCount ? selection.getRangeAt(0) : null ;
291 return this.getComponentSelection().containsNode(this, true); 269 return range ? range.collapsed : true;
270 };
271
272 /**
273 * @return {boolean}
274 */
275 Node.prototype.hasSelection = function() {
276 if (this.isComponentSelectionCollapsed())
277 return false;
278 return this.getComponentSelection().containsNode(this, true);
292 }; 279 };
293 280
294 /** 281 /**
295 * @return {!Selection} 282 * @return {!Selection}
296 */ 283 */
297 Node.prototype.getDeepSelection = function() 284 Node.prototype.getDeepSelection = function() {
298 { 285 var activeElement = this.ownerDocument.activeElement;
299 var activeElement = this.ownerDocument.activeElement; 286 var shadowRoot = null;
300 var shadowRoot = null; 287 while (activeElement && activeElement.shadowRoot) {
301 while (activeElement && activeElement.shadowRoot) { 288 shadowRoot = activeElement.shadowRoot;
302 shadowRoot = activeElement.shadowRoot; 289 activeElement = shadowRoot.activeElement;
303 activeElement = shadowRoot.activeElement; 290 }
304 }
305 291
306 return shadowRoot ? shadowRoot.getSelection() : this.window().getSelection() ; 292 return shadowRoot ? shadowRoot.getSelection() : this.window().getSelection();
307 }; 293 };
308 294
309 /** 295 /**
310 * @return {!Window} 296 * @return {!Window}
311 */ 297 */
312 Node.prototype.window = function() 298 Node.prototype.window = function() {
313 { 299 return this.ownerDocument.defaultView;
314 return this.ownerDocument.defaultView;
315 }; 300 };
316 301
317 Element.prototype.removeChildren = function() 302 Element.prototype.removeChildren = function() {
318 { 303 if (this.firstChild)
319 if (this.firstChild) 304 this.textContent = '';
320 this.textContent = "";
321 }; 305 };
322 306
323 /** 307 /**
324 * @param {string} tagName 308 * @param {string} tagName
325 * @param {string=} customElementType 309 * @param {string=} customElementType
326 * @return {!Element} 310 * @return {!Element}
327 * @suppressGlobalPropertiesCheck 311 * @suppressGlobalPropertiesCheck
328 */ 312 */
329 function createElement(tagName, customElementType) 313 function createElement(tagName, customElementType) {
330 { 314 return document.createElement(tagName, customElementType || '');
331 return document.createElement(tagName, customElementType || "");
332 } 315 }
333 316
334 /** 317 /**
335 * @param {number|string} data 318 * @param {number|string} data
336 * @return {!Text} 319 * @return {!Text}
337 * @suppressGlobalPropertiesCheck 320 * @suppressGlobalPropertiesCheck
338 */ 321 */
339 function createTextNode(data) 322 function createTextNode(data) {
340 { 323 return document.createTextNode(data);
341 return document.createTextNode(data);
342 } 324 }
343 325
344 /** 326 /**
345 * @param {string} elementName 327 * @param {string} elementName
346 * @param {string=} className 328 * @param {string=} className
347 * @param {string=} customElementType 329 * @param {string=} customElementType
348 * @return {!Element} 330 * @return {!Element}
349 */ 331 */
350 Document.prototype.createElementWithClass = function(elementName, className, cus tomElementType) 332 Document.prototype.createElementWithClass = function(elementName, className, cus tomElementType) {
351 { 333 var element = this.createElement(elementName, customElementType || '');
352 var element = this.createElement(elementName, customElementType || ""); 334 if (className)
353 if (className) 335 element.className = className;
354 element.className = className; 336 return element;
355 return element;
356 }; 337 };
357 338
358 /** 339 /**
359 * @param {string} elementName 340 * @param {string} elementName
360 * @param {string=} className 341 * @param {string=} className
361 * @param {string=} customElementType 342 * @param {string=} customElementType
362 * @return {!Element} 343 * @return {!Element}
363 * @suppressGlobalPropertiesCheck 344 * @suppressGlobalPropertiesCheck
364 */ 345 */
365 function createElementWithClass(elementName, className, customElementType) 346 function createElementWithClass(elementName, className, customElementType) {
366 { 347 return document.createElementWithClass(elementName, className, customElementTy pe);
367 return document.createElementWithClass(elementName, className, customElement Type);
368 } 348 }
369 349
370 /** 350 /**
371 * @param {string} childType 351 * @param {string} childType
372 * @param {string=} className 352 * @param {string=} className
373 * @return {!Element} 353 * @return {!Element}
374 */ 354 */
375 Document.prototype.createSVGElement = function(childType, className) 355 Document.prototype.createSVGElement = function(childType, className) {
376 { 356 var element = this.createElementNS('http://www.w3.org/2000/svg', childType);
377 var element = this.createElementNS("http://www.w3.org/2000/svg", childType); 357 if (className)
378 if (className) 358 element.setAttribute('class', className);
379 element.setAttribute("class", className); 359 return element;
380 return element;
381 }; 360 };
382 361
383 /** 362 /**
384 * @param {string} childType 363 * @param {string} childType
385 * @param {string=} className 364 * @param {string=} className
386 * @return {!Element} 365 * @return {!Element}
387 * @suppressGlobalPropertiesCheck 366 * @suppressGlobalPropertiesCheck
388 */ 367 */
389 function createSVGElement(childType, className) 368 function createSVGElement(childType, className) {
390 { 369 return document.createSVGElement(childType, className);
391 return document.createSVGElement(childType, className);
392 } 370 }
393 371
394 /** 372 /**
395 * @return {!DocumentFragment} 373 * @return {!DocumentFragment}
396 * @suppressGlobalPropertiesCheck 374 * @suppressGlobalPropertiesCheck
397 */ 375 */
398 function createDocumentFragment() 376 function createDocumentFragment() {
399 { 377 return document.createDocumentFragment();
400 return document.createDocumentFragment();
401 } 378 }
402 379
403 /** 380 /**
404 * @param {string} elementName 381 * @param {string} elementName
405 * @param {string=} className 382 * @param {string=} className
406 * @param {string=} customElementType 383 * @param {string=} customElementType
407 * @return {!Element} 384 * @return {!Element}
408 */ 385 */
409 Element.prototype.createChild = function(elementName, className, customElementTy pe) 386 Element.prototype.createChild = function(elementName, className, customElementTy pe) {
410 { 387 var element = this.ownerDocument.createElementWithClass(elementName, className , customElementType);
411 var element = this.ownerDocument.createElementWithClass(elementName, classNa me, customElementType); 388 this.appendChild(element);
412 this.appendChild(element); 389 return element;
413 return element;
414 }; 390 };
415 391
416 DocumentFragment.prototype.createChild = Element.prototype.createChild; 392 DocumentFragment.prototype.createChild = Element.prototype.createChild;
417 393
418 /** 394 /**
419 * @param {string} text 395 * @param {string} text
420 * @return {!Text} 396 * @return {!Text}
421 */ 397 */
422 Element.prototype.createTextChild = function(text) 398 Element.prototype.createTextChild = function(text) {
423 { 399 var element = this.ownerDocument.createTextNode(text);
424 var element = this.ownerDocument.createTextNode(text); 400 this.appendChild(element);
425 this.appendChild(element); 401 return element;
426 return element;
427 }; 402 };
428 403
429 DocumentFragment.prototype.createTextChild = Element.prototype.createTextChild; 404 DocumentFragment.prototype.createTextChild = Element.prototype.createTextChild;
430 405
431 /** 406 /**
432 * @param {...string} var_args 407 * @param {...string} var_args
433 */ 408 */
434 Element.prototype.createTextChildren = function(var_args) 409 Element.prototype.createTextChildren = function(var_args) {
435 { 410 for (var i = 0, n = arguments.length; i < n; ++i)
436 for (var i = 0, n = arguments.length; i < n; ++i) 411 this.createTextChild(arguments[i]);
437 this.createTextChild(arguments[i]);
438 }; 412 };
439 413
440 DocumentFragment.prototype.createTextChildren = Element.prototype.createTextChil dren; 414 DocumentFragment.prototype.createTextChildren = Element.prototype.createTextChil dren;
441 415
442 /** 416 /**
443 * @return {number} 417 * @return {number}
444 */ 418 */
445 Element.prototype.totalOffsetLeft = function() 419 Element.prototype.totalOffsetLeft = function() {
446 { 420 return this.totalOffset().left;
447 return this.totalOffset().left;
448 }; 421 };
449 422
450 /** 423 /**
451 * @return {number} 424 * @return {number}
452 */ 425 */
453 Element.prototype.totalOffsetTop = function() 426 Element.prototype.totalOffsetTop = function() {
454 { 427 return this.totalOffset().top;
455 return this.totalOffset().top;
456 }; 428 };
457 429
458 /** 430 /**
459 * @return {!{left: number, top: number}} 431 * @return {!{left: number, top: number}}
460 */ 432 */
461 Element.prototype.totalOffset = function() 433 Element.prototype.totalOffset = function() {
462 { 434 var rect = this.getBoundingClientRect();
463 var rect = this.getBoundingClientRect(); 435 return {left: rect.left, top: rect.top};
464 return { left: rect.left, top: rect.top };
465 }; 436 };
466 437
467 /** 438 /**
468 * @param {string} childType 439 * @param {string} childType
469 * @param {string=} className 440 * @param {string=} className
470 * @return {!Element} 441 * @return {!Element}
471 */ 442 */
472 Element.prototype.createSVGChild = function(childType, className) 443 Element.prototype.createSVGChild = function(childType, className) {
473 { 444 var child = this.ownerDocument.createSVGElement(childType, className);
474 var child = this.ownerDocument.createSVGElement(childType, className); 445 this.appendChild(child);
475 this.appendChild(child); 446 return child;
476 return child;
477 }; 447 };
478 448
479 /** 449 /**
480 * @constructor 450 * @unrestricted
481 * @param {number=} x
482 * @param {number=} y
483 * @param {number=} width
484 * @param {number=} height
485 */ 451 */
486 function AnchorBox(x, y, width, height) 452 var AnchorBox = class {
487 { 453 /**
454 * @param {number=} x
455 * @param {number=} y
456 * @param {number=} width
457 * @param {number=} height
458 */
459 constructor(x, y, width, height) {
488 this.x = x || 0; 460 this.x = x || 0;
489 this.y = y || 0; 461 this.y = y || 0;
490 this.width = width || 0; 462 this.width = width || 0;
491 this.height = height || 0; 463 this.height = height || 0;
492 } 464 }
465 };
493 466
494 /** 467 /**
495 * @param {!AnchorBox} box 468 * @param {!AnchorBox} box
496 * @return {!AnchorBox} 469 * @return {!AnchorBox}
497 */ 470 */
498 AnchorBox.prototype.relativeTo = function(box) 471 AnchorBox.prototype.relativeTo = function(box) {
499 { 472 return new AnchorBox(this.x - box.x, this.y - box.y, this.width, this.height);
500 return new AnchorBox(
501 this.x - box.x, this.y - box.y, this.width, this.height);
502 }; 473 };
503 474
504 /** 475 /**
505 * @param {!Element} element 476 * @param {!Element} element
506 * @return {!AnchorBox} 477 * @return {!AnchorBox}
507 */ 478 */
508 AnchorBox.prototype.relativeToElement = function(element) 479 AnchorBox.prototype.relativeToElement = function(element) {
509 { 480 return this.relativeTo(element.boxInWindow(element.ownerDocument.defaultView)) ;
510 return this.relativeTo(element.boxInWindow(element.ownerDocument.defaultView ));
511 }; 481 };
512 482
513 /** 483 /**
514 * @param {?AnchorBox} anchorBox 484 * @param {?AnchorBox} anchorBox
515 * @return {boolean} 485 * @return {boolean}
516 */ 486 */
517 AnchorBox.prototype.equals = function(anchorBox) 487 AnchorBox.prototype.equals = function(anchorBox) {
518 { 488 return !!anchorBox && this.x === anchorBox.x && this.y === anchorBox.y && this .width === anchorBox.width &&
519 return !!anchorBox && this.x === anchorBox.x && this.y === anchorBox.y && th is.width === anchorBox.width && this.height === anchorBox.height; 489 this.height === anchorBox.height;
520 }; 490 };
521 491
522 /** 492 /**
523 * @param {!Window=} targetWindow 493 * @param {!Window=} targetWindow
524 * @return {!AnchorBox} 494 * @return {!AnchorBox}
525 */ 495 */
526 Element.prototype.boxInWindow = function(targetWindow) 496 Element.prototype.boxInWindow = function(targetWindow) {
527 { 497 targetWindow = targetWindow || this.ownerDocument.defaultView;
528 targetWindow = targetWindow || this.ownerDocument.defaultView;
529 498
530 var anchorBox = new AnchorBox(); 499 var anchorBox = new AnchorBox();
531 var curElement = this; 500 var curElement = this;
532 var curWindow = this.ownerDocument.defaultView; 501 var curWindow = this.ownerDocument.defaultView;
533 while (curWindow && curElement) { 502 while (curWindow && curElement) {
534 anchorBox.x += curElement.totalOffsetLeft(); 503 anchorBox.x += curElement.totalOffsetLeft();
535 anchorBox.y += curElement.totalOffsetTop(); 504 anchorBox.y += curElement.totalOffsetTop();
536 if (curWindow === targetWindow) 505 if (curWindow === targetWindow)
537 break; 506 break;
538 curElement = curWindow.frameElement; 507 curElement = curWindow.frameElement;
539 curWindow = curWindow.parent; 508 curWindow = curWindow.parent;
540 } 509 }
541 510
542 anchorBox.width = Math.min(this.offsetWidth, targetWindow.innerWidth - ancho rBox.x); 511 anchorBox.width = Math.min(this.offsetWidth, targetWindow.innerWidth - anchorB ox.x);
543 anchorBox.height = Math.min(this.offsetHeight, targetWindow.innerHeight - an chorBox.y); 512 anchorBox.height = Math.min(this.offsetHeight, targetWindow.innerHeight - anch orBox.y);
544 return anchorBox; 513 return anchorBox;
545 }; 514 };
546 515
547 /** 516 /**
548 * @param {boolean=} preventDefault 517 * @param {boolean=} preventDefault
549 */ 518 */
550 Event.prototype.consume = function(preventDefault) 519 Event.prototype.consume = function(preventDefault) {
551 { 520 this.stopImmediatePropagation();
552 this.stopImmediatePropagation(); 521 if (preventDefault)
553 if (preventDefault) 522 this.preventDefault();
554 this.preventDefault(); 523 this.handled = true;
555 this.handled = true;
556 }; 524 };
557 525
558 /** 526 /**
559 * @param {number=} start 527 * @param {number=} start
560 * @param {number=} end 528 * @param {number=} end
561 * @return {!Text} 529 * @return {!Text}
562 */ 530 */
563 Text.prototype.select = function(start, end) 531 Text.prototype.select = function(start, end) {
564 { 532 start = start || 0;
565 start = start || 0; 533 end = end || this.textContent.length;
566 end = end || this.textContent.length;
567 534
568 if (start < 0) 535 if (start < 0)
569 start = end + start; 536 start = end + start;
570 537
571 var selection = this.getComponentSelection(); 538 var selection = this.getComponentSelection();
572 selection.removeAllRanges(); 539 selection.removeAllRanges();
573 var range = this.ownerDocument.createRange(); 540 var range = this.ownerDocument.createRange();
574 range.setStart(this, start); 541 range.setStart(this, start);
575 range.setEnd(this, end); 542 range.setEnd(this, end);
576 selection.addRange(range); 543 selection.addRange(range);
577 return this; 544 return this;
578 }; 545 };
579 546
580 /** 547 /**
581 * @return {?number} 548 * @return {?number}
582 */ 549 */
583 Element.prototype.selectionLeftOffset = function() 550 Element.prototype.selectionLeftOffset = function() {
584 { 551 // Calculate selection offset relative to the current element.
585 // Calculate selection offset relative to the current element.
586 552
587 var selection = this.getComponentSelection(); 553 var selection = this.getComponentSelection();
588 if (!selection.containsNode(this, true)) 554 if (!selection.containsNode(this, true))
589 return null; 555 return null;
590 556
591 var leftOffset = selection.anchorOffset; 557 var leftOffset = selection.anchorOffset;
592 var node = selection.anchorNode; 558 var node = selection.anchorNode;
593 559
594 while (node !== this) { 560 while (node !== this) {
595 while (node.previousSibling) { 561 while (node.previousSibling) {
596 node = node.previousSibling; 562 node = node.previousSibling;
597 leftOffset += node.textContent.length; 563 leftOffset += node.textContent.length;
598 }
599 node = node.parentNodeOrShadowHost();
600 } 564 }
565 node = node.parentNodeOrShadowHost();
566 }
601 567
602 return leftOffset; 568 return leftOffset;
603 }; 569 };
604 570
605 /** 571 /**
606 * @param {...!Node} var_args 572 * @param {...!Node} var_args
607 */ 573 */
608 Node.prototype.appendChildren = function(var_args) 574 Node.prototype.appendChildren = function(var_args) {
609 { 575 for (var i = 0, n = arguments.length; i < n; ++i)
610 for (var i = 0, n = arguments.length; i < n; ++i) 576 this.appendChild(arguments[i]);
611 this.appendChild(arguments[i]);
612 }; 577 };
613 578
614 /** 579 /**
615 * @return {string} 580 * @return {string}
616 */ 581 */
617 Node.prototype.deepTextContent = function() 582 Node.prototype.deepTextContent = function() {
618 { 583 return this.childTextNodes()
619 return this.childTextNodes().map(function(node) { return node.textContent; } ).join(""); 584 .map(function(node) {
585 return node.textContent;
586 })
587 .join('');
620 }; 588 };
621 589
622 /** 590 /**
623 * @return {!Array.<!Node>} 591 * @return {!Array.<!Node>}
624 */ 592 */
625 Node.prototype.childTextNodes = function() 593 Node.prototype.childTextNodes = function() {
626 { 594 var node = this.traverseNextTextNode(this);
627 var node = this.traverseNextTextNode(this); 595 var result = [];
628 var result = []; 596 var nonTextTags = {'STYLE': 1, 'SCRIPT': 1};
629 var nonTextTags = { "STYLE": 1, "SCRIPT": 1 }; 597 while (node) {
630 while (node) { 598 if (!nonTextTags[node.parentElement.nodeName])
631 if (!nonTextTags[node.parentElement.nodeName]) 599 result.push(node);
632 result.push(node); 600 node = node.traverseNextTextNode(this);
633 node = node.traverseNextTextNode(this); 601 }
634 } 602 return result;
635 return result;
636 }; 603 };
637 604
638 /** 605 /**
639 * @param {?Node} node 606 * @param {?Node} node
640 * @return {boolean} 607 * @return {boolean}
641 */ 608 */
642 Node.prototype.isAncestor = function(node) 609 Node.prototype.isAncestor = function(node) {
643 { 610 if (!node)
644 if (!node) 611 return false;
645 return false;
646 612
647 var currentNode = node.parentNodeOrShadowHost(); 613 var currentNode = node.parentNodeOrShadowHost();
648 while (currentNode) { 614 while (currentNode) {
649 if (this === currentNode) 615 if (this === currentNode)
650 return true; 616 return true;
651 currentNode = currentNode.parentNodeOrShadowHost(); 617 currentNode = currentNode.parentNodeOrShadowHost();
652 } 618 }
653 return false; 619 return false;
654 }; 620 };
655 621
656 /** 622 /**
657 * @param {?Node} descendant 623 * @param {?Node} descendant
658 * @return {boolean} 624 * @return {boolean}
659 */ 625 */
660 Node.prototype.isDescendant = function(descendant) 626 Node.prototype.isDescendant = function(descendant) {
661 { 627 return !!descendant && descendant.isAncestor(this);
662 return !!descendant && descendant.isAncestor(this);
663 }; 628 };
664 629
665 /** 630 /**
666 * @param {?Node} node 631 * @param {?Node} node
667 * @return {boolean} 632 * @return {boolean}
668 */ 633 */
669 Node.prototype.isSelfOrAncestor = function(node) 634 Node.prototype.isSelfOrAncestor = function(node) {
670 { 635 return !!node && (node === this || this.isAncestor(node));
671 return !!node && (node === this || this.isAncestor(node));
672 }; 636 };
673 637
674 /** 638 /**
675 * @param {?Node} node 639 * @param {?Node} node
676 * @return {boolean} 640 * @return {boolean}
677 */ 641 */
678 Node.prototype.isSelfOrDescendant = function(node) 642 Node.prototype.isSelfOrDescendant = function(node) {
679 { 643 return !!node && (node === this || this.isDescendant(node));
680 return !!node && (node === this || this.isDescendant(node));
681 }; 644 };
682 645
683 /** 646 /**
684 * @param {!Node=} stayWithin 647 * @param {!Node=} stayWithin
685 * @return {?Node} 648 * @return {?Node}
686 */ 649 */
687 Node.prototype.traverseNextNode = function(stayWithin) 650 Node.prototype.traverseNextNode = function(stayWithin) {
688 { 651 if (this.shadowRoot)
689 if (this.shadowRoot) 652 return this.shadowRoot;
690 return this.shadowRoot;
691 653
692 var distributedNodes = this.getDistributedNodes ? this.getDistributedNodes() : []; 654 var distributedNodes = this.getDistributedNodes ? this.getDistributedNodes() : [];
693 655
694 if (distributedNodes.length) 656 if (distributedNodes.length)
695 return distributedNodes[0]; 657 return distributedNodes[0];
696 658
697 if (this.firstChild) 659 if (this.firstChild)
698 return this.firstChild; 660 return this.firstChild;
699 661
700 var node = this; 662 var node = this;
701 while (node) { 663 while (node) {
702 if (stayWithin && node === stayWithin) 664 if (stayWithin && node === stayWithin)
703 return null; 665 return null;
704 666
705 var sibling = nextSibling(node); 667 var sibling = nextSibling(node);
706 if (sibling) 668 if (sibling)
707 return sibling; 669 return sibling;
708 670
709 node = insertionPoint(node) || node.parentNodeOrShadowHost(); 671 node = insertionPoint(node) || node.parentNodeOrShadowHost();
710 } 672 }
711 673
712 /** 674 /**
713 * @param {!Node} node 675 * @param {!Node} node
714 * @return {?Node} 676 * @return {?Node}
715 */ 677 */
716 function nextSibling(node) 678 function nextSibling(node) {
717 { 679 var parent = insertionPoint(node);
718 var parent = insertionPoint(node); 680 if (!parent)
719 if (!parent) 681 return node.nextSibling;
720 return node.nextSibling; 682 var distributedNodes = parent.getDistributedNodes ? parent.getDistributedNod es() : [];
721 var distributedNodes = parent.getDistributedNodes ? parent.getDistribute dNodes() : [];
722 683
723 var position = Array.prototype.indexOf.call(distributedNodes, node); 684 var position = Array.prototype.indexOf.call(distributedNodes, node);
724 if (position + 1 < distributedNodes.length) 685 if (position + 1 < distributedNodes.length)
725 return distributedNodes[position + 1]; 686 return distributedNodes[position + 1];
726 return null; 687 return null;
727 } 688 }
728 689
729 /** 690 /**
730 * @param {!Node} node 691 * @param {!Node} node
731 * @return {?Node} 692 * @return {?Node}
732 */ 693 */
733 function insertionPoint(node) 694 function insertionPoint(node) {
734 { 695 var insertionPoints = node.getDestinationInsertionPoints ? node.getDestinati onInsertionPoints() : [];
735 var insertionPoints = node.getDestinationInsertionPoints ? node.getDes tinationInsertionPoints() : []; 696 return insertionPoints.length > 0 ? insertionPoints[insertionPoints.length - 1] : null;
736 return insertionPoints.length > 0 ? insertionPoints[insertionPoints.leng th - 1] : null; 697 }
737 }
738 698
739 return null; 699 return null;
740 }; 700 };
741 701
742 /** 702 /**
743 * @param {!Node=} stayWithin 703 * @param {!Node=} stayWithin
744 * @return {?Node} 704 * @return {?Node}
745 */ 705 */
746 Node.prototype.traversePreviousNode = function(stayWithin) 706 Node.prototype.traversePreviousNode = function(stayWithin) {
747 { 707 if (stayWithin && this === stayWithin)
748 if (stayWithin && this === stayWithin) 708 return null;
749 return null; 709 var node = this.previousSibling;
750 var node = this.previousSibling; 710 while (node && node.lastChild)
751 while (node && node.lastChild) 711 node = node.lastChild;
752 node = node.lastChild; 712 if (node)
753 if (node) 713 return node;
754 return node; 714 return this.parentNodeOrShadowHost();
755 return this.parentNodeOrShadowHost();
756 }; 715 };
757 716
758 /** 717 /**
759 * @param {*} text 718 * @param {*} text
760 * @param {string=} placeholder 719 * @param {string=} placeholder
761 * @return {boolean} true if was truncated 720 * @return {boolean} true if was truncated
762 */ 721 */
763 Node.prototype.setTextContentTruncatedIfNeeded = function(text, placeholder) 722 Node.prototype.setTextContentTruncatedIfNeeded = function(text, placeholder) {
764 { 723 // Huge texts in the UI reduce rendering performance drastically.
765 // Huge texts in the UI reduce rendering performance drastically. 724 // Moreover, Blink/WebKit uses <unsigned short> internally for storing text co ntent
766 // Moreover, Blink/WebKit uses <unsigned short> internally for storing text content 725 // length, so texts longer than 65535 are inherently displayed incorrectly.
767 // length, so texts longer than 65535 are inherently displayed incorrectly. 726 const maxTextContentLength = 10000;
768 const maxTextContentLength = 10000;
769 727
770 if (typeof text === "string" && text.length > maxTextContentLength) { 728 if (typeof text === 'string' && text.length > maxTextContentLength) {
771 this.textContent = typeof placeholder === "string" ? placeholder : text. trimMiddle(maxTextContentLength); 729 this.textContent = typeof placeholder === 'string' ? placeholder : text.trim Middle(maxTextContentLength);
772 return true; 730 return true;
773 } 731 }
774 732
775 this.textContent = text; 733 this.textContent = text;
776 return false; 734 return false;
777 }; 735 };
778 736
779 /** 737 /**
780 * @return {?Node} 738 * @return {?Node}
781 */ 739 */
782 Event.prototype.deepElementFromPoint = function() 740 Event.prototype.deepElementFromPoint = function() {
783 { 741 var root = this.target && this.target.getComponentRoot();
784 var root = this.target && this.target.getComponentRoot(); 742 return root ? root.deepElementFromPoint(this.pageX, this.pageY) : null;
785 return root ? root.deepElementFromPoint(this.pageX, this.pageY) : null;
786 }; 743 };
787 744
788 /** 745 /**
789 * @param {number} x 746 * @param {number} x
790 * @param {number} y 747 * @param {number} y
791 * @return {?Node} 748 * @return {?Node}
792 */ 749 */
793 Document.prototype.deepElementFromPoint = function(x, y) 750 Document.prototype.deepElementFromPoint = function(x, y) {
794 { 751 var node = this.elementFromPoint(x, y);
795 var node = this.elementFromPoint(x, y); 752 while (node && node.shadowRoot)
796 while (node && node.shadowRoot) 753 node = node.shadowRoot.elementFromPoint(x, y);
797 node = node.shadowRoot.elementFromPoint(x, y); 754 return node;
798 return node;
799 }; 755 };
800 756
801 DocumentFragment.prototype.deepElementFromPoint = Document.prototype.deepElement FromPoint; 757 DocumentFragment.prototype.deepElementFromPoint = Document.prototype.deepElement FromPoint;
802 758
803 /** 759 /**
804 * @return {?Element} 760 * @return {?Element}
805 */ 761 */
806 Document.prototype.deepActiveElement = function() 762 Document.prototype.deepActiveElement = function() {
807 { 763 var activeElement = this.activeElement;
808 var activeElement = this.activeElement; 764 while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot.a ctiveElement)
809 while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot .activeElement) 765 activeElement = activeElement.shadowRoot.activeElement;
810 activeElement = activeElement.shadowRoot.activeElement; 766 return activeElement;
811 return activeElement;
812 }; 767 };
813 768
814 DocumentFragment.prototype.deepActiveElement = Document.prototype.deepActiveElem ent; 769 DocumentFragment.prototype.deepActiveElement = Document.prototype.deepActiveElem ent;
815 770
816 /** 771 /**
817 * @return {boolean} 772 * @return {boolean}
818 */ 773 */
819 Element.prototype.hasFocus = function() 774 Element.prototype.hasFocus = function() {
820 { 775 var root = this.getComponentRoot();
821 var root = this.getComponentRoot(); 776 return !!root && this.isSelfOrAncestor(root.activeElement);
822 return !!root && this.isSelfOrAncestor(root.activeElement);
823 }; 777 };
824 778
825 /** 779 /**
826 * @return {?Document|?DocumentFragment} 780 * @return {?Document|?DocumentFragment}
827 */ 781 */
828 Node.prototype.getComponentRoot = function() 782 Node.prototype.getComponentRoot = function() {
829 { 783 var node = this;
830 var node = this; 784 while (node && node.nodeType !== Node.DOCUMENT_FRAGMENT_NODE && node.nodeType !== Node.DOCUMENT_NODE)
831 while (node && node.nodeType !== Node.DOCUMENT_FRAGMENT_NODE && node.nodeTyp e !== Node.DOCUMENT_NODE) 785 node = node.parentNode;
832 node = node.parentNode; 786 return /** @type {?Document|?DocumentFragment} */ (node);
833 return /** @type {?Document|?DocumentFragment} */ (node);
834 }; 787 };
835 788
836 /** 789 /**
837 * @param {!Event} event 790 * @param {!Event} event
838 * @return {boolean} 791 * @return {boolean}
839 */ 792 */
840 function isEnterKey(event) 793 function isEnterKey(event) {
841 { 794 // Check if in IME.
842 // Check if in IME. 795 return event.keyCode !== 229 && event.key === 'Enter';
843 return event.keyCode !== 229 && event.key === "Enter";
844 } 796 }
845 797
846 /** 798 /**
847 * @param {!Event} event 799 * @param {!Event} event
848 * @return {boolean} 800 * @return {boolean}
849 */ 801 */
850 function isEscKey(event) 802 function isEscKey(event) {
851 { 803 return event.keyCode === 27;
852 return event.keyCode === 27;
853 } 804 }
854 805
855 /** 806 /**
856 * @param {function()} callback 807 * @param {function()} callback
857 * @suppressGlobalPropertiesCheck 808 * @suppressGlobalPropertiesCheck
858 */ 809 */
859 function runOnWindowLoad(callback) 810 function runOnWindowLoad(callback) {
860 { 811 /**
861 /** 812 * @suppressGlobalPropertiesCheck
862 * @suppressGlobalPropertiesCheck 813 */
863 */ 814 function windowLoaded() {
864 function windowLoaded() 815 window.removeEventListener('DOMContentLoaded', windowLoaded, false);
865 { 816 callback();
866 window.removeEventListener("DOMContentLoaded", windowLoaded, false); 817 }
867 callback();
868 }
869 818
870 if (document.readyState === "complete" || document.readyState === "interacti ve") 819 if (document.readyState === 'complete' || document.readyState === 'interactive ')
871 callback(); 820 callback();
872 else 821 else
873 window.addEventListener("DOMContentLoaded", windowLoaded, false); 822 window.addEventListener('DOMContentLoaded', windowLoaded, false);
874 } 823 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698