Bug 596864 - Open links from about: pages in remote tabs [r=mfinkle]
authorMatt Brubeck <mbrubeck@mozilla.com>
Wed, 15 Sep 2010 23:28:12 -0700
changeset 2012 25d089c480c8318880ac7e267f3c5524517eca57
parent 2011 fb1e3fb7ec8a32b266032eed797f669ccb0dc9fd
child 2013 2f7715f27533316ded08e9277ab813a1d026faac
push id1717
push usermbrubeck@mozilla.com
push dateThu, 16 Sep 2010 06:29:13 +0000
reviewersmfinkle
bugs596864
Bug 596864 - Open links from about: pages in remote tabs [r=mfinkle]
chrome/content/Util.js
chrome/content/aboutHome.xhtml
chrome/content/browser-ui.js
chrome/content/content.js
chrome/content/firstrun/firstrun.xhtml
--- a/chrome/content/Util.js
+++ b/chrome/content/Util.js
@@ -158,16 +158,21 @@ let Util = {
   // Put the Mozilla networking code into a state that will kick the auto-connection
   // process.
   forceOnline: function forceOnline() {
 #ifdef MOZ_PLATFORM_MAEMO
     Services.io.offline = false;
 #endif
   },
 
+  isParentProcess: function isInParentProcess() {
+    let appInfo = Cc["@mozilla.org/xre/app-info;1"];
+    return (!appInfo || appInfo.getService(Ci.nsIXULRuntime).processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT);
+  },
+
   isPortrait: function isPortrait() {
     return (window.innerWidth < 500);
   }
 };
 
 
 /**
  * Helper class to nsITimer that adds a little more pizazz.  Callback can be an
--- a/chrome/content/aboutHome.xhtml
+++ b/chrome/content/aboutHome.xhtml
@@ -79,17 +79,17 @@
     <div id="newAddons" class="section-box">
       <h1>&aboutHome.recommendedAddons2;</h1>
       <div id="loadingAddons" class="loading">
         <img src="chrome://browser/skin/images/throbber.png"/>
       </div>
     </div>
 
     <div id="about">
-      <img src="chrome://browser/skin/images/mozilla-32.png"/> <a href="http://www.mozilla.com/about/" onclick="openTabs([this.href]); return false;">&aboutHome.aboutMozilla;</a>
+      <img src="chrome://browser/skin/images/mozilla-32.png"/> <a href="http://www.mozilla.com/about/">&aboutHome.aboutMozilla;</a>
     </div>
   </div>
 
   <!-- l10n hack -->
   <div style="display: none">
     <span id="text-openalltabs">&aboutHome.openAllTabs;</span>
     <span id="text-notabs">&aboutHome.noTabs;</span>
     <span id="text-noaddons">&aboutHome.noAddons;</span>
--- a/chrome/content/browser-ui.js
+++ b/chrome/content/browser-ui.js
@@ -861,17 +861,17 @@ var BrowserUI = {
         for (let i = 0; i < json.rects.length; i++) {
           let rect = json.rects[i];
           rects.push(new Rect(rect.left, rect.top, rect.width, rect.height));
         }
         TapHighlightHelper.show(rects);
         break;
 
       case "Browser:OpenURI":
-        Browser.addTab(json.uri, false, Browser.selectedTab);
+        Browser.addTab(json.uri, json.bringFront, Browser.selectedTab);
     }
   },
 
   supportsCommand : function(cmd) {
     var isSupported = false;
     switch (cmd) {
       case "cmd_back":
       case "cmd_forward":
--- a/chrome/content/content.js
+++ b/chrome/content/content.js
@@ -211,36 +211,16 @@ function getContentClientRects(aElement)
                   top: r.top + offset.y,
                   width: r.width,
                   height: r.height
                 });
   }
   return result;
 };
 
-/** Reponsible for sending messages about viewport size changes and painting. */
-function Coalescer() {
-}
-
-Coalescer.prototype = {
-  handleEvent: function handleEvent(aEvent) {
-    switch (aEvent.type) {
-      case "MozApplicationManifest": {
-        let doc = aEvent.originalTarget;
-        sendAsyncMessage("Browser:MozApplicationManifest", {
-          location: doc.documentURIObject.spec,
-          manifest: doc.documentElement.getAttribute("manifest"),
-          charset: doc.characterSet
-        });
-        break;
-      }
-    }
-  }
-};
-
 
 /**
  * Responsible for sending messages about security, location, and page load state.
  * @param loadingController Object with methods startLoading and stopLoading
  */
 function ProgressController(loadingController) {
   this._webNavigation = docShell.QueryInterface(Ci.nsIWebNavigation);
   this._overrideService = null;
@@ -324,28 +304,54 @@ function Content() {
   addMessageListener("Browser:Focus", this);
   addMessageListener("Browser:KeyEvent", this);
   addMessageListener("Browser:MouseDown", this);
   addMessageListener("Browser:MouseUp", this);
   addMessageListener("Browser:MouseCancel", this);
   addMessageListener("Browser:SaveAs", this);
   addMessageListener("Browser:ZoomToPoint", this);
 
-  this._coalescer = new Coalescer();
-  addEventListener("MozApplicationManifest", this._coalescer, false);
+  if (Util.isParentProcess())
+    addEventListener("DOMActivate", this, true);
+
+  addEventListener("MozApplicationManifest", this, false);
 
   this._progressController = new ProgressController(this);
   this._progressController.start();
 
   this._formAssistant = new FormAssistant();
   this._overlayTimeout = new Util.Timeout();
   this._contextTimeout = new Util.Timeout();
 }
 
 Content.prototype = {
+  handleEvent: function handleEvent(aEvent) {
+    switch (aEvent.type) {
+      case "DOMActivate": {
+        // In a local tab, open remote links in new tabs.
+        let href = Util.getHrefForElement(aEvent.originalTarget);
+        if (!Util.isLocalScheme(href)) {
+          aEvent.preventDefault();
+          sendAsyncMessage("Browser:OpenURI", { uri: href, bringFront: true });
+        }
+        break;
+      }
+
+      case "MozApplicationManifest": {
+        let doc = aEvent.originalTarget;
+        sendAsyncMessage("Browser:MozApplicationManifest", {
+          location: doc.documentURIObject.spec,
+          manifest: doc.documentElement.getAttribute("manifest"),
+          charset: doc.characterSet
+        });
+        break;
+      }
+    }
+  },
+
   receiveMessage: function receiveMessage(aMessage) {
     let json = aMessage.json;
     let x = json.x;
     let y = json.y;
     let modifiers = json.modifiers;
 
     switch (aMessage.name) {
       case "Browser:Blur":
@@ -624,17 +630,17 @@ ViewportHandler.init();
 
 
 const kXLinkNamespace = "http://www.w3.org/1999/xlink";
 
 var ContextHandler = {
   _types: [],
 
   _getLinkURL: function ch_getLinkURL(aLink) {
-    let href = aLink.href;  
+    let href = aLink.href;
     if (href)
       return href;
 
     href = aLink.getAttributeNS(kXLinkNamespace, "href");
     if (!href || !href.match(/\S/)) {
       // Without this we try to save as the current doc,
       // for example, HTML case also throws if empty
       throw "Empty href";
@@ -707,23 +713,23 @@ var ContextHandler = {
       }
 
       elem = elem.parentNode;
     }
 
     for (let i = 0; i < this._types.length; i++)
       if (this._types[i].handler(state, popupNode))
         state.types.push(this._types[i].name);
-    
+
     sendAsyncMessage("Browser:ContextMenu", state);
   },
 
   /**
    * For add-ons to add new types and data to the ContextMenu message.
-   * 
+   *
    * @param aName A string to identify the new type.
    * @param aHandler A function that takes a state object and a target element.
    *    If aHandler returns true, then aName will be added to the list of types.
    *    The function may also modify the state object.
    */
   registerType: function registerType(aName, aHandler) {
     this._types.push({name: aName, handler: aHandler});
   }
--- a/chrome/content/firstrun/firstrun.xhtml
+++ b/chrome/content/firstrun/firstrun.xhtml
@@ -59,38 +59,38 @@
   <link rel="stylesheet" href="chrome://browser/skin/firstRun.css" type="text/css"/>
 </head>
 
 <body id="firstrun" class="">
   <div id="wrapper">
     <div id="header">
       <a href="http://mozilla.com/m"><img src="chrome://browser/content/firstrun/mozilla.png" width="64" height="17"/></a>
     </div>
-    
+
     <div id="head">
       <h1><img src="chrome://branding/content/logoWordmark.png"/></h1>
       <p>&firstrun.heading2;</p>
     </div>
-  
+
     <div id="content">
       <h2></h2>
       <ul id="recommended">
         <li id="sync"><a href="javascript:loadSync();"><b>&firstrun.sync.title;</b> <span>&firstrun.sync.description;</span></a></li>
         <li id="addons"><a href="javascript:loadAddons();"><b>&firstrun.addons.title;</b> <span>&firstrun.addons.description;</span></a></li>
         <li id="home"><a href="about:home"><b>&firstrun.home.title;</b> <span>&firstrun.home.description;</span></a></li>
       </ul>
 
       <p id="relNotes"><a id="releaseNotesURL">&firstrun.relNotes.label;</a></p>
       <script type="application/javascript;version=1.8"><![CDATA[
         let Ci = Components.interfaces, Cc = Components.classes, Cu = Components.utils;
         let gChromeWin = null;
         let links = [
           {id: "releaseNotesURL", pref: "app.releaseNotesURL"},
         ];
-        
+
         function getChromeWin() {
           if (!gChromeWin) {
             gChromeWin = window
                     .QueryInterface(Ci.nsIInterfaceRequestor)
                     .getInterface(Ci.nsIWebNavigation)
                     .QueryInterface(Ci.nsIDocShellTreeItem)
                     .rootTreeItem
                     .QueryInterface(Ci.nsIInterfaceRequestor)
@@ -113,44 +113,45 @@
         function loadAddons() {
           let win = getChromeWin();
           win.BrowserUI.showPanel("addons-container");
         }
 
         function init() {
           setupLinks();
         }
-        
+
         function setupLinks() {
           try {
             let formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"]
-                                      .getService(Ci.nsIURLFormatter);            
+                                      .getService(Ci.nsIURLFormatter);
             links.forEach(function (link) {
               let url = formatter.formatURLPref(link.pref);
               let element = document.getElementById(link.id);
               element.setAttribute("href", url);
             });
           } catch (ex) {}
         }
+
         document.addEventListener("DOMContentLoaded", init, false);
       ]]></script>
     </div>
-  
+
     <div id="footer">
-      
+
       <ul class="nav">
         <!--
         <li><a href="http://mozilla.com/m/faq">&firstrun.faq;</a></li>
         <li><a href="http://mozilla.com/m/privacy">&firstrun.privacy;</a></li>
         -->
       </ul>
-  
+
       <div id="follow">
         <p>&firstrun.follow;</p>
         <ul>
           <li id="follow-twitter"><a href="http://twitter.com/mozmobile"><img src="chrome://browser/content/firstrun/twitter.png" height="41" width="42" /></a></li>
           <li id="follow-facebook"><a href="http://www.facebook.com/firefoxformobile"><img src="chrome://browser/content/firstrun/facebook.png" height="41" width="42" /></a></li>
         </ul>
       </div>
-    </div>  
+    </div>
   </div>
 </body>
 </html>