diff --git a/webapprt/ContentPolicy.js b/webapprt/ContentPolicy.js index b71aff196e7..c9af5b7e311 100644 --- a/webapprt/ContentPolicy.js +++ b/webapprt/ContentPolicy.js @@ -2,24 +2,18 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ +/* We used to use this component to heuristically determine which links to + * direct to the user's default browser, but we no longer use that heuristic. + * It will come in handy when we implement support for trusted apps, however, + * so we left it in (although it is disabled in the manifest). +*/ + const Cc = Components.classes; const Ci = Components.interfaces; const Cu = Components.utils; -Cu.import("resource://webapprt/modules/WebappRT.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -// Allow certain origins to load as top-level documents -const allowedOrigins = [ - WebappRT.config.app.origin, - "https://browserid.org", - "https://www.facebook.com", - "https://accounts.google.com", - "https://www.google.com", - "https://twitter.com", - "https://api.twitter.com", -]; - function ContentPolicy() {} ContentPolicy.prototype = { @@ -28,28 +22,14 @@ ContentPolicy.prototype = { QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPolicy]), shouldLoad: function(contentType, contentLocation, requestOrigin, context, mimeTypeGuess, extra) { - // Redirect top-level document loads that aren't special schemes to the - // default browser when trying to load pages outside of allowed origins - let {prePath, scheme} = contentLocation; - if (contentType == Ci.nsIContentPolicy.TYPE_DOCUMENT && - !/^(about|chrome|resource)$/.test(scheme) && - allowedOrigins.indexOf(prePath) == -1) { - - // Send the url to the default browser - Cc["@mozilla.org/uriloader/external-protocol-service;1"]. - getService(Ci.nsIExternalProtocolService). - getProtocolHandlerInfo(scheme). - launchWithURI(contentLocation); - - // Using window.open will first open then navigate, so explicitly close - if (context.currentURI.spec == "about:blank") { - context.ownerDocument.defaultView.close(); - }; - - return Ci.nsIContentPolicy.REJECT_SERVER; - } return Ci.nsIContentPolicy.ACCEPT; + + // When rejecting a load due to a content policy violation, use this code + // to close the window opened by window.open, if any. + //if (context.currentURI.spec == "about:blank") { + // context.ownerDocument.defaultView.close(); + //}; }, shouldProcess: function(contentType, contentLocation, requestOrigin, context, mimeType, extra) { diff --git a/webapprt/components.manifest b/webapprt/components.manifest index 90d35992d1c..9cf52c71892 100644 --- a/webapprt/components.manifest +++ b/webapprt/components.manifest @@ -8,9 +8,13 @@ component {07ef5b2e-88fb-47bd-8cec-d3b0bef11ac4} ContentPermission.js contract @mozilla.org/content-permission/prompt;1 {07ef5b2e-88fb-47bd-8cec-d3b0bef11ac4} # ContentPolicy.js -component {75acd178-3d5a-48a7-bd92-fba383520ae6} ContentPolicy.js application=webapprt@mozilla.org -contract @mozilla.org/webapprt/content-policy;1 {75acd178-3d5a-48a7-bd92-fba383520ae6} application=webapprt@mozilla.org -category content-policy webapprt-content-policy @mozilla.org/webapprt/content-policy;1 application=webapprt@mozilla.org +# We used to use this component to heuristically determine which links to +# direct to the user's default browser, but we no longer use that heuristic. +# It will come in handy when we implement support for trusted apps, however, +# so we left it in (although it is disabled here). +# component {75acd178-3d5a-48a7-bd92-fba383520ae6} ContentPolicy.js application=webapprt@mozilla.org +# contract @mozilla.org/webapprt/content-policy;1 {75acd178-3d5a-48a7-bd92-fba383520ae6} application=webapprt@mozilla.org +# category content-policy webapprt-content-policy @mozilla.org/webapprt/content-policy;1 application=webapprt@mozilla.org # DirectoryProvider.js component {e1799fda-4b2f-4457-b671-e0641d95698d} DirectoryProvider.js application=webapprt@mozilla.org diff --git a/webapprt/content/webapp.js b/webapprt/content/webapp.js index 80e3a01bd7a..05fdd5c913b 100644 --- a/webapprt/content/webapp.js +++ b/webapprt/content/webapp.js @@ -16,6 +16,12 @@ function onLoad() { let manifest = WebappRT.config.app.manifest; document.documentElement.setAttribute("title", manifest.name); + // Listen for clicks to redirect to the browser. + // This doesn't capture clicks so content can capture them itself and do + // something different if it doesn't want the default behavior. + document.getElementById("content").addEventListener("click", onContentClick, + false, true); + // Only load the webapp on the initially launched main window if ("arguments" in window) { // Load the webapp's launch URL @@ -28,6 +34,38 @@ function onLoad() { } window.addEventListener("load", onLoad, false); +/** + * Direct a click on to the user's default browser. + * + * In the long run, it might be cleaner to move this to an extension of + * nsIWebBrowserChrome3::onBeforeLinkTraversal. + * + * @param {DOMEvent} event the DOM event + **/ +function onContentClick(event) { + let target = event.target; + + if (!(target instanceof HTMLAnchorElement) || + target.getAttribute("target") != "_blank") { + return; + } + + let uri = Services.io.newURI(target.href, + target.ownerDocument.characterSet, + null); + + // Direct the URL to the browser. + Cc["@mozilla.org/uriloader/external-protocol-service;1"]. + getService(Ci.nsIExternalProtocolService). + getProtocolHandlerInfo(uri.scheme). + launchWithURI(uri); + + // Prevent the runtime from loading the URL. We do this after directing it + // to the browser to give the runtime a shot at handling the URL if we fail + // to direct it to the browser for some reason. + event.preventDefault(); +} + #ifdef XP_MACOSX // On Mac, we dynamically create the label for the Quit menuitem, using // a string property to inject the name of the webapp into it.