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 file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
5 const Cc = Components.classes;
6 const Ci = Components.interfaces;
7 const Cu = Components.utils;
9 Cu.import("resource://webapprt/modules/Startup.jsm");
10 Cu.import("resource://webapprt/modules/WebappRT.jsm");
11 Cu.import("resource://gre/modules/Services.jsm");
12 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
14 XPCOMUtils.defineLazyGetter(this, "gAppBrowser",
15 function() document.getElementById("content"));
17 #ifdef MOZ_CRASHREPORTER
18 XPCOMUtils.defineLazyServiceGetter(this, "gCrashReporter",
19 "@mozilla.org/toolkit/crash-reporter;1",
23 let progressListener = {
24 QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
25 Ci.nsISupportsWeakReference]),
26 onLocationChange: function onLocationChange(progress, request, location,
28 // Set the title of the window to the name of the webapp, adding the origin
29 // of the page being loaded if it's from a different origin than the app
30 // (per security bug 741955, which specifies that other-origin pages loaded
31 // in runtime windows must be identified in chrome).
32 let title = WebappRT.config.app.manifest.name;
33 let origin = location.prePath;
34 if (origin != WebappRT.config.app.origin) {
35 title = origin + " - " + title;
37 document.documentElement.setAttribute("title", title);
40 onStateChange: function onStateChange(aProgress, aRequest, aFlags, aStatus) {
41 if (aRequest instanceof Ci.nsIChannel &&
42 aFlags & Ci.nsIWebProgressListener.STATE_START &&
43 aFlags & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT) {
44 updateCrashReportURL(aRequest.URI);
50 window.removeEventListener("load", onLoad, false);
52 let args = window.arguments && window.arguments[0] ?
53 window.arguments[0].QueryInterface(Ci.nsIPropertyBag2) :
56 gAppBrowser.addProgressListener(progressListener,
57 Ci.nsIWebProgress.NOTIFY_LOCATION |
58 Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
62 // Listen for clicks to redirect <a target="_blank"> to the browser.
63 // This doesn't capture clicks so content can capture them itself and do
64 // something different if it doesn't want the default behavior.
65 gAppBrowser.addEventListener("click", onContentClick, false, true);
67 // This is not the only way that a URL gets loaded in the app browser.
68 // When content calls openWindow(), there are no window.arguments,
69 // but something in the platform loads the URL specified by the content.
70 if (args && args.hasKey("url")) {
71 gAppBrowser.setAttribute("src", args.get("url"));
75 window.addEventListener("load", onLoad, false);
78 gAppBrowser.removeProgressListener(progressListener);
80 window.addEventListener("unload", onUnload, false);
83 * Direct a click on <a target="_blank"> to the user's default browser.
85 * In the long run, it might be cleaner to move this to an extension of
86 * nsIWebBrowserChrome3::onBeforeLinkTraversal.
88 * @param {DOMEvent} event the DOM event
90 function onContentClick(event) {
91 let target = event.target;
93 if (!(target instanceof HTMLAnchorElement) ||
94 target.getAttribute("target") != "_blank") {
98 let uri = Services.io.newURI(target.href,
99 target.ownerDocument.characterSet,
102 // Direct the URL to the browser.
103 Cc["@mozilla.org/uriloader/external-protocol-service;1"].
104 getService(Ci.nsIExternalProtocolService).
105 getProtocolHandlerInfo(uri.scheme).
108 // Prevent the runtime from loading the URL. We do this after directing it
109 // to the browser to give the runtime a shot at handling the URL if we fail
110 // to direct it to the browser for some reason.
111 event.preventDefault();
114 // On Mac, we dynamically create the label for the Quit menuitem, using
115 // a string property to inject the name of the webapp into it.
116 function updateMenuItems() {
118 let installRecord = WebappRT.config.app;
119 let manifest = WebappRT.config.app.manifest;
121 Services.strings.createBundle("chrome://webapprt/locale/webapp.properties");
122 let quitLabel = bundle.formatStringFromName("quitApplicationCmdMac.label",
124 let hideLabel = bundle.formatStringFromName("hideApplicationCmdMac.label",
126 document.getElementById("menu_FileQuitItem").setAttribute("label", quitLabel);
127 document.getElementById("menu_mac_hide_app").setAttribute("label", hideLabel);
131 function updateEditUIVisibility() {
133 let editMenuPopupState = document.getElementById("menu_EditPopup").state;
135 // The UI is visible if the Edit menu is opening or open, if the context menu
136 // is open, or if the toolbar has been customized to include the Cut, Copy,
137 // or Paste toolbar buttons.
138 gEditUIVisible = editMenuPopupState == "showing" ||
139 editMenuPopupState == "open";
141 // If UI is visible, update the edit commands' enabled state to reflect
142 // whether or not they are actually enabled for the current focus/selection.
143 if (gEditUIVisible) {
144 goUpdateGlobalEditMenuItems();
147 // Otherwise, enable all commands, so that keyboard shortcuts still work,
148 // then lazily determine their actual enabled state when the user presses
149 // a keyboard shortcut.
151 goSetCommandEnabled("cmd_undo", true);
152 goSetCommandEnabled("cmd_redo", true);
153 goSetCommandEnabled("cmd_cut", true);
154 goSetCommandEnabled("cmd_copy", true);
155 goSetCommandEnabled("cmd_paste", true);
156 goSetCommandEnabled("cmd_selectAll", true);
157 goSetCommandEnabled("cmd_delete", true);
158 goSetCommandEnabled("cmd_switchTextDirection", true);
163 function updateCrashReportURL(aURI) {
164 #ifdef MOZ_CRASHREPORTER
165 if (!gCrashReporter.enabled)
168 let uri = aURI.clone();
169 // uri.userPass throws on protocols without the concept of authentication,
170 // like about:, which tests can load, so we catch and ignore an exception.
172 if (uri.userPass != "") {
177 gCrashReporter.annotateCrashReport("URL", uri.spec);