Bug 563723 - Add an about:home page that mimics current start page. r=gavin,mano,dietrich a=blocking
authorMarco Bonardo <mbonardo@mozilla.com>
Thu, 26 Aug 2010 12:19:37 +0200
changeset 51510 291cea9d9fcaeca8002d0165dd94a307a441d8e8
parent 51509 0d5a07e41321e22e954d73631ae172331aa80c05
child 51511 d906347e3a3683f6b54512b1bc07fc0ab26617b4
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgavin, mano, dietrich, blocking
bugs563723
milestone2.0b5pre
first release with
nightly win64
291cea9d9fca / 4.0b5pre / 20100826041432 / files
nightly linux32
nightly linux64
nightly mac
nightly win32
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly win64
Bug 563723 - Add an about:home page that mimics current start page. r=gavin,mano,dietrich a=blocking
browser/base/content/aboutHome.css
browser/base/content/aboutHome.js
browser/base/content/aboutHome.xhtml
browser/base/content/browser.js
browser/base/jar.mn
browser/branding/nightly/content/jar.mn
browser/branding/unofficial/content/jar.mn
browser/components/about/AboutRedirector.cpp
browser/components/build/nsModule.cpp
browser/components/nsBrowserContentHandler.js
browser/locales/en-US/chrome/browser/aboutHome.dtd
browser/locales/jar.mn
other-licenses/branding/firefox/content/jar.mn
new file mode 100644
--- /dev/null
+++ b/browser/base/content/aboutHome.css
@@ -0,0 +1,109 @@
+%if 0
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is aboutHome.xhtml.
+ *
+ * The Initial Developer of the Original Code is the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Marco Bonardo <mak77@bonardo.net> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+%endif
+
+html {
+  font: message-box;
+  background: -moz-Field;
+  color: -moz-FieldText;
+}
+
+#topSection,
+#bottomSection {
+  position: relative;
+  margin: 1em auto;
+  padding: 25px;
+  width: 560px;
+}
+
+#brandStart {
+  background: -moz-linear-gradient(top, #42607C, #1E4262 30%, #1E4262 80%, #143552 98%, #244665);
+  -moz-border-radius: 1%;
+  padding-bottom: 0.2em;
+  -moz-padding-start: 0.5em;
+  font-size: 250%;
+  font-weight: bold;
+  color: #688196;
+  margin-top: 18px;
+  margin-bottom: 6px;
+}
+#brandStart > span {
+  color: white;
+}
+
+#brandLogo {
+  position: absolute;
+  top: 0;
+}
+body[dir="ltr"] #brandLogo {
+  right: 0;
+}
+body[dir="rtl"] #brandLogo {
+  left: -15px;
+}
+
+#searchContainer {
+  border: 1px solid ThreeDShadow;
+  -moz-border-radius: 1%;
+  padding: 3em;
+}
+#searchEngineLinks {
+  font-size: 80%;
+}
+#searchEngineLinks > a {
+  -moz-margin-start: 1em;
+}
+body[dir="ltr"] #searchEngineLinks {
+  float: right;
+}
+body[dir="rtl"] #searchEngineLinks {
+  float: left;
+}
+
+#searchEngineLogo {
+  margin: 5px;
+}
+
+#searchText {
+  width: 100%;
+}
+
+#aboutMozilla {
+  text-align: center;
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/aboutHome.js
@@ -0,0 +1,114 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is aboutHome.xhtml.
+ *
+ * The Initial Developer of the Original Code is the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Marco Bonardo <mak77@bonardo.net> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// If a definition requires additional params, check that the final search url
+// is handled correctly by the engine.
+const SEARCH_ENGINES = {
+  "Google": {
+    image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEYAAAAYCAMAAABwdHsxAAADAFBMVEVogZYwjM9NtOspS2u0KAfYZBb3rRTiurCMjYrUWhIaPlzDNgfVRgjaVgvoizTI9f2ta17/9Wzrs0v46M/+7VOW6vrJQAsBLochdr+nmF/++o+UDQK88vzaYQarq6scarXT+f68vLzjdRrjewp5d3WqGATkUwaTq9uk7PnUaydkICTJSBD4uCDgZAz9+LiK6PjRZFH33Xv01qbrlxznhgvwx5gCBCbOUhLjfCzhaxHztXG8RhX93UP5yTRGl9QhRGT5wigkRmXniRj70zoKWrT2yUdqjs3UhzXvl0JwU0teu+EBElGD2fH83FZo1vTPilT0vDmd0Z3dbhrWrHLhcQir8PzTTDfPrVGrajv03cf5+vkwUG6z8PrSUw571uzvpCGPTzBsPDMxMEcHagXrkg7voBHf/P8FGHHhzrbyryOQZAeDNCudnZyTJBL2zlT+xByoUCG1wspyY1nRiH7STA3yiB7Jjx/pqT/Pz8/7lhDvfBxTUkl95PY/RE0DI2SQbT7LzJjxdg1OMTzutynnm2v+5DWsNBX+/tVDqOa7tnX57OPGYSHysziEo5a3XBe3l3j+0SXCoaCsjTL++fMgQmLmxXdv0ezsv0ycQxf8p0X1hwrenDU/Tnj9//tkyNj3+fX89fDv22QXHEWQydee7/xEdKG84uRWi5bwaxyK3/L++/iU5PMWM2Q6GS7UXg81l9gmSGgXOVewsKO3x+ECK8h8x3j7/fs5bMBke6kuTmwoRV/SbArKeSrB1snY373x5aSIRz85YIvragDD5+lnorUvSWF80PCQr6o4KGKysrIeQmIgXJ1Vb4j///8+XXjs7ewaUZSutsKFkqY4T3IhXqgYSHtwiJwUNVLExcbk5eU4SGcrcLEsP1wPKV77+/vy8/NBkcBmrN+drLklNGIONHQ5WXVxyuk0VXHHz9dmxuonZahTrNqPobEcP19CVXMURIljzvE/odz29vYcP3VieZHo6OhCYHxOW29y2vNYwe79/f33+PnU2eExgcLX2Nje397NKLzjAAACjElEQVR42q2UMWvbQBTHPRgro6CDKIJOPQSeVH+CDuZ2E3BIVmNkBB5agTF0NYV00y7jdMji0XqxvNljAzmEPASrQ0Vwhk41tPZiC6l3OjmNXYeYujfo3nF3v/fe/+le5hX5HyOTzv1Of88bnXelq0q8C9NRHMcpFrHd3gPTD0qV17uisWeDqE269gyguU88pcrRDowNXrqYTt1/xkQwXi8mZ2Q/TO9vDNa2FVkJLUPocDsYDoe1lB6EURzZ4RrDThHi0RF7mRh+bFGirCEYCJnMLpzUase5XI2aZxhjKM6wS64YJlDZqWxAPEq6ztjFm01KEzGdTxGirgoNFpRfrU7IEg8IiQFoqRlmqYp0p4VGDEO8zB1sYoLyKJlFVCdxjotwntNpISJqYfjKMQKi1fDVvJlqg2G6gWmh98l8iuRoWL1O7Bc53b2TJoSFc88xquwKqig8SGyDFvxRMGyriEdDUF140+DR9HN6hGHOBJIsjinLpvHoV84EIPGCL/ClAzOiojzfKeejz9WX3H6ru98Td6GWaqOi3lbBQQsTlyzzOU1ajjimTgpUkxRDN7Uvtl1kmTGMgT5+28BcAAC/SBSJBl7mWS1kkwRVnpWvs8n1HP6nMswFQmJyp71+DK4mgZ0ssEarFsiyQe0sg9V03acnG2luClgcQx+DKaOyTwTjAUNiS5OKWFGwZbGYw5GsiqKYNI6erp8XTo7TGigAToecVSofjvrEzMuyPBIe9xvXux2MvXCZZroQhNU6a7/mJ5VsK87l+FaD2TLpTvTTbTbj7bb13PiJZ0zAT+u6PtH9nhuKxD270s0hGAfSBOCgaJLHxDrlffcQzOoXSKyYjksOwdDWOLcG2H5i8zf27La6kVLrqwAAAABJRU5ErkJggg=="
+  , params: "source=hp"
+  , links: {
+      advanced: "http://www.google.com/advanced_search"
+    , preferences: "http://www.google.com/preferences"
+    }
+  }
+
+, "Яндекс":
+  {
+    image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAArCAMAAAC5Mt3fAAABnlBMVEX/////AAD/AwP/Bgb/CQn/DAz/Dw//EhL/FRX/GBj/Gxv/Hh7/ISH/JCT/Jyf/MDD/MzP/Pz//QkL/SEj/S0v/Tk7/UVH/YGD/Zmb/aWn/bGz/cnL/dXX/eHj/e3v/fn7/hIT/jY3/k5P/lpb/mZn/nJz/n5//paX/q6v/rq7/tLT/w8P/xsb/z8//1dX/2Nj/29v/3t7/4eH/5OT/7e3/8PD/8/P/9vb/+fn//Pz8/Pz5+fn29vbz8/Pw8PDt7e3q6urn5+fk5OTh4eHe3t7b29vY2NjS0tLPz8/MzMzJycnGxsbDw8PAwMC9vb26urq0tLSurq6rq6uoqKilpaWioqKfn5+cnJyZmZmWlpaTk5ONjY2KioqHh4eEhISBgYF+fn57e3t4eHh1dXVycnJvb29sbGxpaWlmZmZjY2NgYGBdXV1aWlpXV1dUVFRRUVFOTk5LS0tISEhFRUVCQkI/Pz88PDw5OTk2NjYzMzMwMDAtLS0qKionJyckJCQhISEeHh4bGxsVFRUSEhIPDw8MDAwJCQkGBgYDAwMAAABXxKaDAAAAAXRSTlMAQObYZgAAA3pJREFUWMPt1ulbG1UUx/HfQVsUrK1a9612c6t16SZBlkpTKLIkiG26KBSLoTVUdpiUQiIJyfe/9sXcYZJJSFsfx1c9b5J57p18cu5y7pWex/OIPS6cPHrkBTOzQ/EZp9rNxcHYjPfMzOzVI50xIifN7OXPz0sn4kO+e9Hs8DkpVuQDs7azihfpajd7SzEjZ8zsdNzIcTM7Gzfyvpldiht5x8z0L5BE6s6t4f2bhzJTmSt1SDSTMvwiSXdhw28aJAj35vAmwGKPJOkeLEvSzyUYk6S+BQBWRh3yoZl9HUGAm5KUhUd+08geMuj/0ZL/tCTXb01Sd8H/VN9j1/meQ043WV1NkarnPQ6QRB7WU9O4jB1yAxiWpAXYuTGeo9gTbHgze/NpkJKfz6AkXYdSn3QfNkMksQ3zkjQO1VFJ6bG9SXnNrO3Mk5AUFGuQDXgg6RqQ3EMmoZKUpFVYiKyDL82s85snI1shMgCkJSXKkAmQxCbMyrWmmhQvO3js25bIBGyEyKTLQHn4I0DS/hBKN6H6Q8Oaftes/tBqRDLwV4jMQiUhScv++srCmjz4VZL0595bdfFpRwOSy2QymdW97lOQDZEFKEqSFmHdISkodsul93C/KvlKeDIShkPmYDpE8rDrVcIOWfDybjlLJTc30XjD7MD5ujmJIEswESKFSIcs7AK3/HoDzDQxvjCzj+snPjJcBUiGyN9QmHvoeZ7nefNuuBZxe6+3OdJ12Kz9QqvV1QvlRIjswGLtD2RhbRi4I0l9NB2uE2Z2rOU+GYdVhci2q1G1iJZhp9cN13yDcbHD7KWLLZEZf3kGyDpsNyAjwLT8PPMNyEdm9knrHe/5JT5A7gP9UUQrUO6XtALVvohx7oBZx6WWSBJWpPodf7sBGXO1fQa/2NTG22Z2vHWBvOvOogDp2YXiQBTRBlR+lIaAYn0qX7WZdX7fEukpuXkeCQ6MLFC4GkVSwJykNWBjoBZ53cxOtTxPbm9B0fM8/9AqPpB0uQSwPDfvlSdCRB5Uk9JQBagszS3mC+E+PNTVEslRFwVJGqsEj7M1SBrISRrdCVovS5KOmrV9Fp7E7ZKkKkyGF4lmiIYeAVD6vd+/SKwEBbN6VdLgll9y0k99+cm5vNytxQ2BfspMXb/Wvd9LY5nfJpLPcDPbB/lv439BspTHg+9XKv417hniH6z+4JNllI0iAAAAAElFTkSuQmCC"
+  }
+};
+
+let gSearchEngine;
+
+function onLoad(event)
+{
+  setupSearchEngine();
+  document.getElementById("searchText").focus();
+}
+
+
+function onSearchSubmit(aEvent) {
+  let searchTerms = document.getElementById("searchText").value;
+  if (gSearchEngine && searchTerms.length > 0) {
+    const SEARCH_TOKENS = {
+      "_searchTerms_": encodeURIComponent(searchTerms)
+    }
+    let url = gSearchEngine.searchUrl;
+    for (let key in SEARCH_TOKENS) {
+      url = url.replace(key, SEARCH_TOKENS[key]);
+    }
+    window.location.href = url;
+  }
+
+  aEvent.preventDefault();
+}
+
+
+function setupSearchEngine() {
+  gSearchEngine = JSON.parse(localStorage["search-engine"]);
+
+  // Look for extended information, like logo and links.
+  let searchEngineInfo = SEARCH_ENGINES[gSearchEngine.name];
+  if (searchEngineInfo) {
+    for (let prop in searchEngineInfo)
+      gSearchEngine[prop] = searchEngineInfo[prop];
+  }
+
+  // Enqueue additional params if required by the engine definition.
+  if (gSearchEngine.params)
+    gSearchEngine.searchUrl += "&" + gSearchEngine.params;
+
+  // Add search engine logo.
+  if (gSearchEngine.image)
+    document.getElementById("searchEngineLogo").src = gSearchEngine.image;
+
+  if (gSearchEngine.links) {
+    // Add search engine links.
+    if (gSearchEngine.links.advanced) {
+      let advancedLink = document.getElementById("searchEngineAdvancedLink");
+      advancedLink.setAttribute("href", gSearchEngine.links.advanced);
+      advancedLink.hidden = false;
+    }
+    if (gSearchEngine.links.preferences) {
+      let prefsLink = document.getElementById("searchEngineAdvancedPreferences");
+      prefsLink.setAttribute("href", gSearchEngine.links.preferences);
+      prefsLink.hidden = false;
+    }
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/aboutHome.xhtml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License
+# Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is aboutHome.xhtml.
+#
+# The Initial Developer of the Original Code is the Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2010
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Marco Bonardo <mak77@bonardo.net> (original author)
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+<!DOCTYPE html [
+  <!ENTITY % htmlDTD
+    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "DTD/xhtml1-strict.dtd">
+  %htmlDTD;
+  <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
+  %globalDTD;
+  <!ENTITY % aboutHomeDTD SYSTEM "chrome://browser/locale/aboutHome.dtd">
+  %aboutHomeDTD;
+]>
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <title>&abouthome.pageTitle;</title>
+
+    <link rel="icon" type="image/png" id="favicon"
+          href="chrome://branding/content/icon16.png"/>
+    <link rel="stylesheet" type="text/css" media="all"
+          href="chrome://browser/content/aboutHome.css"/>
+
+    <script type="text/javascript;version=1.8"
+            src="chrome://browser/content/aboutHome.js"/>
+  </head>
+
+  <body dir="&locale.dir;" onload="onLoad(event)">
+    <div id="pageContainer">
+      <div id="topSection">
+        <img id="brandLogo" src="chrome://branding/content/icon128.png"
+             title="&abouthome.brandLogo.title;"/>
+        <div id="brandStart">
+          &abouthome.brandStart;
+        </div>
+        <div id ="searchContainer">
+          <img id="searchEngineLogo" title="&abouthome.searchEngineLogo.title;"/>
+          <form name="searchForm" onsubmit="onSearchSubmit(event)">
+            <input type="text" name="searchText" value="" id="searchText" maxLength="256"/>
+            <br/>
+            <input type="submit" value="&abouthome.searchEngineButton.label;"/>
+            <span id="searchEngineLinks">
+              <a hidden="true" id="searchEngineAdvancedLink">&abouthome.searchEngineLinks.advanced;</a>
+              <a hidden="true" id="searchEngineAdvancedPreferences">&abouthome.searchEngineLinks.preferences;</a>
+            </span>
+          </form>
+        </div>
+      </div>
+
+      <div id="bottomSection">
+        <div id="aboutMozilla">
+          <a href="http://www.mozilla.com/about/">&abouthome.aboutMozilla;</a>
+        </div>
+      </div>
+    </div>
+  </body>
+</html>
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3065,25 +3065,26 @@ const DOMLinkHandler = {
 
             var targetDoc = link.ownerDocument;
             var uri = makeURI(link.href, targetDoc.characterSet);
 
             if (gBrowser.isFailedIcon(uri))
               break;
 
             // Verify that the load of this icon is legal.
-            // error pages can load their favicon, to be on the safe side,
-            // only allow chrome:// favicons
-            const aboutNeterr = /^about:neterror\?/;
-            const aboutBlocked = /^about:blocked\?/;
-            const aboutCert = /^about:certerror\?/;
-            if (!(aboutNeterr.test(targetDoc.documentURI) ||
-                  aboutBlocked.test(targetDoc.documentURI) ||
-                  aboutCert.test(targetDoc.documentURI)) ||
-                !uri.schemeIs("chrome")) {
+            // Some error or special pages can load their favicon.
+            // To be on the safe side, only allow chrome:// favicons.
+            var isAllowedPage = [
+              /^about:neterror\?/,
+              /^about:blocked\?/,
+              /^about:certerror\?/,
+              /^about:home$/,
+            ].some(function (re) re.test(targetDoc.documentURI));
+
+            if (!isAllowedPage || !uri.schemeIs("chrome")) {
               var ssm = Cc["@mozilla.org/scriptsecuritymanager;1"].
                         getService(Ci.nsIScriptSecurityManager);
               try {
                 ssm.checkLoadURIWithPrincipal(targetDoc.nodePrincipal, uri,
                                               Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
               } catch(e) {
                 break;
               }
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -12,16 +12,19 @@ browser.jar:
 %  overlay chrome://global/content/viewSource.xul chrome://browser/content/viewSourceOverlay.xul
 %  overlay chrome://global/content/viewPartialSource.xul chrome://browser/content/viewSourceOverlay.xul
 %  style chrome://global/content/customizeToolbar.xul chrome://browser/content/browser.css
 %  style chrome://global/content/customizeToolbar.xul chrome://browser/skin/
 *       content/browser/aboutDialog.xul               (content/aboutDialog.xul)
 *       content/browser/aboutDialog.js                (content/aboutDialog.js)
         content/browser/aboutDialog.css               (content/aboutDialog.css)
 *       content/browser/aboutRobots.xhtml             (content/aboutRobots.xhtml)
+*       content/browser/aboutHome.xhtml               (content/aboutHome.xhtml)
+*       content/browser/aboutHome.js                  (content/aboutHome.js)
+*       content/browser/aboutHome.css                 (content/aboutHome.css)
         content/browser/aboutRobots-icon.png          (content/aboutRobots-icon.png)
         content/browser/aboutRobots-icon-rtl.png      (content/aboutRobots-icon-rtl.png)
         content/browser/aboutRobots-widget-left.png   (content/aboutRobots-widget-left.png)
         content/browser/aboutRobots-widget-right.png  (content/aboutRobots-widget-right.png)
 *       content/browser/browser.css                   (content/browser.css)
 *       content/browser/browser.js                    (content/browser.js)
 *       content/browser/browser.xul                   (content/browser.xul)
 *       content/browser/browser-tabPreviews.xml       (content/browser-tabPreviews.xml)
--- a/browser/branding/nightly/content/jar.mn
+++ b/browser/branding/nightly/content/jar.mn
@@ -1,7 +1,9 @@
 browser.jar:
-% content branding %content/branding/
+% content branding %content/branding/ contentaccessible=yes
   content/branding/about.png                     (about.png)
   content/branding/aboutCredits.png              (aboutCredits.png)
   content/branding/aboutFooter.png               (aboutFooter.png)
   content/branding/icon48.png                    (icon48.png)
   content/branding/icon64.png                    (icon64.png)
+  content/branding/icon128.png                   (../mozicon128.png)
+  content/branding/icon16.png                    (../default16.png)
--- a/browser/branding/unofficial/content/jar.mn
+++ b/browser/branding/unofficial/content/jar.mn
@@ -1,7 +1,9 @@
 browser.jar:
-% content branding %content/branding/
+% content branding %content/branding/ contentaccessible=yes
   content/branding/about.png                     (about.png)
   content/branding/aboutCredits.png              (aboutCredits.png)
   content/branding/aboutFooter.png               (aboutFooter.png)
   content/branding/icon48.png                    (icon48.png)
   content/branding/icon64.png                    (icon64.png)
+  content/branding/icon128.png                   (../mozicon128.png)
+  content/branding/icon16.png                    (../default16.png)
--- a/browser/components/about/AboutRedirector.cpp
+++ b/browser/components/about/AboutRedirector.cpp
@@ -95,16 +95,19 @@ static RedirEntry kRedirMap[] = {
     nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
     nsIAboutModule::ALLOW_SCRIPT },
   { "sessionrestore", "chrome://browser/content/aboutSessionRestore.xhtml",
     nsIAboutModule::ALLOW_SCRIPT },
 #ifdef MOZ_SERVICES_SYNC
   { "sync-tabs", "chrome://browser/content/aboutSyncTabs.xul",
     nsIAboutModule::ALLOW_SCRIPT },
 #endif
+  { "home", "chrome://browser/content/aboutHome.xhtml",
+    nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
+    nsIAboutModule::ALLOW_SCRIPT },
 };
 static const int kRedirTotal = NS_ARRAY_LENGTH(kRedirMap);
 
 static nsCAutoString
 GetAboutModuleName(nsIURI *aURI)
 {
   nsCAutoString path;
   aURI->GetPath(path);
--- a/browser/components/build/nsModule.cpp
+++ b/browser/components/build/nsModule.cpp
@@ -200,16 +200,17 @@ static const mozilla::Module::ContractID
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "feeds", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "privatebrowsing", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "rights", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "robots", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "sessionrestore", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
 #ifdef MOZ_SERVICES_SYNC
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "sync-tabs", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
 #endif
+    { NS_ABOUT_MODULE_CONTRACTID_PREFIX "home", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
 #ifndef WINCE
     { NS_PROFILEMIGRATOR_CONTRACTID, &kNS_FIREFOX_PROFILEMIGRATOR_CID },
 #if defined(XP_WIN) && !defined(__MINGW32__)
     { NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "ie", &kNS_WINIEPROFILEMIGRATOR_CID },
 #elif defined(XP_MACOSX)
     { NS_SHELLSERVICE_CONTRACTID, &kNS_SHELLSERVICE_CID },
     { NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "safari", &kNS_SAFARIPROFILEMIGRATOR_CID },
     { NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "macie", &kNS_MACIEPROFILEMIGRATOR_CID },
--- a/browser/components/nsBrowserContentHandler.js
+++ b/browser/components/nsBrowserContentHandler.js
@@ -32,16 +32,17 @@
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://gre/modules/Services.jsm");
 
 const nsISupports            = Components.interfaces.nsISupports;
 
 const nsIBrowserDOMWindow    = Components.interfaces.nsIBrowserDOMWindow;
 const nsIBrowserHandler      = Components.interfaces.nsIBrowserHandler;
 const nsIBrowserHistory      = Components.interfaces.nsIBrowserHistory;
 const nsIChannel             = Components.interfaces.nsIChannel;
 const nsICommandLine         = Components.interfaces.nsICommandLine;
@@ -60,16 +61,17 @@ const nsISupportsString      = Component
 const nsIURIFixup            = Components.interfaces.nsIURIFixup;
 const nsIWebNavigation       = Components.interfaces.nsIWebNavigation;
 const nsIWindowMediator      = Components.interfaces.nsIWindowMediator;
 const nsIWindowWatcher       = Components.interfaces.nsIWindowWatcher;
 const nsICategoryManager     = Components.interfaces.nsICategoryManager;
 const nsIWebNavigationInfo   = Components.interfaces.nsIWebNavigationInfo;
 const nsIBrowserSearchService = Components.interfaces.nsIBrowserSearchService;
 const nsICommandLineValidator = Components.interfaces.nsICommandLineValidator;
+const nsIXULAppInfo          = Components.interfaces.nsIXULAppInfo;
 
 const NS_BINDING_ABORTED = Components.results.NS_BINDING_ABORTED;
 const NS_ERROR_WONT_HANDLE_CONTENT = 0x805d0001;
 const NS_ERROR_ABORT = Components.results.NS_ERROR_ABORT;
 
 const URI_INHERITS_SECURITY_CONTEXT = nsIHttpProtocolHandler
                                         .URI_INHERITS_SECURITY_CONTEXT;
 
@@ -111,48 +113,65 @@ function resolveURIInternal(aCmdLine, aA
   }
 
   return uri;
 }
 
 const OVERRIDE_NONE        = 0;
 const OVERRIDE_NEW_PROFILE = 1;
 const OVERRIDE_NEW_MSTONE  = 2;
+const OVERRIDE_NEW_BUILD_ID = 3;
 /**
  * Determines whether a home page override is needed.
  * Returns:
  *  OVERRIDE_NEW_PROFILE if this is the first run with a new profile.
  *  OVERRIDE_NEW_MSTONE if this is the first run with a build with a different
  *                      Gecko milestone (i.e. right after an upgrade).
+ *  OVERRIDE_NEW_BUILD_ID if this is the first run with a new build ID of the
+ *                        same Gecko milestone (i.e. after a nightly upgrade).
  *  OVERRIDE_NONE otherwise.
  */
 function needHomepageOverride(prefb) {
   var savedmstone = null;
   try {
     savedmstone = prefb.getCharPref("browser.startup.homepage_override.mstone");
   } catch (e) {}
 
   if (savedmstone == "ignore")
     return OVERRIDE_NONE;
 
   var mstone = Components.classes["@mozilla.org/network/protocol;1?name=http"]
                          .getService(nsIHttpProtocolHandler).misc;
 
+  var savedBuildID = null;
+  try {
+    savedBuildID = prefb.getCharPref("browser.startup.homepage_override.buildID");
+  } catch (e) {}
+
+  var buildID =  Components.classes["@mozilla.org/xre/app-info;1"]
+                           .getService(nsIXULAppInfo).platformBuildID;
+
   if (mstone != savedmstone) {
     // Bug 462254. Previous releases had a default pref to suppress the EULA
     // agreement if the platform's installer had already shown one. Now with
     // about:rights we've removed the EULA stuff and default pref, but we need
     // a way to make existing profiles retain the default that we removed.
     if (savedmstone)
       prefb.setBoolPref("browser.rights.3.shown", true);
     
     prefb.setCharPref("browser.startup.homepage_override.mstone", mstone);
+    prefb.setCharPref("browser.startup.homepage_override.buildID", buildID);
     return (savedmstone ? OVERRIDE_NEW_MSTONE : OVERRIDE_NEW_PROFILE);
   }
 
+  if (buildID != savedBuildID) {
+    prefb.setCharPref("browser.startup.homepage_override.buildID", buildID);
+    return OVERRIDE_NEW_BUILD_ID;
+  }
+
   return OVERRIDE_NONE;
 }
 
 /**
  * Gets the override page for the first run after the application has been
  * updated.
  * @param  defaultOverridePage
  *         The default override page.
@@ -557,34 +576,41 @@ nsBrowserContentHandler.prototype = {
     var prefb = Components.classes["@mozilla.org/preferences-service;1"]
                           .getService(nsIPrefBranch);
     var formatter = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
                               .getService(Components.interfaces.nsIURLFormatter);
 
     var overridePage = "";
     var haveUpdateSession = false;
     try {
-      switch (needHomepageOverride(prefb)) {
-        case OVERRIDE_NEW_PROFILE:
-          // New profile
-          overridePage = formatter.formatURLPref("startup.homepage_welcome_url");
-          break;
-        case OVERRIDE_NEW_MSTONE:
-          // Existing profile, new build
-          copyPrefOverride();
+      let override = needHomepageOverride(prefb);
+      Components.utils.reportError("OVERRIDE: " + override);
+      if (override != OVERRIDE_NONE) {
+        // Setup the default search engine to about:home page.
+        AboutHomeUtils.loadDefaultSearchEngine();
 
-          // Check whether we have a session to restore. If we do, we assume
-          // that this is an "update" session.
-          var ss = Components.classes["@mozilla.org/browser/sessionstartup;1"]
-                             .getService(Components.interfaces.nsISessionStartup);
-          haveUpdateSession = ss.doRestore();
-          overridePage = formatter.formatURLPref("startup.homepage_override_url");
-          if (prefb.prefHasUserValue("app.update.postupdate"))
-            overridePage = getPostUpdateOverridePage(overridePage);
-          break;
+        switch (override) {
+          case OVERRIDE_NEW_PROFILE:
+            // New profile.
+            overridePage = formatter.formatURLPref("startup.homepage_welcome_url");
+            break;
+          case OVERRIDE_NEW_MSTONE:
+            // Existing profile, new milestone build.
+            copyPrefOverride();
+
+            // Check whether we have a session to restore. If we do, we assume
+            // that this is an "update" session.
+            var ss = Components.classes["@mozilla.org/browser/sessionstartup;1"]
+                               .getService(Components.interfaces.nsISessionStartup);
+            haveUpdateSession = ss.doRestore();
+            overridePage = formatter.formatURLPref("startup.homepage_override_url");
+            if (prefb.prefHasUserValue("app.update.postupdate"))
+              overridePage = getPostUpdateOverridePage(overridePage);
+            break;
+        }
       }
     } catch (ex) {}
 
     // formatURLPref might return "about:blank" if getting the pref fails
     if (overridePage == "about:blank")
       overridePage = "";
 
     var startPage = "";
@@ -851,10 +877,36 @@ nsDefaultCommandLineHandler.prototype = 
                  "chrome,dialog=no,all" + gBrowserContentHandler.getFeatures(cmdLine),
                  gBrowserContentHandler.defaultArgs, NO_EXTERNAL_URIS);
     }
   },
 
   helpInfo : "",
 };
 
+let AboutHomeUtils = {
+  get _storage() {
+    let aboutHomeURI = Services.io.newURI("moz-safe-about:home", null, null);
+    let principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"].
+                    getService(Components.interfaces.nsIScriptSecurityManager).
+                    getCodebasePrincipal(aboutHomeURI);
+    let dsm = Components.classes["@mozilla.org/dom/storagemanager;1"].
+              getService(Components.interfaces.nsIDOMStorageManager);
+    return dsm.getLocalStorageForPrincipal(principal, "");
+  },
+
+  loadDefaultSearchEngine: function AHU_loadDefaultSearchEngine()
+  {
+    // TODO: should use originalDefaultEngine once available, see bug 587691.
+    let defaultEngine = Services.search.defaultEngine;
+    let submission = defaultEngine.getSubmission("_searchTerms_");
+    if (submission.postData)
+      throw new Error("Home page does not support POST search engines.");
+    let engine = {
+      name: defaultEngine.name
+    , searchUrl: submission.uri.spec
+    }
+    this._storage.setItem("search-engine", JSON.stringify(engine));
+  }
+};
+
 var components = [nsBrowserContentHandler, nsDefaultCommandLineHandler];
 var NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
new file mode 100644
--- /dev/null
+++ b/browser/locales/en-US/chrome/browser/aboutHome.dtd
@@ -0,0 +1,20 @@
+<!ENTITY % brandDTD
+    SYSTEM "chrome://branding/locale/brand.dtd">
+  %brandDTD;
+
+<!-- These strings are used in the about:home page -->
+
+<!ENTITY abouthome.pageTitle "&brandFullName; Start Page">
+<!ENTITY abouthome.brandLogo.title "&brandFullName; logo">
+
+<!-- LOCALIZATION NOTE (brandStart): brandShortName must be in a <span/> -->
+<!ENTITY abouthome.brandStart "<span>&brandShortName;</span> Start">
+
+<!ENTITY abouthome.searchEngineLogo.title "Search engine logo">
+
+<!ENTITY abouthome.searchEngineButton.label "Search">
+
+<!ENTITY abouthome.searchEngineLinks.advanced "Advanced Search">
+<!ENTITY abouthome.searchEngineLinks.preferences "Preferences">
+
+<!ENTITY abouthome.aboutMozilla "About Mozilla">
--- a/browser/locales/jar.mn
+++ b/browser/locales/jar.mn
@@ -1,16 +1,17 @@
 #filter substitution
 
 @AB_CD@.jar:
 % locale browser @AB_CD@ %locale/browser/
     locale/browser/aboutCertError.dtd              (%chrome/browser/aboutCertError.dtd)
     locale/browser/aboutDialog.dtd                 (%chrome/browser/aboutDialog.dtd)
     locale/browser/aboutPrivateBrowsing.dtd        (%chrome/browser/aboutPrivateBrowsing.dtd)
     locale/browser/aboutRobots.dtd                 (%chrome/browser/aboutRobots.dtd)
+    locale/browser/aboutHome.dtd                   (%chrome/browser/aboutHome.dtd)
     locale/browser/aboutSessionRestore.dtd         (%chrome/browser/aboutSessionRestore.dtd)
 #ifdef MOZ_SERVICES_SYNC
     locale/browser/aboutSyncTabs.dtd               (%chrome/browser/aboutSyncTabs.dtd)
 #endif
     locale/browser/credits.dtd                     (%chrome/browser/credits.dtd)
 *   locale/browser/browser.dtd                     (%chrome/browser/browser.dtd)
     locale/browser/baseMenuOverlay.dtd             (%chrome/browser/baseMenuOverlay.dtd)
     locale/browser/browser.properties              (%chrome/browser/browser.properties)
--- a/other-licenses/branding/firefox/content/jar.mn
+++ b/other-licenses/branding/firefox/content/jar.mn
@@ -1,7 +1,9 @@
 browser.jar:
-% content branding %content/branding/
+% content branding %content/branding/ contentaccessible=yes
   content/branding/about.png                     (about.png)
   content/branding/aboutCredits.png              (aboutCredits.png)
   content/branding/aboutFooter.png               (aboutFooter.png)
   content/branding/icon48.png                    (icon48.png)
   content/branding/icon64.png                    (icon64.png)
+  content/branding/icon128.png                   (../mozicon128.png)
+  content/branding/icon16.png                    (../default16.png)