Closed Bug 1059989 Opened 10 years ago Closed 4 years ago

Tweak event propagation in shadow dom

Categories

(Core :: DOM: Events, defect, P5)

29 Branch
x86_64
Linux
defect

Tracking

()

RESOLVED DUPLICATE of bug 1492446

People

(Reporter: smaug, Unassigned)

Details

Attachments

(4 files, 1 obsolete file)

https://bugzilla.mozilla.org/show_bug.cgi?id=887541#c13

    2. If CURRENT is a shadow root:
        1. If INSERTION-POINTS is not empty:
            1. Pop INSERTION-POINTS and set CURRENT to be the popped node.
        2. Otherwise:
            1. Let SHADOW-HOST be the shadow host which hosts CURRENT
            2. If SHADOW-HOST hosts the node tree which NODE participates in and EVENT is one of the events which must be stopped:
                1. Stop this algorithm
            3. If CURRENT is not the youngest shadow root hosted by SHADOW-HOST:
                1. Let SHADOW-INSERTION-POINT be the shadow insertion point into which CURRENT shadow root is projected.
                2. Set CURRENT to SHADOW-INSERTION-POINT.
            4. Otherwise set CURRENT to SHADOW-HOST.


that misses the case when we have insertion points in the stack, but there another shadow dom tree between shadow root and
and that insertion point.

(2014/08/28)
http://w3c.github.io/webcomponents/spec/shadow/#event-paths-example
N->K-J-I-H
We end up missing K and J
Attached patch wip (obsolete) — Splinter Review
I feel that this is still missing some case if there several shadow roots in
the same host
Attached patch wip2Splinter Review
Using SubtreeRoot and not parent.
But William, since I don't know what the distribution algorithm will look like in the spec, this may need tweaking.


Input
    NODE, a node
    EVENT, an event
Output
    PATH, an event path, a ordered list of an event target

1. Let PATH be the empty ordered list of nodes
2. Let CURRENT be NODE
3. Let INSERTION-POINTS be an empty stack of nodes.
4. Add CURRENT to PATH
5. Repeat while CURRENT exists:
    1. If the destination insertion points of CURRENT is not empty:
        1. Push the destination insertion points into INSERTION-POINTS in order of first destination to final destination, excluding shadow insertion points.
        2. Let LAST-PUSHED-INSERTION-POINT be the last node in the destination insertion points of CURRENT to be pushed into INSERTION-POINTS
        2. If LAST-PUSHED-INSERTION-POINT exists:
            1. Pop INSERTION-POINTS and set CURRENT to be the popped node.
    2. Otherwise if CURRENT is a shadow root:
        1. Let SHADOW-POOL-HOST be the shadow host which hosts CURRENT
        2. If SHADOW-POOL-HOST hosts the node tree which NODE participates in and EVENT is one of the events which must be stopped:
            1. Stop this algorithm
        3. If CURRENT is not the youngest shadow root hosted by SHADOW-POOL-HOST:
            1. Let SHADOW-POOL-HOST be the shadow insertion point into which CURRENT shadow root is projected.
        4. If INSERTION-POINTS is not empty:
            1. If the most recent node in the INSERTION-POINTS is in the same node tree as SHADOW-POOL-HOST:
                1. Pop INSERTION-POINTS and set CURRENT to be the popped node.
        5. Otherwise:
            1. Set CURRENT to SHADOW-POOL-HOST
    3. Otherwise:
        1. Let CURRENT be the parent node of CURRENT.
    4. If CURRENT exists:
        1. Add CURRENT to PATH.
Attachment #8480810 - Attachment is obsolete: true
Attached file a testcase
Flags: needinfo?(wchen)
The change looks right to me. Steps 4 and step 4.1 in the algorithm should be combined to match up with step 5.
Flags: needinfo?(wchen)
Ah yes, since we want to execute 5 if 4 or 4.1 is false.
Input
    NODE, a node
    EVENT, an event
Output
    PATH, an event path, a ordered list of an event target

