Bug 1535487 - determine rootUrl directly in buglist creator r=tomprince
[gecko.git] / toolkit / actors / UAWidgetsChild.jsm
blob8b88bbb35b0b101739ca918841fb4982330bc34e
1 /* vim: set ts=2 sw=2 sts=2 et tw=80: */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 "use strict";
7 var EXPORTED_SYMBOLS = ["UAWidgetsChild"];
9 const {ActorChild} = ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
10 const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
12 class UAWidgetsChild extends ActorChild {
13   constructor(dispatcher) {
14     super(dispatcher);
16     this.widgets = new WeakMap();
17   }
19   handleEvent(aEvent) {
20     switch (aEvent.type) {
21       case "UAWidgetSetupOrChange":
22         this.setupOrNotifyWidget(aEvent.target);
23         break;
24       case "UAWidgetTeardown":
25         this.teardownWidget(aEvent.target);
26         break;
27     }
29     // In case we are a nested frame, prevent the message manager of the
30     // parent frame from receving the event.
31     aEvent.stopPropagation();
32   }
34   setupOrNotifyWidget(aElement) {
35     let widget = this.widgets.get(aElement);
36     if (!widget) {
37       this.setupWidget(aElement);
38       return;
39     }
40     if (typeof widget.onchange == "function") {
41       try {
42         widget.onchange();
43       } catch (ex) {
44         Cu.reportError(ex);
45       }
46     }
47   }
49   setupWidget(aElement) {
50     let uri;
51     let widgetName;
52     switch (aElement.localName) {
53       case "video":
54       case "audio":
55         uri = "chrome://global/content/elements/videocontrols.js";
56         widgetName = "VideoControlsWidget";
57         break;
58       case "input":
59         uri = "chrome://global/content/elements/datetimebox.js";
60         widgetName = "DateTimeBoxWidget";
61         break;
62       case "embed":
63       case "object":
64         uri = "chrome://global/content/elements/pluginProblem.js";
65         widgetName = "PluginProblemWidget";
66         break;
67       case "marquee":
68         uri = "chrome://global/content/elements/marquee.js";
69         widgetName = "MarqueeWidget";
70         break;
71     }
73     if (!uri || !widgetName) {
74       Cu.reportError("Getting a UAWidgetSetupOrChange event on undefined element.");
75       return;
76     }
78     let shadowRoot = aElement.openOrClosedShadowRoot;
79     if (!shadowRoot) {
80       Cu.reportError("Getting a UAWidgetSetupOrChange event without the Shadow Root.");
81       return;
82     }
84     let isSystemPrincipal = aElement.nodePrincipal.isSystemPrincipal;
85     let sandbox = isSystemPrincipal ?
86       Object.create(null) : Cu.getUAWidgetScope(aElement.nodePrincipal);
88     if (!sandbox[widgetName]) {
89       Services.scriptloader.loadSubScript(uri, sandbox);
90     }
92     let widget = new sandbox[widgetName](shadowRoot);
93     if (!isSystemPrincipal) {
94       widget = widget.wrappedJSObject;
95     }
96     this.widgets.set(aElement, widget);
97     try {
98       widget.onsetup();
99     } catch (ex) {
100       Cu.reportError(ex);
101     }
102   }
104   teardownWidget(aElement) {
105     let widget = this.widgets.get(aElement);
106     if (!widget) {
107       return;
108     }
109     if (typeof widget.destructor == "function") {
110       try {
111         widget.destructor();
112       } catch (ex) {
113         Cu.reportError(ex);
114       }
115     }
116     this.widgets.delete(aElement);
117   }