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

Side by Side Diff: Source/devtools/front_end/host/DOMExtension.js

Issue 673163004: [DevTools] Extract platform module. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fixed bug in hosted mode Created 6 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2007 Apple Inc. All rights reserved.
3 * Copyright (C) 2012 Google Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 * its contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Contains diff method based on Javascript Diff Algorithm By John Resig
30 * http://ejohn.org/files/jsdiff.js (released under the MIT license).
31 */
32
33 /**
34 * @param {number} offset
35 * @param {string} stopCharacters
36 * @param {!Node} stayWithinNode
37 * @param {string=} direction
38 * @return {!Range}
39 */
40 Node.prototype.rangeOfWord = function(offset, stopCharacters, stayWithinNode, di rection)
41 {
42 var startNode;
43 var startOffset = 0;
44 var endNode;
45 var endOffset = 0;
46
47 if (!stayWithinNode)
48 stayWithinNode = this;
49
50 if (!direction || direction === "backward" || direction === "both") {
51 var node = this;
52 while (node) {
53 if (node === stayWithinNode) {
54 if (!startNode)
55 startNode = stayWithinNode;
56 break;
57 }
58
59 if (node.nodeType === Node.TEXT_NODE) {
60 var start = (node === this ? (offset - 1) : (node.nodeValue.leng th - 1));
61 for (var i = start; i >= 0; --i) {
62 if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) {
63 startNode = node;
64 startOffset = i + 1;
65 break;
66 }
67 }
68 }
69
70 if (startNode)
71 break;
72
73 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 }
84
85 if (!direction || direction === "forward" || direction === "both") {
86 node = this;
87 while (node) {
88 if (node === stayWithinNode) {
89 if (!endNode)
90 endNode = stayWithinNode;
91 break;
92 }
93
94 if (node.nodeType === Node.TEXT_NODE) {
95 var start = (node === this ? offset : 0);
96 for (var i = start; i < node.nodeValue.length; ++i) {
97 if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) {
98 endNode = node;
99 endOffset = i;
100 break;
101 }
102 }
103 }
104
105 if (endNode)
106 break;
107
108 node = node.traverseNextNode(stayWithinNode);
109 }
110
111 if (!endNode) {
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 }
119
120 var result = this.ownerDocument.createRange();
121 result.setStart(startNode, startOffset);
122 result.setEnd(endNode, endOffset);
123
124 return result;
125 }
126
127 /**
128 * @param {!Node=} stayWithin
129 * @return {?Node}
130 */
131 Node.prototype.traverseNextTextNode = function(stayWithin)
132 {
133 var node = this.traverseNextNode(stayWithin);
134 if (!node)
135 return null;
136
137 while (node && node.nodeType !== Node.TEXT_NODE)
138 node = node.traverseNextNode(stayWithin);
139
140 return node;
141 }
142
143 /**
144 * @param {number} offset
145 * @return {!{container: !Node, offset: number}}
146 */
147 Node.prototype.rangeBoundaryForOffset = function(offset)
148 {
149 var node = this.traverseNextTextNode(this);
150 while (node && offset > node.nodeValue.length) {
151 offset -= node.nodeValue.length;
152 node = node.traverseNextTextNode(this);
153 }
154 if (!node)
155 return { container: this, offset: 0 };
156 return { container: node, offset: offset };
157 }
158
159 /**
160 * @param {number|undefined} x
161 * @param {number|undefined} y
162 * @param {!Element=} relativeTo
163 */
164 Element.prototype.positionAt = function(x, y, relativeTo)
165 {
166 var shift = {x: 0, y: 0};
167 if (relativeTo)
168 shift = relativeTo.boxInWindow(this.ownerDocument.defaultView);
169
170 if (typeof x === "number")
171 this.style.setProperty("left", (shift.x + x) + "px");
172 else
173 this.style.removeProperty("left");
174
175 if (typeof y === "number")
176 this.style.setProperty("top", (shift.y + y) + "px");
177 else
178 this.style.removeProperty("top");
179 }
180
181 /**
182 * @return {boolean}
183 */
184 Element.prototype.isScrolledToBottom = function()
185 {
186 // This code works only for 0-width border.
187 // Both clientHeight and scrollHeight are rounded to integer values, so we t olerate
188 // one pixel error.
189 return Math.abs(this.scrollTop + this.clientHeight - this.scrollHeight) <= 1 ;
190 }
191
192 /**
193 * @param {!Node} fromNode
194 * @param {!Node} toNode
195 */
196 function removeSubsequentNodes(fromNode, toNode)
197 {
198 for (var node = fromNode; node && node !== toNode; ) {
199 var nodeToRemove = node;
200 node = node.nextSibling;
201 nodeToRemove.remove();
202 }
203 }
204
205 /**
206 * @constructor
207 * @param {!Size} minimum
208 * @param {?Size=} preferred
209 */
210 function Constraints(minimum, preferred)
211 {
212 /**
213 * @type {!Size}
214 */
215 this.minimum = minimum;
216
217 /**
218 * @type {!Size}
219 */
220 this.preferred = preferred || minimum;
221
222 if (this.minimum.width > this.preferred.width || this.minimum.height > this. preferred.height)
223 throw new Error("Minimum size is greater than preferred.");
224 }
225
226 /**
227 * @param {?Constraints} constraints
228 * @return {boolean}
229 */
230 Constraints.prototype.isEqual = function(constraints)
231 {
232 return !!constraints && this.minimum.isEqual(constraints.minimum) && this.pr eferred.isEqual(constraints.preferred);
233 }
234
235 /**
236 * @param {!Constraints|number} value
237 * @return {!Constraints}
238 */
239 Constraints.prototype.widthToMax = function(value)
240 {
241 if (typeof value === "number")
242 return new Constraints(this.minimum.widthToMax(value), this.preferred.wi dthToMax(value));
243 return new Constraints(this.minimum.widthToMax(value.minimum), this.preferre d.widthToMax(value.preferred));
244 }
245
246 /**
247 * @param {!Constraints|number} value
248 * @return {!Constraints}
249 */
250 Constraints.prototype.addWidth = function(value)
251 {
252 if (typeof value === "number")
253 return new Constraints(this.minimum.addWidth(value), this.preferred.addW idth(value));
254 return new Constraints(this.minimum.addWidth(value.minimum), this.preferred. addWidth(value.preferred));
255 }
256
257 /**
258 * @param {!Constraints|number} value
259 * @return {!Constraints}
260 */
261 Constraints.prototype.heightToMax = function(value)
262 {
263 if (typeof value === "number")
264 return new Constraints(this.minimum.heightToMax(value), this.preferred.h eightToMax(value));
265 return new Constraints(this.minimum.heightToMax(value.minimum), this.preferr ed.heightToMax(value.preferred));
266 }
267
268 /**
269 * @param {!Constraints|number} value
270 * @return {!Constraints}
271 */
272 Constraints.prototype.addHeight = function(value)
273 {
274 if (typeof value === "number")
275 return new Constraints(this.minimum.addHeight(value), this.preferred.add Height(value));
276 return new Constraints(this.minimum.addHeight(value.minimum), this.preferred .addHeight(value.preferred));
277 }
278
279 /**
280 * @param {!Event} event
281 * @return {boolean}
282 */
283 Element.prototype.containsEventPoint = function(event)
284 {
285 var box = this.getBoundingClientRect();
286 return box.left < event.x && event.x < box.right &&
287 box.top < event.y && event.y < box.bottom;
288 }
289
290 /**
291 * @param {!Array.<string>} nameArray
292 * @return {?Node}
293 */
294 Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = function(nameArray)
295 {
296 for (var node = this; node && node !== this.ownerDocument; node = node.paren tNodeOrShadowHost()) {
297 for (var i = 0; i < nameArray.length; ++i) {
298 if (node.nodeName.toLowerCase() === nameArray[i].toLowerCase())
299 return node;
300 }
301 }
302 return null;
303 }
304
305 /**
306 * @param {string} nodeName
307 * @return {?Node}
308 */
309 Node.prototype.enclosingNodeOrSelfWithNodeName = function(nodeName)
310 {
311 return this.enclosingNodeOrSelfWithNodeNameInArray([nodeName]);
312 }
313
314 /**
315 * @param {string} className
316 * @param {!Element=} stayWithin
317 * @return {?Element}
318 */
319 Node.prototype.enclosingNodeOrSelfWithClass = function(className, stayWithin)
320 {
321 for (var node = this; node && node !== stayWithin && node !== this.ownerDocu ment; node = node.parentNodeOrShadowHost()) {
322 if (node.nodeType === Node.ELEMENT_NODE && node.classList.contains(class Name))
323 return /** @type {!Element} */ (node);
324 }
325 return null;
326 }
327
328 /**
329 * @return {?Element}
330 */
331 Node.prototype.parentElementOrShadowHost = function()
332 {
333 var node = this.parentNode;
334 if (!node)
335 return null;
336 if (node.nodeType === Node.ELEMENT_NODE)
337 return /** @type {!Element} */ (node);
338 if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE)
339 return /** @type {!Element} */ (node.host);
340 return null;
341 }
342
343 /**
344 * @return {?Node}
345 */
346 Node.prototype.parentNodeOrShadowHost = function()
347 {
348 return this.parentNode || this.host || null;
349 }
350
351 /**
352 * @param {string} query
353 * @return {?Node}
354 */
355 Element.prototype.query = function(query)
356 {
357 return this.ownerDocument.evaluate(query, this, null, XPathResult.FIRST_ORDE RED_NODE_TYPE, null).singleNodeValue;
358 }
359
360 Element.prototype.removeChildren = function()
361 {
362 if (this.firstChild)
363 this.textContent = "";
364 }
365
366 /**
367 * @return {boolean}
368 */
369 Element.prototype.isInsertionCaretInside = function()
370 {
371 var selection = window.getSelection();
372 if (!selection.rangeCount || !selection.isCollapsed)
373 return false;
374 var selectionRange = selection.getRangeAt(0);
375 return selectionRange.startContainer.isSelfOrDescendant(this);
376 }
377
378 /**
379 * @param {string} tagName
380 * @return {!Element}
381 * @suppressGlobalPropertiesCheck
382 */
383 function createElement(tagName)
384 {
385 return document.createElement(tagName);
386 }
387
388 /**
389 * @param {number|string} data
390 * @return {!Text}
391 * @suppressGlobalPropertiesCheck
392 */
393 function createTextNode(data)
394 {
395 return document.createTextNode(data);
396 }
397
398 /**
399 * @param {string} elementName
400 * @param {string=} className
401 * @return {!Element}
402 */
403 Document.prototype.createElementWithClass = function(elementName, className)
404 {
405 var element = this.createElement(elementName);
406 if (className)
407 element.className = className;
408 return element;
409 }
410
411 /**
412 * @param {string} elementName
413 * @param {string=} className
414 * @return {!Element}
415 * @suppressGlobalPropertiesCheck
416 */
417 function createElementWithClass(elementName, className)
418 {
419 return document.createElementWithClass(elementName, className);
420 }
421
422 /**
423 * @return {!DocumentFragment}
424 * @suppressGlobalPropertiesCheck
425 */
426 function createDocumentFragment()
427 {
428 return document.createDocumentFragment();
429 }
430
431 /**
432 * @param {string} elementName
433 * @param {string=} className
434 * @return {!Element}
435 */
436 Element.prototype.createChild = function(elementName, className)
437 {
438 var element = this.ownerDocument.createElementWithClass(elementName, classNa me);
439 this.appendChild(element);
440 return element;
441 }
442
443 DocumentFragment.prototype.createChild = Element.prototype.createChild;
444
445 /**
446 * @param {string} text
447 * @return {!Text}
448 */
449 Element.prototype.createTextChild = function(text)
450 {
451 var element = this.ownerDocument.createTextNode(text);
452 this.appendChild(element);
453 return element;
454 }
455
456 DocumentFragment.prototype.createTextChild = Element.prototype.createTextChild;
457
458 /**
459 * @param {...string} var_args
460 */
461 Element.prototype.createTextChildren = function(var_args)
462 {
463 for (var i = 0, n = arguments.length; i < n; ++i)
464 this.createTextChild(arguments[i]);
465 }
466
467 DocumentFragment.prototype.createTextChildren = Element.prototype.createTextChil dren;
468
469 /**
470 * @param {...!Element} var_args
471 */
472 Element.prototype.appendChildren = function(var_args)
473 {
474 for (var i = 0, n = arguments.length; i < n; ++i)
475 this.appendChild(arguments[i]);
476 }
477
478 /**
479 * @return {number}
480 */
481 Element.prototype.totalOffsetLeft = function()
482 {
483 return this.totalOffset().left;
484 }
485
486 /**
487 * @return {number}
488 */
489 Element.prototype.totalOffsetTop = function()
490 {
491 return this.totalOffset().top;
492 }
493
494 /**
495 * @return {!{left: number, top: number}}
496 */
497 Element.prototype.totalOffset = function()
498 {
499 var rect = this.getBoundingClientRect();
500 return { left: rect.left, top: rect.top };
501 }
502
503 /**
504 * @return {!{left: number, top: number}}
505 */
506 Element.prototype.scrollOffset = function()
507 {
508 var curLeft = 0;
509 var curTop = 0;
510 for (var element = this; element; element = element.scrollParent) {
511 curLeft += element.scrollLeft;
512 curTop += element.scrollTop;
513 }
514 return { left: curLeft, top: curTop };
515 }
516
517 /**
518 * @constructor
519 * @param {number=} x
520 * @param {number=} y
521 * @param {number=} width
522 * @param {number=} height
523 */
524 function AnchorBox(x, y, width, height)
525 {
526 this.x = x || 0;
527 this.y = y || 0;
528 this.width = width || 0;
529 this.height = height || 0;
530 }
531
532 /**
533 * @param {!AnchorBox} box
534 * @return {!AnchorBox}
535 */
536 AnchorBox.prototype.relativeTo = function(box)
537 {
538 return new AnchorBox(
539 this.x - box.x, this.y - box.y, this.width, this.height);
540 }
541
542 /**
543 * @param {!Element} element
544 * @return {!AnchorBox}
545 */
546 AnchorBox.prototype.relativeToElement = function(element)
547 {
548 return this.relativeTo(element.boxInWindow(element.ownerDocument.defaultView ));
549 }
550
551 /**
552 * @param {?AnchorBox} anchorBox
553 * @return {boolean}
554 */
555 AnchorBox.prototype.equals = function(anchorBox)
556 {
557 return !!anchorBox && this.x === anchorBox.x && this.y === anchorBox.y && th is.width === anchorBox.width && this.height === anchorBox.height;
558 }
559
560 /**
561 * @param {!Window} targetWindow
562 * @return {!AnchorBox}
563 */
564 Element.prototype.offsetRelativeToWindow = function(targetWindow)
565 {
566 var elementOffset = new AnchorBox();
567 var curElement = this;
568 var curWindow = this.ownerDocument.defaultView;
569 while (curWindow && curElement) {
570 elementOffset.x += curElement.totalOffsetLeft();
571 elementOffset.y += curElement.totalOffsetTop();
572 if (curWindow === targetWindow)
573 break;
574
575 curElement = curWindow.frameElement;
576 curWindow = curWindow.parent;
577 }
578
579 return elementOffset;
580 }
581
582 /**
583 * @param {!Window=} targetWindow
584 * @return {!AnchorBox}
585 */
586 Element.prototype.boxInWindow = function(targetWindow)
587 {
588 targetWindow = targetWindow || this.ownerDocument.defaultView;
589
590 var anchorBox = this.offsetRelativeToWindow(window);
591 anchorBox.width = Math.min(this.offsetWidth, window.innerWidth - anchorBox.x );
592 anchorBox.height = Math.min(this.offsetHeight, window.innerHeight - anchorBo x.y);
593
594 return anchorBox;
595 }
596
597 /**
598 * @param {string} text
599 */
600 Element.prototype.setTextAndTitle = function(text)
601 {
602 this.textContent = text;
603 this.title = text;
604 }
605
606 KeyboardEvent.prototype.__defineGetter__("data", function()
607 {
608 // Emulate "data" attribute from DOM 3 TextInput event.
609 // See http://www.w3.org/TR/DOM-Level-3-Events/#events-Events-TextEvent-data
610 switch (this.type) {
611 case "keypress":
612 if (!this.ctrlKey && !this.metaKey)
613 return String.fromCharCode(this.charCode);
614 else
615 return "";
616 case "keydown":
617 case "keyup":
618 if (!this.ctrlKey && !this.metaKey && !this.altKey)
619 return String.fromCharCode(this.which);
620 else
621 return "";
622 }
623 });
624
625 /**
626 * @param {boolean=} preventDefault
627 */
628 Event.prototype.consume = function(preventDefault)
629 {
630 this.stopImmediatePropagation();
631 if (preventDefault)
632 this.preventDefault();
633 this.handled = true;
634 }
635
636 /**
637 * @param {number=} start
638 * @param {number=} end
639 * @return {!Text}
640 */
641 Text.prototype.select = function(start, end)
642 {
643 start = start || 0;
644 end = end || this.textContent.length;
645
646 if (start < 0)
647 start = end + start;
648
649 var selection = this.ownerDocument.defaultView.getSelection();
650 selection.removeAllRanges();
651 var range = this.ownerDocument.createRange();
652 range.setStart(this, start);
653 range.setEnd(this, end);
654 selection.addRange(range);
655 return this;
656 }
657
658 /**
659 * @return {?number}
660 */
661 Element.prototype.selectionLeftOffset = function()
662 {
663 // Calculate selection offset relative to the current element.
664
665 var selection = window.getSelection();
666 if (!selection.containsNode(this, true))
667 return null;
668
669 var leftOffset = selection.anchorOffset;
670 var node = selection.anchorNode;
671
672 while (node !== this) {
673 while (node.previousSibling) {
674 node = node.previousSibling;
675 leftOffset += node.textContent.length;
676 }
677 node = node.parentNodeOrShadowHost();
678 }
679
680 return leftOffset;
681 }
682
683 /**
684 * @return {string}
685 */
686 Node.prototype.deepTextContent = function()
687 {
688 var node = this.traverseNextTextNode(this);
689 var result = [];
690 var nonTextTags = { "STYLE": 1, "SCRIPT": 1 };
691 while (node) {
692 if (!nonTextTags[node.parentElement.nodeName])
693 result.push(node.textContent);
694 node = node.traverseNextTextNode(this);
695 }
696 return result.join("");
697 }
698
699 /**
700 * @param {?Node} node
701 * @return {boolean}
702 */
703 Node.prototype.isAncestor = function(node)
704 {
705 if (!node)
706 return false;
707
708 var currentNode = node.parentNodeOrShadowHost();
709 while (currentNode) {
710 if (this === currentNode)
711 return true;
712 currentNode = currentNode.parentNodeOrShadowHost();
713 }
714 return false;
715 }
716
717 /**
718 * @param {?Node} descendant
719 * @return {boolean}
720 */
721 Node.prototype.isDescendant = function(descendant)
722 {
723 return !!descendant && descendant.isAncestor(this);
724 }
725
726 /**
727 * @param {?Node} node
728 * @return {boolean}
729 */
730 Node.prototype.isSelfOrAncestor = function(node)
731 {
732 return !!node && (node === this || this.isAncestor(node));
733 }
734
735 /**
736 * @param {?Node} node
737 * @return {boolean}
738 */
739 Node.prototype.isSelfOrDescendant = function(node)
740 {
741 return !!node && (node === this || this.isDescendant(node));
742 }
743
744 /**
745 * @param {!Node=} stayWithin
746 * @return {?Node}
747 */
748 Node.prototype.traverseNextNode = function(stayWithin)
749 {
750 if (this.firstChild)
751 return this.firstChild;
752
753 if (this.shadowRoot)
754 return this.shadowRoot;
755
756 if (stayWithin && this === stayWithin)
757 return null;
758
759 var node = this.nextSibling;
760 if (node)
761 return node;
762
763 node = this;
764 while (node && !node.nextSibling && (!stayWithin || !node.parentNodeOrShadow Host() || node.parentNodeOrShadowHost() !== stayWithin))
765 node = node.parentNodeOrShadowHost();
766 if (!node)
767 return null;
768
769 return node.nextSibling;
770 }
771
772 /**
773 * @param {!Node=} stayWithin
774 * @return {?Node}
775 */
776 Node.prototype.traversePreviousNode = function(stayWithin)
777 {
778 if (stayWithin && this === stayWithin)
779 return null;
780 var node = this.previousSibling;
781 while (node && node.lastChild)
782 node = node.lastChild;
783 if (node)
784 return node;
785 return this.parentNodeOrShadowHost();
786 }
787
788 /**
789 * @param {*} text
790 * @param {string=} placeholder
791 * @return {boolean} true if was truncated
792 */
793 Node.prototype.setTextContentTruncatedIfNeeded = function(text, placeholder)
794 {
795 // Huge texts in the UI reduce rendering performance drastically.
796 // Moreover, Blink/WebKit uses <unsigned short> internally for storing text content
797 // length, so texts longer than 65535 are inherently displayed incorrectly.
798 const maxTextContentLength = 65535;
799
800 if (typeof text === "string" && text.length > maxTextContentLength) {
801 this.textContent = typeof placeholder === "string" ? placeholder : text. trimEnd(maxTextContentLength);
802 return true;
803 }
804
805 this.textContent = text;
806 return false;
807 }
808
809 /**
810 * @return {?Node}
811 */
812 Event.prototype.deepElementFromPoint = function()
813 {
814 // 1. climb to the component root.
815 var node = this.target;
816 while (node && node.nodeType !== Node.DOCUMENT_FRAGMENT_NODE && node.nodeTyp e !== Node.DOCUMENT_NODE)
817 node = node.parentNode;
818
819 if (!node)
820 return null;
821
822 // 2. Find deepest node by coordinates.
823 node = node.elementFromPoint(this.pageX, this.pageY);
824 while (node && node.shadowRoot)
825 node = node.shadowRoot.elementFromPoint(this.pageX, this.pageY);
826 return node;
827 }
828
829 /**
830 * @param {number} x
831 * @param {number} y
832 * @return {?Node}
833 */
834 Document.prototype.deepElementFromPoint = function(x, y)
835 {
836 var node = this.elementFromPoint(x, y);
837 while (node && node.shadowRoot)
838 node = node.shadowRoot.elementFromPoint(x, y);
839 return node;
840 }
841
842 /**
843 * @return {boolean}
844 */
845 function isEnterKey(event) {
846 // Check if in IME.
847 return event.keyCode !== 229 && event.keyIdentifier === "Enter";
848 }
849
850 function consumeEvent(e)
851 {
852 e.consume();
853 }
OLDNEW
« no previous file with comments | « Source/devtools/front_end/heap_snapshot_worker/module.json ('k') | Source/devtools/front_end/host/ToolboxHost.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698