1. Let PATH be the empty ordered list of nodes
2. Let CURRENT be NODE
3. Let INSERTION-POINTS be an empty stack of nodes.
4. Add CURRENT to PATH
5. Repeat while CURRENT exists:
    1. If the destination insertion points of CURRENT is not empty:
        1. Push the destination insertion points into INSERTION-POINTS in order of first destination to final destination, excluding shadow insertion points.
        2. Let LAST-PUSHED-INSERTION-POINT be the last node in the destination insertion points of CURRENT to be pushed into INSERTION-POINTS
        2. If LAST-PUSHED-INSERTION-POINT exists:
            1. Pop INSERTION-POINTS and set CURRENT to be the popped node.
    2. Otherwise if CURRENT is a shadow root:
        1. Let SHADOW-POOL-HOST be the shadow host which hosts CURRENT
        2. If SHADOW-POOL-HOST hosts the node tree which NODE participates in and EVENT is one of the events which must be stopped:
            1. Stop this algorithm
        3. If CURRENT is not the youngest shadow root hosted by SHADOW-POOL-HOST:
            1. Let SHADOW-POOL-HOST be the shadow insertion point into which CURRENT shadow root is projected.
        4. If INSERTION-POINTS is not empty and
           if the most recent node in the INSERTION-POINTS is in the same node tree as SHADOW-POOL-HOST:
            1. Pop INSERTION-POINTS and set CURRENT to be the popped node.
        5. Otherwise:
            1. Set CURRENT to SHADOW-POOL-HOST
    3. Otherwise:
        1. Let CURRENT be the parent node of CURRENT.
    4. If CURRENT exists:
        1. Add CURRENT to PATH.
The patch does break test_event_dispatch.html Test 4. Looking at that now.
Need to play with older shadow root here, not only shadow host.
The algorithm would work if step 4 was adjusted to something like "if any of the nodes in INSERTION-POINTS are in the same node tree as SHADOW-POOL-HOST", but this might not be so nice on the implementation side because we probably don't want to iterate through the nodes in INSERTION-POINTS.

The current step would work if we kept shadow insertion points in step 5.1.1, but that would break other things. The last node in INSERTION-POINTS would otherwise be enough information to determine if we should step out of the shadow root or pop the stack, but we throw shadow insertion points away right now. We could change to algorithm to be able to handle having shadow insertion points in INSERTION-POINTS and just always pop the stack until a content insertion point or empty.
Attached patch wip v3Splinter Review
Multiple shadow roots and shadow insertion points make things pretty tricky. I tweaked the algorithm a bit more so that we put shadow insertion points in INSERTION-POINTS, but when nodes are added to the event path, we replace them with either the shadow root that is projected into the insertion point or replace with the next node in INSERTION-POINTS if it's in the same node tree.

The proposed algorithm looks like this:

Input
    NODE, a node
    EVENT, an event
Output
    PATH, an event path, a ordered list of an event target

1. Let PATH be the empty ordered list of nodes
2. Let CURRENT be NODE
3. Let INSERTION-POINTS be an empty stack of nodes.
4. Add CURRENT to PATH
5. Repeat while CURRENT exists:
    1. If the destination insertion points of CURRENT is not empty:
        1. Push the destination insertion points into INSERTION-POINTS in order of first destination to final destination.
        2. Pop INSERTION-POINTS and set CURRENT to be the popped node.
    2. Otherwise if CURRENT is a shadow root:
        1. Let SHADOW-POOL-HOST be the shadow host which hosts CURRENT
        2. If SHADOW-POOL-HOST hosts the node tree which NODE participates in and EVENT is one of the events which must be stopped:
            1. Stop this algorithm
        3. If CURRENT is not the youngest shadow root hosted by SHADOW-POOL-HOST:
            1. Let SHADOW-POOL-HOST be the shadow insertion point into which CURRENT shadow root is projected.
        4. If INSERTION-POINTS is not empty and if the most recent node in the INSERTION-POINTS is in the same node tree as SHADOW-POOL-HOST:
            1. Pop INSERTION-POINTS and set CURRENT to be the popped node.
        5. Otherwise:
            1. Set CURRENT to SHADOW-POOL-HOST and skip step 4
    3. Otherwise:
        1. Let CURRENT be the parent node of CURRENT.
    4. Repeat while CURRENT is a shadow insertion point.
        1. Let PROJECTED-SHADOW be the shadow root projected into CURRENT.
        2. If INSERTION-POINTS is not empty and if the most recent node in the INSERTION-POINTS is in the same node tree as PROJECTED-SHADOW:
            1. Pop INSERTION-POINTS and set CURRENT to be the popped node.
        3. Otherwise:
            1. Set CURRENT to PROJECTED-SHADOW.
    5. If CURRENT exists:
        1. Add CURRENT to PATH.

The main change is the addition of step 4. I also updated the WIP and it fixes the test failure. It also fixes another issue in test 4 where the current algorithm loses a node in the event path.
https://bugzilla.mozilla.org/show_bug.cgi?id=1472046

Move all DOM bugs that haven't been updated in more than 3 years and has no one currently assigned to P5.

If you have questions, please contact :mdaly.
Priority: -- → P5
Status: NEW → RESOLVED
Closed: 4 years ago
Resolution: --- → DUPLICATE
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: