bug 771395 - show origin of page in window title when it is different from webapp's origin; r=felipe
authorMyk Melez <myk@mozilla.org>
Tue, 10 Jul 2012 15:07:31 -0700
changeset 98866 5bb5b5dd4960f358b91b04f906435a3b68374b27
parent 98865 1f07f04ec01decf4086d97cd024cd324d5e9e698
child 98867 3bf8ff8836d19bf73a5c3b61991103d445f2b8f8
push id11698
push usermyk@mozilla.com
push dateTue, 10 Jul 2012 22:08:07 +0000
treeherdermozilla-inbound@5bb5b5dd4960 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfelipe
bugs771395
milestone16.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 771395 - show origin of page in window title when it is different from webapp's origin; r=felipe
webapprt/CommandLineHandler.js
webapprt/content/webapp.js
webapprt/test/chrome/Makefile.in
webapprt/test/chrome/browser_window-title.js
webapprt/test/chrome/window-title.html
webapprt/test/chrome/window-title.webapp
--- a/webapprt/CommandLineHandler.js
+++ b/webapprt/CommandLineHandler.js
@@ -25,23 +25,23 @@ CommandLineHandler.prototype = {
     // Initialize DOMApplicationRegistry by importing Webapps.jsm, but only
     // after broadcasting webapprt-command-line.  Webapps.jsm calls
     // DOMApplicationRegistry.init() when it's first imported.  init() accesses
     // the WebappRegD directory, which in test mode is special-cased by
     // DirectoryProvider.js after it observes webapprt-command-line.
     Cu.import("resource://gre/modules/Webapps.jsm");
 
     if (!inTestMode) {
-      startUp();
+      startUp(inTestMode);
     } else {
       // startUp() accesses WebappRT.config, which in test mode is not valid
       // until WebappRT.jsm observes an app installation.
       Services.obs.addObserver(function onInstall(subj, topic, data) {
         Services.obs.removeObserver(onInstall, "webapprt-test-did-install");
-        startUp();
+        startUp(inTestMode);
       }, "webapprt-test-did-install", false);
     }
 
     // Open the window with arguments to identify it as the main window
     Services.ww.openWindow(null,
                            "chrome://webapprt/content/webapp.xul",
                            "_blank",
                            "chrome,dialog=no,resizable,scrollbars,centerscreen",
--- a/webapprt/content/webapp.js
+++ b/webapprt/content/webapp.js
@@ -3,64 +3,102 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource://webapprt/modules/WebappRT.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyGetter(this, "gAppBrowser",
+                            function() document.getElementById("content"));
+
+let progressListener = {
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
+                                         Ci.nsISupportsWeakReference]),
+  onLocationChange: function onLocationChange(progress, request, location,
+                                              flags) {
+    // Set the title of the window to the name of the webapp, adding the origin
+    // of the page being loaded if it's from a different origin than the app
+    // (per security bug 741955, which specifies that other-origin pages loaded
+    // in runtime windows must be identified in chrome).
+    let title = WebappRT.config.app.manifest.name;
+    let origin = location.prePath;
+    if (origin != WebappRT.config.app.origin) {
+      title = origin + " - " + title;
+    }
+    document.documentElement.setAttribute("title", title);
+  }
+};
 
 function onLoad() {
   window.removeEventListener("load", onLoad, false);
 
   let cmdLineArgs = window.arguments && window.arguments[0] ?
                     window.arguments[0].QueryInterface(Ci.nsIPropertyBag2) :
                     null;
 
   // In test mode, listen for test app installations and load the -test-mode URL
   // if present.
   if (cmdLineArgs && cmdLineArgs.hasKey("test-mode")) {
+    // This observer is only present until the first app gets installed.
+    // It adds the progress listener, which can't happen until then because
+    // the progress listener needs to access the app manifest, which isn't
+    // available beforehand.
+    Services.obs.addObserver(function observeOnce(subj, topic, data) {
+      Services.obs.removeObserver(observeOnce, "webapprt-test-did-install");
+      gAppBrowser.webProgress.
+        addProgressListener(progressListener,Ci.nsIWebProgress.NOTIFY_LOCATION);
+    }, "webapprt-test-did-install", false);
+
+    // This observer is present for the lifetime of the runtime.
     Services.obs.addObserver(function observe(subj, topic, data) {
-      // The observer is present for the lifetime of the runtime.
       initWindow(false);
     }, "webapprt-test-did-install", false);
+
     let testURL = cmdLineArgs.get("test-mode");
     if (testURL) {
-      document.getElementById("content").loadURI(testURL);
+      gAppBrowser.loadURI(testURL);
     }
+
     return;
   }
 
+  gAppBrowser.webProgress.
+    addProgressListener(progressListener, Ci.nsIWebProgress.NOTIFY_LOCATION);
+
   initWindow(!!cmdLineArgs);
 }
