| OLD | NEW |
| (Empty) | |
| 1 <!DOCTYPE html> |
| 2 <html> |
| 3 <head> |
| 4 <title>Shadow DOM: Extensions to Event Interface</title> |
| 5 <meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"> |
| 6 <meta name="assert" content="Event interface must have composedPath() as a metho
d"> |
| 7 <link rel="help" href="http://w3c.github.io/webcomponents/spec/shadow/#extension
s-to-event-interface"> |
| 8 <script src="/resources/testharness.js"></script> |
| 9 <script src="/resources/testharnessreport.js"></script> |
| 10 <script src="resources/event-path-test-helpers.js"></script> |
| 11 </head> |
| 12 <body> |
| 13 <div id="log"></div> |
| 14 <script> |
| 15 |
| 16 test(function () { |
| 17 assert_true('composedPath' in Event.prototype); |
| 18 assert_true('composedPath' in new Event('my-event')); |
| 19 }, 'composedPath() must exist on Event'); |
| 20 |
| 21 test(function () { |
| 22 var event = new Event('my-event'); |
| 23 assert_array_equals(event.composedPath(), []); |
| 24 }, 'composedPath() must return an empty array when the event has not been dispat
ched'); |
| 25 |
| 26 test(function () { |
| 27 var event = new Event('my-event'); |
| 28 document.body.dispatchEvent(event); |
| 29 assert_array_equals(event.composedPath(), []); |
| 30 }, 'composedPath() must return an empty array when the event is no longer dispat
ched'); |
| 31 |
| 32 test(function () { |
| 33 assert_true('composed' in Event.prototype); |
| 34 assert_true('composed' in new Event('my-event')); |
| 35 }, 'composed must exist on Event'); |
| 36 |
| 37 test(function () { |
| 38 var event = new Event('my-event'); |
| 39 assert_false(event.composed); |
| 40 }, 'composed on EventInit must default to false'); |
| 41 |
| 42 test(function () { |
| 43 var event = new Event('my-event', {composed: true}); |
| 44 assert_true(event.composed); |
| 45 |
| 46 event = new Event('my-event', {composed: false}); |
| 47 assert_false(event.composed); |
| 48 }, 'composed on EventInit must set the composed flag'); |
| 49 |
| 50 /* |
| 51 -SR: ShadowRoot -S: Slot target: (~) *: indicates start digit: event path or
der |
| 52 A (4) --------------------------- A-SR (3) |
| 53 + B ------------ B-SR + A1 (2) --- A1-SR (1) |
| 54 + C + B1 --- B1-SR + A2-S + A1a (*; 0) |
| 55 + D --- D-SR + B1a + B1b --- B1b-SR |
| 56 + D1 + B1c-S + B1b1 |
| 57 + B1b2 |
| 58 */ |
| 59 |
| 60 function testComposedEvent(mode) { |
| 61 test(function () { |
| 62 var nodes = createTestTree(mode); |
| 63 var log = dispatchEventWithLog(nodes, nodes.A1a, new Event('my-event', {
composed: true, bubbles: true})); |
| 64 |
| 65 var expectedPath = ['A1a', 'A1-SR', 'A1', 'A-SR', 'A']; |
| 66 assert_array_equals(log.eventPath, expectedPath); |
| 67 assert_array_equals(log.eventPath.length, log.pathAtTargets.length); |
| 68 assert_array_equals(log.pathAtTargets[0], expectedPath); |
| 69 assert_array_equals(log.pathAtTargets[1], expectedPath); |
| 70 assert_array_equals(log.pathAtTargets[2], mode == 'open' ? expectedPath
: ['A1', 'A-SR', 'A'], |
| 71 'composedPath must only contain unclosed nodes of the current target
.'); |
| 72 }, 'The event must propagate out of ' + mode + ' mode shadow boundaries when
the composed flag is set'); |
| 73 } |
| 74 |
| 75 testComposedEvent('open'); |
| 76 testComposedEvent('closed'); |
| 77 |
| 78 /* |
| 79 -SR: ShadowRoot -S: Slot target: (~) *: indicates start digit: event path or
der |
| 80 A ------------------------------- A-SR |
| 81 + B ------------ B-SR + A1 --- A1-SR (1) |
| 82 + C + B1 --- B1-SR + A2-S + A1a (*; 0) |
| 83 + D --- D-SR + B1a + B1b --- B1b-SR |
| 84 + D1 + B1c-S + B1b1 |
| 85 + B1b2 |
| 86 */ |
| 87 |
| 88 function testNonComposedEvent(mode) { |
| 89 test(function () { |
| 90 var nodes = createTestTree(mode); |
| 91 var log = dispatchEventWithLog(nodes, nodes.A1a, new Event('my-event', {
composed: false, bubbles: true})); |
| 92 |
| 93 var expectedPath = ['A1a', 'A1-SR']; |
| 94 assert_array_equals(log.eventPath, expectedPath); |
| 95 assert_array_equals(log.eventPath.length, log.pathAtTargets.length); |
| 96 assert_array_equals(log.pathAtTargets[0], expectedPath); |
| 97 assert_array_equals(log.pathAtTargets[1], expectedPath); |
| 98 }, 'The event must not propagate out of ' + mode + ' mode shadow boundaries
when the composed flag is unset'); |
| 99 } |
| 100 |
| 101 testNonComposedEvent('open'); |
| 102 testNonComposedEvent('closed'); |
| 103 |
| 104 /* |
| 105 -SR: ShadowRoot -S: Slot target: (~) relatedTarget: [~] *: indicates start
digit: event path order |
| 106 A ------------------------------- A-SR |
| 107 + B ------------ B-SR + A1 ----------- A1-SR (1) |
| 108 + C + B1 --- B1-SR + A2-S [*; 0-1] + A1a (*; 0) |
| 109 + D --- D-SR + B1a + B1b --- B1b-SR |
| 110 + D1 + B1c-S + B1b1 |
| 111 + B1b2 |
| 112 */ |
| 113 |
| 114 function testNonComposedEventWithRelatedTarget(mode) { |
| 115 test(function () { |
| 116 var nodes = createTestTree(mode); |
| 117 var log = dispatchEventWithLog(nodes, nodes.A1a, new MouseEvent('foo', {
composed: false, bubbles: true, relatedTarget: nodes['A2-S']})); |
| 118 |
| 119 var expectedPath = ['A1a', 'A1-SR']; |
| 120 assert_array_equals(log.eventPath, expectedPath); |
| 121 assert_array_equals(log.eventPath.length, log.pathAtTargets.length); |
| 122 assert_array_equals(log.pathAtTargets[0], expectedPath); |
| 123 assert_array_equals(log.pathAtTargets[1], expectedPath); |
| 124 assert_array_equals(log.relatedTargets, ['A2-S', 'A2-S']); |
| 125 }, 'The event must not propagate out of ' + mode + ' mode shadow boundaries
when the composed flag is unset on an event with relatedTarget'); |
| 126 } |
| 127 |
| 128 testNonComposedEventWithRelatedTarget('open'); |
| 129 testNonComposedEventWithRelatedTarget('closed'); |
| 130 |
| 131 /* |
| 132 -SR: ShadowRoot -S: Slot target: (~) relatedTarget: [~] *: indicates start
digit: event path order |
| 133 A ------------------------------------------------ A-SR |
| 134 + B ------------ B-SR (4) + A1 --- A1-SR |
| 135 + C + B1 (3) [0,3-4] --- B1-SR (2) + A2-S + A1a |
| 136 + D --- D-SR + B1a (*; 0) + B1b [1-2] --- B1b-SR |
| 137 + D1 + B1c-S (1) + B1b1 |
| 138 + B1b2 [*] |
| 139 */ |
| 140 |
| 141 function testScopedEventWithUnscopedRelatedTargetThroughSlot(mode) { |
| 142 test(function () { |
| 143 var nodes = createTestTree(mode); |
| 144 var log = dispatchEventWithLog(nodes, nodes.B1a, new MouseEvent('foo', {
scoped: true, relatedTargetScoped: false, bubbles: true, relatedTarget: nodes['B
1b2']})); |
| 145 |
| 146 var expectedPath = ['B1a', 'B1c-S', 'B1-SR', 'B1', 'B-SR']; |
| 147 var pathExposedToB1a = ['B1a', 'B1', 'B-SR']; |
| 148 assert_array_equals(log.eventPath, expectedPath); |
| 149 assert_array_equals(log.eventPath.length, log.pathAtTargets.length); |
| 150 assert_array_equals(log.pathAtTargets[0], mode == 'open' ? expectedPath
: pathExposedToB1a); |
| 151 assert_array_equals(log.pathAtTargets[1], expectedPath); |
| 152 assert_array_equals(log.pathAtTargets[2], expectedPath); |
| 153 assert_array_equals(log.pathAtTargets[3], mode == 'open' ? expectedPath
: pathExposedToB1a); |
| 154 assert_array_equals(log.pathAtTargets[4], mode == 'open' ? expectedPath
: pathExposedToB1a); |
| 155 assert_array_equals(log.relatedTargets, ['B1', 'B1b', 'B1b', 'B1', 'B1']
); |
| 156 }, 'The event must not propagate out of ' + mode + ' mode shadow tree of the
target but must propagate out of inner shadow trees when the scoped flag is set
'); |
| 157 } |
| 158 |
| 159 testScopedEventWithUnscopedRelatedTargetThroughSlot('open'); |
| 160 testScopedEventWithUnscopedRelatedTargetThroughSlot('closed'); |
| 161 |
| 162 /* |
| 163 -SR: ShadowRoot -S: Slot target: (~) relatedTarget: [~] *: indicates start
digit: event path order |
| 164 A ------------------------------- A-SR (3) |
| 165 + B ------------ B-SR + A1 (2) ------- A1-SR (1) |
| 166 + C + B1 --- B1-SR + A2-S [*; 0-3] + A1a (*; 0) |
| 167 + D --- D-SR + B1a + B1b --- B1b-SR |
| 168 + D1 + B1c-S + B1b1 |
| 169 + B1b2 |
| 170 */ |
| 171 |
| 172 function testComposedEventWithRelatedTarget(mode) { |
| 173 test(function () { |
| 174 var nodes = createTestTree(mode); |
| 175 log = dispatchEventWithLog(nodes, nodes.A1a, new MouseEvent('foo', {comp
osed: true, bubbles: true, relatedTarget: nodes['A2-S']})); |
| 176 |
| 177 var expectedPath = ['A1a', 'A1-SR', 'A1', 'A-SR']; |
| 178 var pathExposedToA1 = ['A1', 'A-SR']; |
| 179 assert_array_equals(log.eventPath, expectedPath); |
| 180 assert_array_equals(log.eventPath.length, log.pathAtTargets.length); |
| 181 assert_array_equals(log.pathAtTargets[0], expectedPath); |
| 182 assert_array_equals(log.pathAtTargets[1], expectedPath); |
| 183 assert_array_equals(log.pathAtTargets[2], mode == 'open' ? expectedPath
: pathExposedToA1); |
| 184 assert_array_equals(log.pathAtTargets[3], mode == 'open' ? expectedPath
: pathExposedToA1); |
| 185 assert_array_equals(log.relatedTargets, ['A2-S', 'A2-S', 'A2-S', 'A2-S']
); |
| 186 }, 'The event must propagate out of ' + mode + ' mode shadow tree in which t
he relative target and the relative related target are the same'); |
| 187 } |
| 188 |
| 189 testComposedEventWithRelatedTarget('open'); |
| 190 testComposedEventWithRelatedTarget('closed'); |
| 191 |
| 192 /* |
| 193 -SR: ShadowRoot -S: Slot target: (~) relatedTarget: [~] *: indicates start
digit: event path order |
| 194 A (8) [0-5,8] ---------------------------------------- A-SR (7) |
| 195 + B (5) ------- B-SR (4) + A1 [6,7] --- A1-SR |
| 196 + C + B1 (3) ------- B1-SR (2) + A2-S (6) + A1a [*] |
| 197 + D --- D-SR + B1a (*; 0) + B1b ------- B1b-SR |
| 198 + D1 + B1c-S (1) + B1b1 |
| 199 + B1b2 |
| 200 */ |
| 201 |
| 202 function testComposedEventThroughSlot(mode) { |
| 203 test(function () { |
| 204 var nodes = createTestTree(mode); |
| 205 log = dispatchEventWithLog(nodes, nodes.B1a, new MouseEvent('foo', {comp
osed: true, bubbles: true, relatedTarget: nodes.A1a})); |
| 206 |
| 207 var expectedPath = ['B1a', 'B1c-S', 'B1-SR', 'B1', 'B-SR', 'B',
'A2-S', 'A-SR', 'A']; |
| 208 var expectedRelatedTarget = ['A', 'A', 'A', 'A', 'A', 'A',
'A1', 'A1', 'A']; |
| 209 var pathExposedToB1a = ['B1a', 'B1', 'B-SR', 'B',
'A']; |
| 210 var pathExposedToB1cS = ['B1a', 'B1c-S', 'B1-SR', 'B1', 'B-SR', 'B',
'A']; |
| 211 var pathExposedToB = [ 'B',
'A']; |
| 212 var pathExposedToA1 = [ 'B',
'A2-S', 'A-SR', 'A']; |
| 213 |
| 214 assert_array_equals(log.eventPath, expectedPath); |
| 215 assert_array_equals(log.eventPath.length, log.pathAtTargets.length); |
| 216 assert_array_equals(log.pathAtTargets[0], mode == 'open' ? expectedPath
: pathExposedToB1a); |
| 217 assert_array_equals(log.pathAtTargets[1], mode == 'open' ? expectedPath
: pathExposedToB1cS); |
| 218 assert_array_equals(log.pathAtTargets[2], mode == 'open' ? expectedPath
: pathExposedToB1cS); |
| 219 assert_array_equals(log.pathAtTargets[3], mode == 'open' ? expectedPath
: pathExposedToB1a); |
| 220 assert_array_equals(log.pathAtTargets[4], mode == 'open' ? expectedPath
: pathExposedToB1a); |
| 221 assert_array_equals(log.pathAtTargets[5], mode == 'open' ? expectedPath
: pathExposedToB); |
| 222 assert_array_equals(log.pathAtTargets[6], mode == 'open' ? expectedPath
: pathExposedToA1); |
| 223 assert_array_equals(log.pathAtTargets[7], mode == 'open' ? expectedPath
: pathExposedToA1); |
| 224 assert_array_equals(log.pathAtTargets[8], mode == 'open' ? expectedPath
: pathExposedToB); |
| 225 assert_array_equals(log.relatedTargets, expectedRelatedTarget); |
| 226 }, 'composedPath() must contain and only contain the unclosed nodes of targe
t in ' + mode + ' mode shadow trees'); |
| 227 } |
| 228 |
| 229 testComposedEventThroughSlot('open'); |
| 230 testComposedEventThroughSlot('closed'); |
| 231 |
| 232 </script> |
| 233 </body> |
| 234 </html> |
| OLD | NEW |