OLD | NEW |
---|---|
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 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
301 return box.left < event.x && event.x < box.right && | 301 return box.left < event.x && event.x < box.right && |
302 box.top < event.y && event.y < box.bottom; | 302 box.top < event.y && event.y < box.bottom; |
303 } | 303 } |
304 | 304 |
305 /** | 305 /** |
306 * @param {!Array.<string>} nameArray | 306 * @param {!Array.<string>} nameArray |
307 * @return {?Node} | 307 * @return {?Node} |
308 */ | 308 */ |
309 Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = function(nameArray) | 309 Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = function(nameArray) |
310 { | 310 { |
311 for (var node = this; node && node !== this.ownerDocument; node = node.paren tNode) { | 311 for (var node = this; node && node !== this.ownerDocument; node = node.paren tNodeOrShadowHost()) { |
312 for (var i = 0; i < nameArray.length; ++i) { | 312 for (var i = 0; i < nameArray.length; ++i) { |
313 if (node.nodeName.toLowerCase() === nameArray[i].toLowerCase()) | 313 if (node.nodeName.toLowerCase() === nameArray[i].toLowerCase()) |
314 return node; | 314 return node; |
315 } | 315 } |
316 } | 316 } |
317 return null; | 317 return null; |
318 } | 318 } |
319 | 319 |
320 /** | 320 /** |
321 * @param {string} nodeName | 321 * @param {string} nodeName |
322 * @return {?Node} | 322 * @return {?Node} |
323 */ | 323 */ |
324 Node.prototype.enclosingNodeOrSelfWithNodeName = function(nodeName) | 324 Node.prototype.enclosingNodeOrSelfWithNodeName = function(nodeName) |
325 { | 325 { |
326 return this.enclosingNodeOrSelfWithNodeNameInArray([nodeName]); | 326 return this.enclosingNodeOrSelfWithNodeNameInArray([nodeName]); |
327 } | 327 } |
328 | 328 |
329 /** | 329 /** |
330 * @param {string} className | 330 * @param {string} className |
331 * @param {!Element=} stayWithin | 331 * @param {!Element=} stayWithin |
332 * @return {?Element} | 332 * @return {?Element} |
333 */ | 333 */ |
334 Node.prototype.enclosingNodeOrSelfWithClass = function(className, stayWithin) | 334 Node.prototype.enclosingNodeOrSelfWithClass = function(className, stayWithin) |
335 { | 335 { |
336 for (var node = this; node && node !== stayWithin && node !== this.ownerDocu ment; node = node.parentNode) { | 336 for (var node = this; node && node !== stayWithin && node !== this.ownerDocu ment; node = node.parentNodeOrShadowHost()) { |
337 if (node.nodeType === Node.ELEMENT_NODE && node.classList.contains(class Name)) | 337 if (node.nodeType === Node.ELEMENT_NODE && node.classList.contains(class Name)) |
338 return /** @type {!Element} */ (node); | 338 return /** @type {!Element} */ (node); |
339 } | 339 } |
340 return null; | 340 return null; |
341 } | 341 } |
342 | 342 |
343 /** | 343 /** |
344 * @return {?Element} | |
345 */ | |
346 Node.prototype.parentElementOrShadowHost = function() | |
aandrey
2014/09/25 05:47:21
I'd expect this to give identical result as parent
pfeldman
2014/10/13 13:33:11
I think it will produce identical results for DOM
| |
347 { | |
348 var node = this.parentNode; | |
349 if (!node) | |
350 return null; | |
351 if (node.nodeType === Node.ELEMENT_NODE) | |
352 return /** @type {!Element} */ (node); | |
353 if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) | |
aandrey
2014/09/25 05:47:21
else if
pfeldman
2014/10/13 13:33:11
We can't do else if by the guidelines.
| |
354 return /** @type {!Element} */ (node.host); | |
aandrey
2014/09/25 05:47:21
this.host? (see message above)
pfeldman
2014/10/13 13:33:11
this.host is null for shadow root element children
| |
355 return null; | |
356 } | |
357 | |
358 /** | |
359 * @return {?Node} | |
360 */ | |
361 Node.prototype.parentNodeOrShadowHost = function() | |
362 { | |
363 return this.parentNode || this.host || null; | |
364 } | |
365 | |
366 /** | |
344 * @param {string} query | 367 * @param {string} query |
345 * @return {?Node} | 368 * @return {?Node} |
346 */ | 369 */ |
347 Element.prototype.query = function(query) | 370 Element.prototype.query = function(query) |
348 { | 371 { |
349 return this.ownerDocument.evaluate(query, this, null, XPathResult.FIRST_ORDE RED_NODE_TYPE, null).singleNodeValue; | 372 return this.ownerDocument.evaluate(query, this, null, XPathResult.FIRST_ORDE RED_NODE_TYPE, null).singleNodeValue; |
350 } | 373 } |
351 | 374 |
352 Element.prototype.removeChildren = function() | 375 Element.prototype.removeChildren = function() |
353 { | 376 { |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
619 return null; | 642 return null; |
620 | 643 |
621 var leftOffset = selection.anchorOffset; | 644 var leftOffset = selection.anchorOffset; |
622 var node = selection.anchorNode; | 645 var node = selection.anchorNode; |
623 | 646 |
624 while (node !== this) { | 647 while (node !== this) { |
625 while (node.previousSibling) { | 648 while (node.previousSibling) { |
626 node = node.previousSibling; | 649 node = node.previousSibling; |
627 leftOffset += node.textContent.length; | 650 leftOffset += node.textContent.length; |
628 } | 651 } |
629 node = node.parentNode; | 652 node = node.parentNodeOrShadowHost(); |
630 } | 653 } |
631 | 654 |
632 return leftOffset; | 655 return leftOffset; |
633 } | 656 } |
634 | 657 |
635 /** | 658 /** |
636 * @param {?Node} node | 659 * @param {?Node} node |
637 * @return {boolean} | 660 * @return {boolean} |
638 */ | 661 */ |
639 Node.prototype.isAncestor = function(node) | 662 Node.prototype.isAncestor = function(node) |
640 { | 663 { |
641 if (!node) | 664 if (!node) |
642 return false; | 665 return false; |
643 | 666 |
644 var currentNode = node.parentNode; | 667 var currentNode = node.parentNodeOrShadowHost(); |
645 while (currentNode) { | 668 while (currentNode) { |
646 if (this === currentNode) | 669 if (this === currentNode) |
647 return true; | 670 return true; |
648 currentNode = currentNode.parentNode; | 671 currentNode = currentNode.parentNodeOrShadowHost(); |
649 } | 672 } |
650 return false; | 673 return false; |
651 } | 674 } |
652 | 675 |
653 /** | 676 /** |
654 * @param {?Node} descendant | 677 * @param {?Node} descendant |
655 * @return {boolean} | 678 * @return {boolean} |
656 */ | 679 */ |
657 Node.prototype.isDescendant = function(descendant) | 680 Node.prototype.isDescendant = function(descendant) |
658 { | 681 { |
(...skipping 29 matching lines...) Expand all Loading... | |
688 return node; | 711 return node; |
689 | 712 |
690 if (stayWithin && this === stayWithin) | 713 if (stayWithin && this === stayWithin) |
691 return null; | 714 return null; |
692 | 715 |
693 node = this.nextSibling; | 716 node = this.nextSibling; |
694 if (node) | 717 if (node) |
695 return node; | 718 return node; |
696 | 719 |
697 node = this; | 720 node = this; |
698 while (node && !node.nextSibling && (!stayWithin || !node.parentNode || node .parentNode !== stayWithin)) | 721 while (node && !node.nextSibling && (!stayWithin || !node.parentNodeOrShadow Host() || node.parentNodeOrShadowHost() !== stayWithin)) |
699 node = node.parentNode; | 722 node = node.parentNodeOrShadowHost(); |
700 if (!node) | 723 if (!node) |
701 return null; | 724 return null; |
702 | 725 |
703 return node.nextSibling; | 726 return node.nextSibling; |
704 } | 727 } |
705 | 728 |
706 /** | 729 /** |
707 * @param {!Node=} stayWithin | 730 * @param {!Node=} stayWithin |
708 * @return {?Node} | 731 * @return {?Node} |
709 */ | 732 */ |
710 Node.prototype.traversePreviousNode = function(stayWithin) | 733 Node.prototype.traversePreviousNode = function(stayWithin) |
711 { | 734 { |
712 if (stayWithin && this === stayWithin) | 735 if (stayWithin && this === stayWithin) |
713 return null; | 736 return null; |
714 var node = this.previousSibling; | 737 var node = this.previousSibling; |
715 while (node && node.lastChild) | 738 while (node && node.lastChild) |
716 node = node.lastChild; | 739 node = node.lastChild; |
717 if (node) | 740 if (node) |
718 return node; | 741 return node; |
719 return this.parentNode; | 742 return this.parentNodeOrShadowHost(); |
720 } | 743 } |
721 | 744 |
722 /** | 745 /** |
723 * @param {*} text | 746 * @param {*} text |
724 * @param {string=} placeholder | 747 * @param {string=} placeholder |
725 * @return {boolean} true if was truncated | 748 * @return {boolean} true if was truncated |
726 */ | 749 */ |
727 Node.prototype.setTextContentTruncatedIfNeeded = function(text, placeholder) | 750 Node.prototype.setTextContentTruncatedIfNeeded = function(text, placeholder) |
728 { | 751 { |
729 // Huge texts in the UI reduce rendering performance drastically. | 752 // Huge texts in the UI reduce rendering performance drastically. |
730 // Moreover, Blink/WebKit uses <unsigned short> internally for storing text content | 753 // Moreover, Blink/WebKit uses <unsigned short> internally for storing text content |
731 // length, so texts longer than 65535 are inherently displayed incorrectly. | 754 // length, so texts longer than 65535 are inherently displayed incorrectly. |
732 const maxTextContentLength = 65535; | 755 const maxTextContentLength = 65535; |
733 | 756 |
734 if (typeof text === "string" && text.length > maxTextContentLength) { | 757 if (typeof text === "string" && text.length > maxTextContentLength) { |
735 this.textContent = typeof placeholder === "string" ? placeholder : text. trimEnd(maxTextContentLength); | 758 this.textContent = typeof placeholder === "string" ? placeholder : text. trimEnd(maxTextContentLength); |
736 return true; | 759 return true; |
737 } | 760 } |
738 | 761 |
739 this.textContent = text; | 762 this.textContent = text; |
740 return false; | 763 return false; |
741 } | 764 } |
742 | 765 |
743 /** | 766 /** |
767 * @return {?Node} | |
768 */ | |
769 Event.prototype.elementFromPoint = function() | |
770 { | |
771 var node = this.target; | |
772 while (node && node.nodeType !== Node.DOCUMENT_FRAGMENT_NODE && node.nodeTyp e !== Node.DOCUMENT_NODE) | |
773 node = node.parentNode; | |
774 return node ? node.elementFromPoint(this.pageX, this.pageY) : null; | |
775 } | |
776 | |
777 /** | |
778 * @param {number} x | |
779 * @param {number} y | |
780 * @return {?Node} | |
781 */ | |
782 Document.prototype.deepElementFromPoint = function(x, y) | |
783 { | |
784 var node = this.elementFromPoint(x, y); | |
785 while (node && node.shadowRoot) | |
786 node = node.shadowRoot.elementFromPoint(x, y); | |
787 return node; | |
788 } | |
789 | |
790 /** | |
744 * @return {boolean} | 791 * @return {boolean} |
745 */ | 792 */ |
746 function isEnterKey(event) { | 793 function isEnterKey(event) { |
747 // Check if in IME. | 794 // Check if in IME. |
748 return event.keyCode !== 229 && event.keyIdentifier === "Enter"; | 795 return event.keyCode !== 229 && event.keyIdentifier === "Enter"; |
749 } | 796 } |
750 | 797 |
751 function consumeEvent(e) | 798 function consumeEvent(e) |
752 { | 799 { |
753 e.consume(); | 800 e.consume(); |
754 } | 801 } |
OLD | NEW |