1/* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5("use strict"); 6 7const EXPORTED_SYMBOLS = [ 8 "EventDispatcher", 9 "MarionetteEventsParent", 10 "registerEventsActor", 11 "unregisterEventsActor", 12]; 13 14const { XPCOMUtils } = ChromeUtils.import( 15 "resource://gre/modules/XPCOMUtils.jsm" 16); 17 18XPCOMUtils.defineLazyModuleGetters(this, { 19 EventEmitter: "resource://gre/modules/EventEmitter.jsm", 20 Log: "chrome://remote/content/shared/Log.jsm", 21}); 22 23XPCOMUtils.defineLazyGetter(this, "logger", () => 24 Log.get(Log.TYPES.MARIONETTE) 25); 26 27// Singleton to allow forwarding events to registered listeners. 28const EventDispatcher = { 29 init() { 30 EventEmitter.decorate(this); 31 }, 32}; 33EventDispatcher.init(); 34 35class MarionetteEventsParent extends JSWindowActorParent { 36 async receiveMessage(msg) { 37 const { name, data } = msg; 38 39 let rv; 40 switch (name) { 41 case "MarionetteEventsChild:PageLoadEvent": 42 EventDispatcher.emit("page-load", data); 43 break; 44 } 45 46 return rv; 47 } 48} 49 50/** 51 * Register Events actors to listen for page load events via EventDispatcher. 52 */ 53function registerEventsActor() { 54 try { 55 // Register the JSWindowActor pair for events as used by Marionette 56 ChromeUtils.registerWindowActor("MarionetteEvents", { 57 kind: "JSWindowActor", 58 parent: { 59 moduleURI: 60 "chrome://remote/content/marionette/actors/MarionetteEventsParent.jsm", 61 }, 62 child: { 63 moduleURI: 64 "chrome://remote/content/marionette/actors/MarionetteEventsChild.jsm", 65 events: { 66 beforeunload: { capture: true }, 67 DOMContentLoaded: { mozSystemGroup: true }, 68 hashchange: { mozSystemGroup: true }, 69 pagehide: { mozSystemGroup: true }, 70 pageshow: { mozSystemGroup: true }, 71 // popstate doesn't bubble, as such use capturing phase 72 popstate: { capture: true, mozSystemGroup: true }, 73 74 click: {}, 75 dblclick: {}, 76 unload: { capture: true, createActor: false }, 77 }, 78 }, 79 80 allFrames: true, 81 includeChrome: true, 82 }); 83 } catch (e) { 84 if (e.name === "NotSupportedError") { 85 logger.warn(`MarionetteEvents actor is already registered!`); 86 } else { 87 throw e; 88 } 89 } 90} 91 92function unregisterEventsActor() { 93 ChromeUtils.unregisterWindowActor("MarionetteEvents"); 94} 95