browser_canvasframe_helper_06.js (3773B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 // Test support for event propagation stop in the 7 // CanvasFrameAnonymousContentHelper event handling mechanism. 8 9 const TEST_URL = 10 "data:text/html;charset=utf-8,CanvasFrameAnonymousContentHelper test"; 11 12 add_task(async function () { 13 const tab = await addTab(TEST_URL); 14 await SpecialPowers.spawn(tab.linkedBrowser, [], async function () { 15 const { require } = ChromeUtils.importESModule( 16 "resource://devtools/shared/loader/Loader.sys.mjs" 17 ); 18 const { 19 HighlighterEnvironment, 20 } = require("resource://devtools/server/actors/highlighters.js"); 21 const { 22 CanvasFrameAnonymousContentHelper, 23 } = require("resource://devtools/server/actors/highlighters/utils/markup.js"); 24 const doc = content.document; 25 26 const nodeBuilder = () => { 27 const root = doc.createElement("div"); 28 29 const parent = doc.createElement("div"); 30 parent.style = 31 "pointer-events:auto;width:300px;height:300px;background:yellow;"; 32 parent.id = "parent-element"; 33 root.appendChild(parent); 34 35 const child = doc.createElement("div"); 36 child.style = 37 "pointer-events:auto;width:200px;height:200px;background:red;"; 38 child.id = "child-element"; 39 parent.appendChild(child); 40 41 return root; 42 }; 43 44 info("Building the helper"); 45 const env = new HighlighterEnvironment(); 46 env.initFromWindow(doc.defaultView); 47 const helper = new CanvasFrameAnonymousContentHelper(env, nodeBuilder); 48 await helper.initialize(); 49 50 info("Getting the parent and child elements"); 51 const parentEl = helper.getElement("parent-element"); 52 const childEl = helper.getElement("child-element"); 53 54 info("Adding an event listener on both elements"); 55 let mouseDownHandled = []; 56 57 function onParentMouseDown(e, id) { 58 mouseDownHandled.push(id); 59 } 60 parentEl.addEventListener("mousedown", onParentMouseDown); 61 62 function onChildMouseDown(e, id) { 63 mouseDownHandled.push(id); 64 e.stopPropagation(); 65 } 66 childEl.addEventListener("mousedown", onChildMouseDown); 67 68 function once(target, event) { 69 return new Promise(done => { 70 target.addEventListener(event, done, { once: true }); 71 }); 72 } 73 74 info("Synthesizing an event on the child element"); 75 let onDocMouseDown = once(doc, "mousedown"); 76 synthesizeMouseDown(100, 100, doc.defaultView); 77 await onDocMouseDown; 78 79 is(mouseDownHandled.length, 1, "The mousedown event was handled only once"); 80 is( 81 mouseDownHandled[0], 82 "child-element", 83 "The mousedown event was handled on the child element" 84 ); 85 86 info("Synthesizing an event on the parent, outside of the child element"); 87 mouseDownHandled = []; 88 onDocMouseDown = once(doc, "mousedown"); 89 synthesizeMouseDown(250, 250, doc.defaultView); 90 await onDocMouseDown; 91 92 is(mouseDownHandled.length, 1, "The mousedown event was handled only once"); 93 is( 94 mouseDownHandled[0], 95 "parent-element", 96 "The mousedown event was handled on the parent element" 97 ); 98 99 info("Removing the event listener"); 100 parentEl.removeEventListener("mousedown", onParentMouseDown); 101 childEl.removeEventListener("mousedown", onChildMouseDown); 102 103 env.destroy(); 104 helper.destroy(); 105 106 function synthesizeMouseDown(x, y, win) { 107 // We need to make sure the inserted anonymous content can be targeted by the 108 // event right after having been inserted, and so we need to force a sync 109 // reflow. 110 win.document.documentElement.offsetWidth; 111 EventUtils.synthesizeMouseAtPoint(x, y, { type: "mousedown" }, win); 112 } 113 }); 114 115 gBrowser.removeCurrentTab(); 116 });