-
 window.addEventListener("load", onLoad, false);
 
+function onUnload() {
+  gAppBrowser.removeProgressListener(progressListener);
+}
+window.addEventListener("unload", onUnload, false);
+
 function initWindow(isMainWindow) {
-  // Set the title of the window to the name of the webapp
   let manifest = WebappRT.config.app.manifest;
-  document.documentElement.setAttribute("title", manifest.name);
 
   updateMenuItems();
 
   // Listen for clicks to redirect <a target="_blank"> 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);
+  gAppBrowser.addEventListener("click", onContentClick, false, true);
 
   // Only load the webapp on the initially launched main window
   if (isMainWindow) {
     // Load the webapp's launch URL
     let installRecord = WebappRT.config.app;
     let url = Services.io.newURI(installRecord.origin, null, null);
     if (manifest.launch_path)
       url = Services.io.newURI(manifest.launch_path, null, url);
-    document.getElementById("content").setAttribute("src", url.spec);
+    gAppBrowser.setAttribute("src", url.spec);
   }
 }
 
 /**
  * Direct a click on <a target="_blank"> to the user's default browser.
  *
  * In the long run, it might be cleaner to move this to an extension of
  * nsIWebBrowserChrome3::onBeforeLinkTraversal.
--- a/webapprt/test/chrome/Makefile.in
+++ b/webapprt/test/chrome/Makefile.in
@@ -11,11 +11,14 @@ relativesrcdir = webapprt/test/chrome
 include $(DEPTH)/config/autoconf.mk
 
 MOCHITEST_WEBAPPRT_CHROME_FILES = \
   head.js \
   install.html \
   browser_sample.js \
     sample.webapp \
     sample.html \
+  browser_window-title.js \
+    window-title.webapp \
+    window-title.html \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/webapprt/test/chrome/browser_window-title.js
@@ -0,0 +1,55 @@
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function test() {
+  waitForExplicitFinish();
+
+  installWebapp("window-title.webapp", undefined,
+                function onInstall(appConfig) {
+    is(document.documentElement.getAttribute("title"),
+       appConfig.app.manifest.name,
+       "initial window title should be webapp name");
+
+    let appBrowser = document.getElementById("content");
+
+    // Tests are triples of [URL to load, expected window title, test message].
+    let tests = [
+      ["http://example.com/webapprtChrome/webapprt/test/chrome/window-title.html",
+       "http://example.com" + " - " + appConfig.app.manifest.name,
+       "window title should show origin of page at different origin"],
+      ["http://mochi.test:8888/webapprtChrome/webapprt/test/chrome/window-title.html",
+       appConfig.app.manifest.name,
+       "after returning to app origin, window title should no longer show origin"],
+    ];
+
+    let title, message;
+
+    let progressListener = {
+      QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
+                                             Ci.nsISupportsWeakReference]),
+      onLocationChange: function onLocationChange(progress, request, location,
+                                                  flags) {
+        // Do test in timeout to give runtime time to change title.
+        window.setTimeout(function() {
+          is(document.documentElement.getAttribute("title"), title, message);
+          testNext();
+        }, 0);
+      }
+    };
+
+    appBrowser.webProgress.
+      addProgressListener(progressListener, Ci.nsIWebProgress.NOTIFY_LOCATION);
+
+    function testNext() {
+      if (!tests.length) {
+        appBrowser.removeProgressListener(progressListener);
+        appBrowser.stop();
+        finish();
+        return;
+      }
+
+      [appBrowser.contentDocument.location, title, message] = tests.shift();
+    }
+
+    testNext();
+  });
+}
new file mode 100644
--- /dev/null
+++ b/webapprt/test/chrome/window-title.html
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML>
+<html>
+  <head>
+    <title>Window Title Test App</title>
+    <meta charset="utf-8">
+  </head>
+  <body>
+    <h1>Window Title Test App</h1>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/webapprt/test/chrome/window-title.webapp
@@ -0,0 +1,5 @@
+{
+  "name": "Window Title Test App",
+  "description": "an app for testing window titles",
+  "launch_path": "/webapprtChrome/webapprt/test/chrome/window-title.html"
+}