ergedEvents = {}; const mergeEvents = event => { if (event.type === "touchstart") { mergedEvents.touch = event; } else { mergedEvents.pointer = event; } // Resolve the promise if we got pointerdown if (mergedEvents.pointer) { resolve(mergedEvents); } }; promise.then(e => { const map = new Map([ ["pointerPressure", e.pointer.pressure], ["pointerTangentinalPressure", e.pointer.tangentialPressure], ["pointerTiltx", e.pointer.tiltX], ["pointerTilty", e.pointer.tiltY], ["pointerTwist", e.pointer.twist], ["pointerWidth", e.pointer.width], ["pointerHeight", e.pointer.height], ["touchRotationAngle", e.touch?.rotationAngle || 0], ]); this.sendMessage("PointerInfo:Populated", map); this.propertyCollected("PointerInfo"); }); this.handlers.touchstart = touchStartHandler; this.handlers.pointerdown = pointerDownHandler; if (Cu.isInAutomation) { // Just simulate the events if we are in automation const pointerEvent = new PointerEvent("pointerdown"); this.contentWindow.windowRoot.dispatchEvent(pointerEvent); } } sendMessage(name, obj, transferables) { if (this.destroyed) { return; } this.sendAsyncMessage(name, obj, transferables); } propertyCollected(name) { this.collectedProperties.add(name); if (this.targetProperties.difference(this.collectedProperties).size === 0) { this.sendMessage("WindowInfo::Done"); } } didDestroy() { this.destroyed = true; for (const [type, handler] of Object.entries(this.handlers)) { this.contentWindow?.windowRoot?.removeEventListener(type, handler); } } async receiveMessage(msg) { lazy.console.debug("Actor Child: Got ", msg.name); switch (msg.name) { case "WindowInfo:PopulateFromDocument": if (this.document.readyState == "complete") { this.populateScreenInfo(); this.populatePointerInfo(); } break; } return null; } async handleEvent(event) { lazy.console.debug("Actor Child: Got ", event.type); switch (event.type) { case "DOMContentLoaded": this.populateScreenInfo(); this.populatePointerInfo(); break; } } } PK