|
656 | 656 | } |
657 | 657 | }, |
658 | 658 | dispatchEvent: function(event) { |
659 | | - dispatchEvent(event, this); |
| 659 | + // We want to use the native dispatchEvent because it triggers the default |
| 660 | + // actions (like checking a checkbox). However, if there are no listeners |
| 661 | + // in the composed tree then there are no events that will trigger and |
| 662 | + // listeners in the non composed tree that are part of the event path are |
| 663 | + // not notified. |
| 664 | + // |
| 665 | + // If we find out that there are no listeners in the composed tree we add |
| 666 | + // a temporary listener to the target which makes us get called back even |
| 667 | + // in that case. |
| 668 | + |
| 669 | + var nativeEvent = unwrap(event); |
| 670 | + var eventType = nativeEvent.type; |
| 671 | + |
| 672 | + // Allow dispatching the same event again. This is safe because if user |
| 673 | + // code calls this during an existing dispatch of the same event the |
| 674 | + // native dispatchEvent throws (that is required by the spec). |
| 675 | + handledEventsTable.set(nativeEvent, false); |
| 676 | + |
| 677 | + // Force rendering since we prefer native dispatch and that works on the |
| 678 | + // composed tree. |
| 679 | + scope.renderAllPending(); |
| 680 | + |
| 681 | + var tempListener; |
| 682 | + if (!hasListenerInAncestors(this, eventType)) { |
| 683 | + tempListener = function() {}; |
| 684 | + this.addEventListener(eventType, tempListener, true); |
| 685 | + } |
| 686 | + |
| 687 | + try { |
| 688 | + return unwrap(this).dispatchEvent_(nativeEvent); |
| 689 | + } finally { |
| 690 | + if (tempListener) |
| 691 | + this.removeEventListener(eventType, tempListener, true); |
| 692 | + } |
660 | 693 | } |
661 | 694 | }; |
662 | 695 |
|
| 696 | + function hasListener(node, type) { |
| 697 | + var listeners = listenersTable.get(node); |
| 698 | + if (listeners) { |
| 699 | + for (var i = 0; i < listeners.length; i++) { |
| 700 | + if (!listeners[i].removed && listeners[i].type === type) |
| 701 | + return true; |
| 702 | + } |
| 703 | + } |
| 704 | + return false; |
| 705 | + } |
| 706 | + |
| 707 | + function hasListenerInAncestors(target, type) { |
| 708 | + for (var node = unwrap(target); node; node = node.parentNode) { |
| 709 | + if (hasListener(wrap(node), type)) |
| 710 | + return true; |
| 711 | + } |
| 712 | + return false; |
| 713 | + } |
| 714 | + |
663 | 715 | if (OriginalEventTarget) |
664 | 716 | registerWrapper(OriginalEventTarget, EventTarget); |
665 | 717 |
|
|
0 commit comments