<!DOCTYPE HTML> <html> <!-- https://bugzilla.mozilla.org/show_bug.cgi?id=887541 --> <head> <title>Test for event model in web components</title> <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> </head> <body> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=887541">Bug 887541</a> <script> var els = SpecialPowers.Cc["@mozilla.org/eventlistenerservice;1"] .getService(SpecialPowers.Ci.nsIEventListenerService); function eventListener(e) { eventChain.push(this); } function isEventChain(actual, expected, msg) { is(actual.length, expected.length, msg); for (var i = 0; i < expected.length; i++) { is(actual[i], expected[i], msg + " at " + i); } // Check to make sure the event chain matches what we get back from nsIEventListenerService.getEventTargetChainFor if (0 < actual.length) { var chain = els.getEventTargetChainFor(actual[0], true); // Events should be dispatched on actual[0]. for (var i = 0; i < expected.length; i++) { ok(SpecialPowers.compare(chain[i], expected[i]), msg + " at " + i + " for nsIEventListenerService"); } } } /* * Test 1: Test of event dispatch through a basic ShadowRoot with content a insertion point. * * <div elemOne> ------ <shadow-root shadowOne> * | | * <div elemTwo> <span elemThree> * | * <content elemFour> */ var elemOne = document.createElement("div"); elemOne.addEventListener("custom", eventListener); var elemTwo = document.createElement("div"); elemTwo.addEventListener("custom", eventListener); var elemThree = document.createElement("span"); elemThree.addEventListener("custom", eventListener); var elemFour = document.createElement("content"); elemFour.addEventListener("custom", eventListener); var shadowOne = elemOne.createShadowRoot(); shadowOne.addEventListener("custom", eventListener); elemThree.appendChild(elemFour); shadowOne.appendChild(elemThree); elemOne.appendChild(elemTwo); var eventChain = []; var customEvent = new CustomEvent("custom", { "bubbles" : true, "composed" : true }); elemTwo.dispatchEvent(customEvent); isEventChain(eventChain, [elemTwo, elemFour, elemThree, shadowOne, elemOne], "Event path for test 1 for event dispatched on elemTwo."); /* * Test 2: Test of event dispatch through a nested ShadowRoots with content insertion points. * * <div elemFive> --- <shadow-root shadowTwo> * | | * <div elemOne> <div elemFour> ----- <shadow-root shadowOne> * | | * <content elemTwo> <p elemSix> * | * <content elemThree> */ elemOne = document.createElement("div"); elemOne.addEventListener("custom", eventListener); elemTwo = document.createElement("content"); elemTwo.addEventListener("custom", eventListener); elemThree = document.createElement("content"); elemThree.addEventListener("custom", eventListener); var elemFour = document.createElement("div"); elemFour.addEventListener("custom", eventListener); var elemFive = document.createElement("div"); elemFive.addEventListener("custom", eventListener); var elemSix = document.createElement("p"); elemSix.addEventListener("custom", eventListener); var shadowOne = elemFour.createShadowRoot(); shadowOne.addEventListener("custom", eventListener); var shadowTwo = elemFive.createShadowRoot(); shadowTwo.addEventListener("custom", eventListener); elemFive.appendChild(elemOne); shadowTwo.appendChild(elemFour); elemFour.appendChild(elemTwo); shadowOne.appendChild(elemSix); elemSix.appendChild(elemThree); eventChain = []; customEvent = new CustomEvent("custom", { "bubbles" : true, "composed" : true }); elemOne.dispatchEvent(customEvent); is(elemOne.getDestinationInsertionPoints().length, 2, "yes"); isEventChain(eventChain, [elemOne, elemThree, elemSix, shadowOne, elemTwo, elemFour, shadowTwo, elemFive], "Event path for test 2 for event dispatched on elemOne."); /* * Test 3: Test of event dispatch through nested ShadowRoot with content insertion points. * * <div elemOne> ------- <shadow-root shadowOne> * | | * <span elemTwo> <span elemThree> ------------ <shadow-root shadowTwo> * | | * <span elemFour> <content elemSix> * | * <content elemFive> */ elemOne = document.createElement("div"); elemOne.addEventListener("custom", eventListener); elemTwo = document.createElement("span"); elemTwo.addEventListener("custom", eventListener); elemThree = document.createElement("span"); elemThree.addEventListener("custom", eventListener); elemFour = document.createElement("span"); elemFour.addEventListener("custom", eventListener); elemFive = document.createElement("content"); elemFive.addEventListener("custom", eventListener); elemSix = document.createElement("content"); elemSix.addEventListener("custom", eventListener); shadowOne = elemOne.createShadowRoot(); shadowOne.addEventListener("custom", eventListener); shadowTwo = elemThree.createShadowRoot(); shadowTwo.addEventListener("custom", eventListener); elemOne.appendChild(elemTwo); shadowOne.appendChild(elemThree); elemThree.appendChild(elemFour); elemFour.appendChild(elemFive); shadowTwo.appendChild(elemSix); eventChain = []; customEvent = new CustomEvent("custom", { "bubbles" : true, "composed" : true }); elemTwo.dispatchEvent(customEvent); isEventChain(eventChain, [elemTwo, elemFive, elemFour, elemSix, shadowTwo, elemThree, shadowOne, elemOne], "Event path for test 3 for event dispatched on elemTwo."); /* * Test 4: Test of event dispatch through host with multiple ShadowRoots with shadow insertion point. * * <div elemSeven> --- <shadow-root shadowTwo> (younger ShadowRoot) * | | | * <div elemOne> | <div elemSix> -------- <shadow-root shadowOne> * | | | * | <shadow elemFour> <content elemFive> * | | * | <content elemTwo> * | * --- <shadow-root shadowThree> (older ShadowRoot) * | | * | <content elemThree> * | * <div elemEight> */ elemOne = document.createElement("div"); elemOne.addEventListener("custom", eventListener); elemTwo = document.createElement("content"); elemTwo.addEventListener("custom", eventListener); elemThree = document.createElement("content"); elemThree.addEventListener("custom", eventListener); elemFour = document.createElement("shadow"); elemFour.addEventListener("custom", eventListener); elemFive = document.createElement("content"); elemFive.addEventListener("custom", eventListener); elemSix = document.createElement("div"); elemSix.addEventListener("custom", eventListener); var elemSeven = document.createElement("div"); elemSeven.addEventListener("custom", eventListener); var elemEight = document.createElement("div"); elemEight.addEventListener("custom", eventListener); var shadowThree = elemSeven.createShadowRoot(); shadowThree.addEventListener("custom", eventListener); shadowTwo = elemSeven.createShadowRoot(); shadowTwo.addEventListener("custom", eventListener); shadowOne = elemSix.createShadowRoot(); shadowOne.addEventListener("custom", eventListener); elemSeven.appendChild(elemOne); shadowTwo.appendChild(elemSix); elemSix.appendChild(elemFour); elemFour.appendChild(elemTwo); shadowThree.appendChild(elemEight); shadowThree.appendChild(elemThree); shadowOne.appendChild(elemFive); eventChain = []; customEvent = new CustomEvent("custom", { "bubbles" : true, "composed" : true }); elemOne.dispatchEvent(customEvent); isEventChain(eventChain, [elemOne, elemFive, shadowOne, elemThree, shadowThree, elemTwo, elemFour, elemSix, shadowTwo, elemSeven], "Event path for test 4 for event dispatched on elemOne."); eventChain = []; customEvent = new CustomEvent("custom", { "bubbles" : true, "composed" : true }); elemEight.dispatchEvent(customEvent); isEventChain(eventChain, [elemEight, elemFive, shadowOne, elemSix, shadowTwo, elemSeven], "Event path for test 4 for event dispatched on elemEight."); /* * Test 5: Test of event dispatch through nested shadowroot with insertion points that match specific tags. * * <div elemOne> --------- <shadow-root shadowOne> * | | | * | <p elemThree> <span elemFour> ------------------------ <shadow-root shadowTwo> * | | | | * <span elemTwo> | <content select="p" elemFive> <content elemSeven> * | * <content select="span" elemSix> */ elemOne = document.createElement("div"); elemOne.addEventListener("custom", eventListener); elemTwo = document.createElement("span"); elemTwo.addEventListener("custom", eventListener); elemThree = document.createElement("p"); elemThree.addEventListener("custom", eventListener); elemFour = document.createElement("span"); elemFour.addEventListener("custom", eventListener); elemFive = document.createElement("content"); elemFive.select = "p"; elemFive.addEventListener("custom", eventListener); elemSix = document.createElement("content"); elemSix.select = "span"; elemSix.addEventListener("custom", eventListener); elemSeven = document.createElement("content"); elemSeven.addEventListener("custom", eventListener); shadowTwo = elemFour.createShadowRoot(); shadowTwo.addEventListener("custom", eventListener); shadowOne = elemOne.createShadowRoot(); shadowOne.addEventListener("custom", eventListener); elemOne.appendChild(elemTwo); elemOne.appendChild(elemThree); shadowOne.appendChild(elemFour); elemFour.appendChild(elemSix); elemFour.appendChild(elemFive); shadowTwo.appendChild(elemSeven); eventChain = []; customEvent = new CustomEvent("custom", { "bubbles" : true, "composed" : true }); elemTwo.dispatchEvent(customEvent); isEventChain(eventChain, [elemTwo, elemSeven, shadowTwo, elemSix, elemFour, shadowOne, elemOne], "Event path for test 5 for event dispatched on elemTwo."); eventChain = []; customEvent = new CustomEvent("custom", { "bubbles" : true, "composed" : true }); elemThree.dispatchEvent(customEvent); isEventChain(eventChain, [elemThree, elemSeven, shadowTwo, elemFive, elemFour, shadowOne, elemOne], "Event path for test 5 for event dispatched on elemThree."); /* * Test 6: Test of event dispatch through nested shadowroot with insertion points that match specific tags. * * <div elemOne> --------- <shadow-root shadowOne>; * | | | * | <p elemThree> <span elemFour> ------ <shadow-root shadowTwo> * | | | | * <span elemTwo> <content elemFive> | <content select="p" elemSeven> * | * <content select="span" elemSix> */ elemOne = document.createElement("div"); elemOne.addEventListener("custom", eventListener); elemTwo = document.createElement("span"); elemTwo.addEventListener("custom", eventListener); elemThree = document.createElement("p"); elemThree.addEventListener("custom", eventListener); elemFour = document.createElement("span"); elemFour.addEventListener("custom", eventListener); elemFive = document.createElement("content"); elemFive.addEventListener("custom", eventListener); elemSix = document.createElement("content"); elemSix.select = "span"; elemSix.addEventListener("custom", eventListener); elemSeven = document.createElement("content"); elemSeven.select = "p"; elemSeven.addEventListener("custom", eventListener); shadowTwo = elemFour.createShadowRoot(); shadowTwo.addEventListener("custom", eventListener); shadowOne = elemOne.createShadowRoot(); shadowOne.addEventListener("custom", eventListener); elemOne.appendChild(elemTwo); elemOne.appendChild(elemThree); shadowOne.appendChild(elemFour); elemFour.appendChild(elemFive); shadowTwo.appendChild(elemSix); shadowTwo.appendChild(elemSeven); eventChain = []; customEvent = new CustomEvent("custom", { "bubbles" : true, "composed" : true }); elemTwo.dispatchEvent(customEvent); isEventChain(eventChain, [elemTwo, elemSix, shadowTwo, elemFive, elemFour, shadowOne, elemOne], "Event path for test 6 for event dispatched on elemTwo."); eventChain = []; customEvent = new CustomEvent("custom", { "bubbles" : true, "composed" : true }); elemThree.dispatchEvent(customEvent); isEventChain(eventChain, [elemThree, elemSeven, shadowTwo, elemFive, elemFour, shadowOne, elemOne], "Event path for test 6 for event dispatched on elemThree."); /* * Test 7: Test of event dispatch through nested shadowroot with insertion points that match specific tags. * * <div elemOne> --------- <shadow-root shadowOne> * | | | * | <p elemThree> <span elemFour> ------ <shadow-root shadowTwo> * | | | * <span elemTwo> <content elemFive> <span elemEight> * | | * | <content select="p" elemSeven> * | * <content select="span" elemSix> */ elemOne = document.createElement("div"); elemOne.addEventListener("custom", eventListener); elemTwo = document.createElement("span"); elemTwo.addEventListener("custom", eventListener); elemThree = document.createElement("p"); elemThree.addEventListener("custom", eventListener); elemFour = document.createElement("span"); elemFour.addEventListener("custom", eventListener); elemFive = document.createElement("content"); elemFive.addEventListener("custom", eventListener); elemSix = document.createElement("content"); elemSix.select = "span"; elemSix.addEventListener("custom", eventListener); elemSeven = document.createElement("content"); elemSeven.select = "p"; elemSeven.addEventListener("custom", eventListener); elemEight = document.createElement("span"); elemEight.addEventListener("custom", eventListener); shadowTwo = elemFour.createShadowRoot(); shadowTwo.addEventListener("custom", eventListener); shadowOne = elemOne.createShadowRoot(); shadowOne.addEventListener("custom", eventListener); elemOne.appendChild(elemTwo); elemOne.appendChild(elemThree); shadowOne.appendChild(elemFour); elemFour.appendChild(elemFive); shadowTwo.appendChild(elemEight); elemEight.appendChild(elemSix); elemEight.appendChild(elemSeven); eventChain = []; customEvent = new CustomEvent("custom", { "bubbles" : true, "composed" : true }); elemTwo.dispatchEvent(customEvent); isEventChain(eventChain, [elemTwo, elemSix, elemEight, shadowTwo, elemFive, elemFour, shadowOne, elemOne], "Event path for test 7 for event dispatched on elemTwo."); eventChain = []; customEvent = new CustomEvent("custom", { "bubbles" : true, "composed" : true }); elemThree.dispatchEvent(customEvent); isEventChain(eventChain, [elemThree, elemSeven, elemEight, shadowTwo, elemFive, elemFour, shadowOne, elemOne], "Event path for test 7 for event dispatched on elemThree."); /* * Test 8: Test of event dispatch through host with multiple ShadowRoots with shadow insertion point. * * <div elemOne> --- <shadow-root shadowOne> (younger ShadowRoot) * | | * | <div elemFour> * | | * | <shadow elemTwo> * | * --- <shadow-root shadowTwo> (older ShadowRoot) * | * <div elemThree> */ elemOne = document.createElement("div"); elemOne.addEventListener("custom", eventListener); elemTwo = document.createElement("shadow"); elemTwo.addEventListener("custom", eventListener); elemThree = document.createElement("div"); elemThree.addEventListener("custom", eventListener); elemFour = document.createElement("div"); elemFour.addEventListener("custom", eventListener); shadowTwo = elemOne.createShadowRoot(); shadowTwo.addEventListener("custom", eventListener); shadowOne = elemOne.createShadowRoot(); shadowOne.addEventListener("custom", eventListener); shadowOne.appendChild(elemFour); elemFour.appendChild(elemTwo); shadowTwo.appendChild(elemThree); eventChain = []; customEvent = new CustomEvent("custom", { "bubbles" : true, "composed" : true }); elemThree.dispatchEvent(customEvent); isEventChain(eventChain, [elemThree, shadowTwo, elemTwo, elemFour, shadowOne, elemOne], "Event path for test 8 for event dispatched on elemThree."); </script> </body> </html>