Skip to content

Commit

Permalink
Implement changes to event path iteration
Browse files Browse the repository at this point in the history
  • Loading branch information
Zirro authored and domenic committed May 12, 2019
1 parent 5146cb2 commit 3781125
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 34 deletions.
59 changes: 30 additions & 29 deletions lib/jsdom/living/events/EventTarget-impl.js
Expand Up @@ -170,47 +170,48 @@ class EventTargetImpl {
slotInClosedTree = false;
}

let clearTargetsTupleIndex = -1;
for (let i = eventImpl._path.length - 1; i >= 0 && clearTargetsTupleIndex === -1; i--) {
let clearTargetsStructIndex = -1;
for (let i = eventImpl._path.length - 1; i >= 0 && clearTargetsStructIndex === -1; i--) {
if (eventImpl._path[i].target !== null) {
clearTargetsTupleIndex = i;
clearTargetsStructIndex = i;
}
}
const clearTargetsTuple = eventImpl._path[clearTargetsTupleIndex];
const clearTargetsStruct = eventImpl._path[clearTargetsStructIndex];

clearTargets =
(isNode(clearTargetsTuple.target) && isShadowRoot(getRoot(clearTargetsTuple.target))) ||
(isNode(clearTargetsTuple.relatedTarget) && isShadowRoot(getRoot(clearTargetsTuple.relatedTarget)));

eventImpl.eventPhase = Event.CAPTURING_PHASE;
(isNode(clearTargetsStruct.target) && isShadowRoot(getRoot(clearTargetsStruct.target))) ||
(isNode(clearTargetsStruct.relatedTarget) && isShadowRoot(getRoot(clearTargetsStruct.relatedTarget)));

if (activationTarget !== null && activationTarget._legacyPreActivationBehavior) {
activationTarget._legacyPreActivationBehavior();
}

for (let i = eventImpl._path.length - 1; i >= 0; --i) {
const tuple = eventImpl._path[i];
const struct = eventImpl._path[i];

if (tuple.target === null) {
invokeEventListeners(tuple, eventImpl);
if (struct.target !== null) {
eventImpl.eventPhase = Event.AT_TARGET;
} else {
eventImpl.eventPhase = Event.CAPTURING_PHASE;
}

invokeEventListeners(struct, eventImpl, "capturing");
}

for (let i = 0; i < eventImpl._path.length; i++) {
const tuple = eventImpl._path[i];
const struct = eventImpl._path[i];

if (tuple.target !== null) {
if (struct.target !== null) {
eventImpl.eventPhase = Event.AT_TARGET;
} else {
if (!eventImpl.bubbles) {
continue;
}

eventImpl.eventPhase = Event.BUBBLING_PHASE;
}

if (
(eventImpl.eventPhase === Event.BUBBLING_PHASE && eventImpl.bubbles) ||
eventImpl.eventPhase === Event.AT_TARGET
) {
invokeEventListeners(tuple, eventImpl);
}
invokeEventListeners(struct, eventImpl, "bubbling");
}
}

Expand Down Expand Up @@ -244,30 +245,30 @@ module.exports = {
};

// https://dom.spec.whatwg.org/#concept-event-listener-invoke
function invokeEventListeners(tuple, eventImpl) {
const tupleIndex = eventImpl._path.indexOf(tuple);
for (let i = tupleIndex; i >= 0; i--) {
function invokeEventListeners(struct, eventImpl, phase) {
const structIndex = eventImpl._path.indexOf(struct);
for (let i = structIndex; i >= 0; i--) {
const t = eventImpl._path[i];
if (t.target) {
eventImpl.target = t.target;
break;
}
}

eventImpl.relatedTarget = idlUtils.wrapperForImpl(tuple.relatedTarget);
eventImpl.relatedTarget = idlUtils.wrapperForImpl(struct.relatedTarget);

if (eventImpl._stopPropagationFlag) {
return;
}

eventImpl.currentTarget = idlUtils.wrapperForImpl(tuple.item);
eventImpl.currentTarget = idlUtils.wrapperForImpl(struct.item);

const listeners = tuple.item._eventListeners;
innerInvokeEventListeners(eventImpl, listeners);
const listeners = struct.item._eventListeners;
innerInvokeEventListeners(eventImpl, listeners, phase, struct);
}

// https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke
function innerInvokeEventListeners(eventImpl, listeners) {
function innerInvokeEventListeners(eventImpl, listeners, phase) {
let found = false;

const { type, target } = eventImpl;
Expand All @@ -292,8 +293,8 @@ function innerInvokeEventListeners(eventImpl, listeners) {
found = true;

if (
(eventImpl.eventPhase === Event.CAPTURING_PHASE && !capture) ||
(eventImpl.eventPhase === Event.BUBBLING_PHASE && capture)
(phase === "capturing" && !capture) ||
(phase === "bubbling" && capture)
) {
continue;
}
Expand Down
2 changes: 1 addition & 1 deletion test/to-port-to-wpts/level2/events.js
Expand Up @@ -377,7 +377,7 @@ describe("level2/events", () => {
this.plist.addEventListener("foo", this.monitor.handleEvent, true);
this.plist.addEventListener("foo", this.monitor.handleEvent, false);
this.plist.dispatchEvent(this.event);
assert.equal(this.monitor.atEvents.length, 4, 'should be at 4 events');
assert.equal(this.monitor.atEvents.length, 2, 'should be at 2 events'); // Changed from 4 to 2 after https://github.com/whatwg/dom/commit/98564fc5284439d2555f545fa04288e230a37a03
assert.equal(this.monitor.bubbledEvents.length, 0, 'should have no bubbled events');
assert.equal(this.monitor.capturedEvents.length, 0, 'should have no captured events');
});
Expand Down
4 changes: 0 additions & 4 deletions test/web-platform-tests/to-run.yaml
Expand Up @@ -99,8 +99,6 @@ DIR: dom/collections

DIR: dom/events

Event-dispatch-handlers-changed.html: [fail, Unknown]
Event-dispatch-listener-order.window.html: [fail, Unknown]
Event-dispatch-on-disabled-elements.html: [timeout, Uses testdriver.js]
Event-isTrusted.any.html: [fail, Unknown]
Event-timestamp-high-resolution.html: [fail, Not implemented]
Expand Down Expand Up @@ -848,8 +846,6 @@ Element-interface-attachShadow-custom-element.html: [fail, CustomElement.define
MouseEvent-prototype-offsetX-offsetY.html: [fail, offsetTop not implemented]
Range-prototype-insertNode.html: [fail, Range is not implemented]
ShadowRoot-interface.html: [fail, shadowRoot.styleSheet and shadowRoot.activeElement are not yet implemented]
capturing-and-bubbling-event-listeners-across-shadow-trees.html: [fail, Unknown]
event-dispatch-order.tentative.html: [fail, Unknown]
form-control-form-attribute.html: [fail, Form association doesn't respect the spec]
leaktests/html-collection.html: [fail, Document.all is not implemented]
leaktests/window-frames.html: [fail, Window.name is not implemeneted]
Expand Down

0 comments on commit 3781125

Please sign in to comment.