b=437959, r=gavin. View, install and remove add-ons
authorMark Finkle <mfinkle@mozilla.com>
Tue, 19 Aug 2008 22:18:36 -0400
changeset 64795 8144c98b0263d6bfdcf785fd1e36138158b7ccfd
parent 64794 80141d5d8f3aab37f91aac7d73e06bfab8854aa4
child 64796 f0710295c7c5243bc355b8842aaaee7d2348d8af
push id19389
push userffxbld
push dateWed, 06 Apr 2011 21:33:21 +0000
treeherdermozilla-central@8e9f90073a20 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgavin
bugs437959
b=437959, r=gavin. View, install and remove add-ons
mobile/app/mobile.js
mobile/chrome/content/browser-ui.js
mobile/chrome/content/browser.js
mobile/chrome/content/browser.xul
mobile/chrome/jar.mn
mobile/chrome/locale/en-US/browser.properties
--- a/mobile/app/mobile.js
+++ b/mobile/app/mobile.js
@@ -99,32 +99,51 @@ pref("signon.SignonFileName", "signons.t
 /* autocomplete */
 pref("browser.formfill.enable", true);
 
 /* spellcheck */
 pref("layout.spellcheckDefault", 1);
 
 /* extension manager and xpinstall */
 pref("xpinstall.dialog.confirm", "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul");
-pref("xpinstall.dialog.progress.skin", "chrome://mozapps/content/extensions/extensions.xul?type=themes");
-pref("xpinstall.dialog.progress.chrome", "chrome://mozapps/content/extensions/extensions.xul?type=extensions");
-pref("xpinstall.dialog.progress.type.skin", "Extension:Manager-themes");
-pref("xpinstall.dialog.progress.type.chrome", "Extension:Manager-extensions");
+pref("xpinstall.dialog.progress.skin", "chrome://browser/content/browser.xul");
+pref("xpinstall.dialog.progress.chrome", "chrome://browser/content/browser.xul");
+pref("xpinstall.dialog.progress.type.skin", "navigator:browser");
+pref("xpinstall.dialog.progress.type.chrome", "navigator:browser");
 pref("extensions.update.enabled", true);
 pref("extensions.update.interval", 86400);
 pref("extensions.dss.enabled", false);
 pref("extensions.dss.switchPending", false);
 pref("extensions.ignoreMTimeChanges", false);
 pref("extensions.logging.enabled", false);
+pref("extensions.hideInstallButton", true);
 
 /* these point at AMO */
 pref("extensions.update.url", "chrome://mozapps/locale/extensions/extensions.properties");
 pref("extensions.getMoreExtensionsURL", "chrome://mozapps/locale/extensions/extensions.properties");
 pref("extensions.getMoreThemesURL", "chrome://mozapps/locale/extensions/extensions.properties");
 
+/* preferences for the Get Add-ons pane */
+pref("extensions.getAddons.showPane", true);
+pref("extensions.getAddons.browseAddons", "https://%LOCALE%.add-ons.mozilla.com/%LOCALE%/%APP%");
+pref("extensions.getAddons.maxResults", 5);
+pref("extensions.getAddons.recommended.browseURL", "https://%LOCALE%.add-ons.mozilla.com/%LOCALE%/%APP%/recommended");
+pref("extensions.getAddons.recommended.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/list/featured/all/10/%OS%/%VERSION%");
+pref("extensions.getAddons.search.browseURL", "https://%LOCALE%.add-ons.mozilla.com/%LOCALE%/%APP%/search?q=%TERMS%");
+pref("extensions.getAddons.search.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/search/%TERMS%/all/10/%OS%/%VERSION%");
+
+/* blocklist preferences */
+pref("extensions.blocklist.enabled", true);
+pref("extensions.blocklist.interval", 86400);
+pref("extensions.blocklist.url", "https://addons.mozilla.org/blocklist/2/%APP_ID%/%APP_VERSION%/%PRODUCT%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/");
+pref("extensions.blocklist.detailsURL", "http://%LOCALE%.www.mozilla.com/%LOCALE%/blocklist/");
+
+/* dictionary download preference */
+pref("browser.dictionaries.download.url", "https://%LOCALE%.add-ons.mozilla.com/%LOCALE%/firefox/%VERSION%/dictionaries/");
+
 /* make clicking on links stand out a bit */
 pref("browser.display.use_focus_colors", true);
 pref("browser.display.focus_background_color", "#ffffa0");
 pref("browser.display.focus_text_color", "#00000");
 
 /* block popups by default, and notify the user about blocked popups */
 pref("dom.disable_open_during_load", true);
 pref("privacy.popups.showBrowserMessage", true);
@@ -141,17 +160,17 @@ pref("accessibility.typeaheadfind.linkso
 pref("accessibility.typeaheadfind.casesensitive", 0);
 
 // pointer to the default engine name
 pref("browser.search.defaultenginename",      "chrome://browser/locale/region.properties");
 
 // disable logging for the search service by default
 pref("browser.search.log", false);
 
-// Ordering of Search Engines in the Engine list. 
+// Ordering of Search Engines in the Engine list.
 pref("browser.search.order.1",                "chrome://browser/locale/region.properties");
 pref("browser.search.order.2",                "chrome://browser/locale/region.properties");
 
 // disable updating
 pref("browser.search.update", false);
 pref("browser.search.update.log", false);
 pref("browser.search.updateinterval", 6);
 
--- a/mobile/chrome/content/browser-ui.js
+++ b/mobile/chrome/content/browser-ui.js
@@ -39,19 +39,20 @@ const TOOLBARSTATE_LOADING        = 1;
 const TOOLBARSTATE_LOADED         = 2;
 const TOOLBARSTATE_INDETERMINATE  = 3;
 
 const PANELMODE_NONE              = 0;
 const PANELMODE_URLVIEW           = 1;
 const PANELMODE_URLEDIT           = 2;
 const PANELMODE_BOOKMARK          = 3;
 const PANELMODE_BOOKMARKLIST      = 4;
-const PANELMODE_SIDEBAR           = 5;
-const PANELMODE_TABLIST           = 6;
-const PANELMODE_FULL              = 7;
+const PANELMODE_ADDONS            = 5;
+const PANELMODE_SIDEBAR           = 6;
+const PANELMODE_TABLIST           = 7;
+const PANELMODE_FULL              = 8;
 
 var BrowserUI = {
   _panel : null,
   _caption : null,
   _edit : null,
   _throbber : null,
   _autocompleteNavbuttons : null,
   _favicon : null,
@@ -394,32 +395,30 @@ var BrowserUI = {
       return;
     this.mode = aMode;
 
     var toolbar = document.getElementById("toolbar-main");
     var bookmark = document.getElementById("bookmark-container");
     var urllist = document.getElementById("urllist-container");
     var sidebar = document.getElementById("browser-controls");
     var tablist = document.getElementById("tab-list-container");
+    var addons = document.getElementById("addons-container");
     var container = document.getElementById("browser-container");
 
-    // Make sure the UI elements are sized correctly since the window size can change
-    //sidebar.left = toolbar.width = container.boxObject.width;
-    //sidebar.height = tablist.height = container.boxObject.height;
-
     if (aMode == PANELMODE_URLVIEW || aMode == PANELMODE_SIDEBAR ||
         aMode == PANELMODE_TABLIST || aMode == PANELMODE_FULL)
     {
       this._showToolbar();
       toolbar.setAttribute("mode", "view");
       this._edit.hidden = true;
       this._edit.reallyClosePopup();
       this._caption.hidden = false;
       bookmark.hidden = true;
       urllist.hidden = true;
+      addons.hidden = true;
 
       let sidebarTo = toolbar.boxObject.width;
       let tablistTo = -tablist.boxObject.width;
       if (aMode == PANELMODE_SIDEBAR || aMode == PANELMODE_FULL)
         sidebarTo -= sidebar.boxObject.width;
       if (aMode == PANELMODE_TABLIST || aMode == PANELMODE_FULL)
         tablistTo = 0;
       sidebar.left = sidebarTo;
@@ -429,56 +428,79 @@ var BrowserUI = {
       this._showToolbar();
       toolbar.setAttribute("mode", "edit");
       this._caption.hidden = true;
       this._edit.hidden = false;
       this._edit.focus();
 
       bookmark.hidden = true;
       urllist.hidden = true;
+      addons.hidden = true;
       sidebar.left = toolbar.boxObject.width;
       tablist.left = -tablist.boxObject.width;
     }
     else if (aMode == PANELMODE_BOOKMARK) {
       this._showToolbar();
       toolbar.setAttribute("mode", "view");
       this._edit.hidden = true;
       this._edit.reallyClosePopup();
       this._caption.hidden = false;
 
       urllist.hidden = true;
       sidebar.left = toolbar.boxObject.width;
       tablist.left = -tablist.boxObject.width;
 
       bookmark.hidden = false;
+      addons.hidden = true;
       bookmark.width = container.boxObject.width;
     }
     else if (aMode == PANELMODE_BOOKMARKLIST) {
       this._showToolbar();
       toolbar.setAttribute("mode", "view");
       this._edit.hidden = true;
       this._edit.reallyClosePopup();
       this._caption.hidden = false;
 
       bookmark.hidden = true;
+      addons.hidden = true;
+      sidebar.left = toolbar.boxObject.width;
+      tablist.left = -tablist.boxObject.width;
+
+      urllist.hidden = false;
+      urllist.width = container.boxObject.width;
+      urllist.height = container.boxObject.height;
+    }
+    else if (aMode == PANELMODE_ADDONS) {
+      this._showToolbar();
+      toolbar.setAttribute("mode", "view");
+      this._edit.hidden = true;
+      this._edit.reallyClosePopup();
+      this._caption.hidden = false;
+
+      bookmark.hidden = true;
       sidebar.left = toolbar.boxObject.width;
       tablist.left = -tablist.boxObject.width;
 
-      urllist.hidden = false;
-      urllist.width = container.boxObject.width;
-      urllist.height = container.boxObject.height;
+      var iframe = document.getElementById("addons-items-container");
+      if (iframe.getAttribute("src") == "")
+        iframe.setAttribute("src", "chrome://mozapps/content/extensions/extensions.xul");
+
+      addons.hidden = false;
+      addons.width = container.boxObject.width;
+      addons.height = container.boxObject.height - toolbar.boxObject.height;
     }
     else if (aMode == PANELMODE_NONE) {
       this._hideToolbar();
       sidebar.left = toolbar.boxObject.width;
       tablist.left = -tablist.boxObject.width;
 
       this._edit.reallyClosePopup();
       urllist.hidden = true;
       bookmark.hidden = true;
+      addons.hidden = true;
     }
   },
 
   _showPlaces : function(aItems) {
     var list = document.getElementById("urllist-items");
     while (list.firstChild) {
       list.removeChild(list.firstChild);
     }
@@ -604,16 +626,18 @@ var BrowserUI = {
       case "cmd_stop":
       case "cmd_search":
       case "cmd_go":
       case "cmd_star":
       case "cmd_bookmarks":
       case "cmd_menu":
       case "cmd_newTab":
       case "cmd_closeTab":
+      case "cmd_addons":
+      case "cmd_actions":
         isSupported = true;
         break;
       default:
         isSupported = false;
         break;
     }
     return isSupported;
   },
@@ -668,26 +692,32 @@ var BrowserUI = {
           BookmarkHelper.edit(bookmarkURI);
         }
         break;
       }
       case "cmd_bookmarks":
         this.showBookmarks();
         break;
       case "cmd_menu":
-        if (this.mode == PANELMODE_FULL)
+        // XXX Remove PANELMODE_ADDON when design changes
+        if (this.mode == PANELMODE_FULL || this.mode == PANELMODE_ADDONS)
           this.show(PANELMODE_NONE);
         else
           this.show(PANELMODE_FULL);
         break;
       case "cmd_newTab":
         this.newTab();
         break;
       case "cmd_closeTab":
         Browser.content.removeTab(Browser.content.browser);
+        break;
+      case "cmd_addons":
+      case "cmd_actions":
+        this.show(PANELMODE_ADDONS);
+        break;
     }
   }
 };
 
 var BookmarkHelper = {
   _item : null,
   _uri : null,
   _bmksvc : null,
--- a/mobile/chrome/content/browser.js
+++ b/mobile/chrome/content/browser.js
@@ -97,16 +97,20 @@ var Browser = {
     var styleURI = ios.newURI("chrome://browser/content/scrollbars.css", null, null);
     styleSheets.loadAndRegisterSheet(styleURI, styleSheets.AGENT_SHEET);
 
     this._content = document.getElementById("content");
     this._content.progressListenerCreator = function (content, browser) {
       return new ProgressController(content, browser);
     };
 
+    var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
+    os.addObserver(gXPInstallObserver, "xpinstall-install-blocked", false);
+    os.addObserver(gXPInstallObserver, "xpinstall-download-started", false);
+
     this._content.tabList = document.getElementById("tab-list");
     this._content.newTab(true);
     this._content.addEventListener("DOMTitleChanged", this, true);
     this._content.addEventListener("DOMUpdatePageReport", gPopupBlockerObserver.onUpdatePageReport, false);
     BrowserUI.init();
 
     SpatialNavigation.init(this.content);
 
@@ -215,17 +219,16 @@ var Browser = {
         break;
     }
   },
 
   supportsCommand : function(cmd) {
     var isSupported = false;
     switch (cmd) {
       case "cmd_fullscreen":
-      case "cmd_addons":
       case "cmd_downloads":
         isSupported = true;
         break;
       default:
         isSupported = false;
         break;
     }
     return isSupported;
@@ -237,41 +240,16 @@ var Browser = {
 
   doCommand : function(cmd) {
     var browser = this.content.browser;
 
     switch (cmd) {
       case "cmd_fullscreen":
         window.fullScreen = !window.fullScreen;
         break;
-      case "cmd_addons":
-      {
-        const EMTYPE = "Extension:Manager";
-
-        var aOpenMode = "extensions";
-        var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
-        var needToOpen = true;
-        var windowType = EMTYPE + "-" + aOpenMode;
-        var windows = wm.getEnumerator(windowType);
-        while (windows.hasMoreElements()) {
-          var theEM = windows.getNext().QueryInterface(Ci.nsIDOMWindowInternal);
-          if (theEM.document.documentElement.getAttribute("windowtype") == windowType) {
-            theEM.focus();
-            needToOpen = false;
-            break;
-          }
-        }
-
-        if (needToOpen) {
-          const EMURL = "chrome://mozapps/content/extensions/extensions.xul?type=" + aOpenMode;
-          const EMFEATURES = "chrome,dialog=no,resizable=yes";
-          window.openDialog(EMURL, "", EMFEATURES);
-        }
-        break;
-      }
       case "cmd_downloads":
         Cc["@mozilla.org/download-manager-ui;1"].getService(Ci.nsIDownloadManagerUI).show(window);
         break;
     }
   },
 
   getNotificationBox : function() {
     return document.getElementById("notifications");
@@ -297,17 +275,17 @@ var Browser = {
 
   doFind: function (aEvent) {
     var findbar = document.getElementById("findbar");
     if (Browser.findState == FINDSTATE_FIND)
       findbar.onFindCommand();
     else
       findbar.onFindAgainCommand(Browser.findState == FINDSTATE_FIND_PREVIOUS);
   },
-  
+
   translatePhoneNumbers: function() {
     let doc = getBrowser().contentDocument;
     let textnodes = doc.evaluate("//text()",
                                  doc,
                                  null,
                                  XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
                                  null);
     let s, node, lastLastIndex;
@@ -849,11 +827,73 @@ const gPopupBlockerObserver = {
   dontShowMessage: function ()
   {
     var showMessage = gPrefService.getBoolPref("privacy.popups.showBrowserMessage");
     gPrefService.setBoolPref("privacy.popups.showBrowserMessage", !showMessage);
     Browser.getNotificationBox().removeCurrentNotification();
   }
 };
 
+const gXPInstallObserver = {
+  observe: function (aSubject, aTopic, aData)
+  {
+    var brandBundle = document.getElementById("bundle_brand");
+    var browserBundle = document.getElementById("bundle_browser");
+    switch (aTopic) {
+      case "xpinstall-install-blocked":
+        var installInfo = aSubject.QueryInterface(Components.interfaces.nsIXPIInstallInfo);
+        var host = installInfo.originatingURI.host;
+        var brandShortName = brandBundle.getString("brandShortName");
+        var notificationName, messageString, buttons;
+        if (!gPrefService.getBoolPref("xpinstall.enabled")) {
+          notificationName = "xpinstall-disabled"
+          if (gPrefService.prefIsLocked("xpinstall.enabled")) {
+            messageString = browserBundle.getString("xpinstallDisabledMessageLocked");
+            buttons = [];
+          }
+          else {
+            messageString = browserBundle.getFormattedString("xpinstallDisabledMessage",
+                                                             [brandShortName, host]);
+            buttons = [{
+              label: browserBundle.getString("xpinstallDisabledButton"),
+              accessKey: browserBundle.getString("xpinstallDisabledButton.accesskey"),
+              popup: null,
+              callback: function editPrefs() {
+                gPrefService.setBoolPref("xpinstall.enabled", true);
+                return false;
+              }
+            }];
+          }
+        }
+        else {
+          notificationName = "xpinstall"
+          messageString = browserBundle.getFormattedString("xpinstallPromptWarning",
+                                                           [brandShortName, host]);
+
+          buttons = [{
+            label: browserBundle.getString("xpinstallPromptAllowButton"),
+            accessKey: browserBundle.getString("xpinstallPromptAllowButton.accesskey"),
+            popup: null,
+            callback: function() {
+              // Force the addon manager panel to appear
+              CommandUpdater.doCommand("cmd_addons");
+
+              var mgr = Cc["@mozilla.org/xpinstall/install-manager;1"].createInstance(Ci.nsIXPInstallManager);
+              mgr.initManagerWithInstallInfo(installInfo);
+              return false;
+            }
+          }];
+        }
+
+        var nBox = Browser.getNotificationBox();
+        if (!nBox.getNotificationWithValue(notificationName)) {
+          const priority = nBox.PRIORITY_WARNING_MEDIUM;
+          const iconURL = "chrome://mozapps/skin/update/update.png";
+          nBox.appendNotification(messageString, notificationName, iconURL, priority, buttons);
+        }
+        break;
+    }
+  }
+};
+
 function getNotificationBox(aWindow) {
   return Browser.getNotificationBox();
-};
+}
--- a/mobile/chrome/content/browser.xul
+++ b/mobile/chrome/content/browser.xul
@@ -84,16 +84,17 @@
     <command id="cmd_star" label="&star.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
     <command id="cmd_bookmarks" label="&bookmarks.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
 
     <!-- misc -->
     <command id="cmd_menu" oncommand="CommandUpdater.doCommand(this.id);"/>
     <command id="cmd_fullscreen" oncommand="CommandUpdater.doCommand(this.id);"/>
     <command id="cmd_addons" oncommand="CommandUpdater.doCommand(this.id);"/>
     <command id="cmd_downloads" oncommand="CommandUpdater.doCommand(this.id);"/>
+    <command id="cmd_actions" oncommand="CommandUpdater.doCommand(this.id);"/>
 
     <!-- scrolling -->
     <command id="cmd_scrollPageUp" oncommand="CommandUpdater.doCommand(this.id);"/>
     <command id="cmd_scrollPageDown" oncommand="CommandUpdater.doCommand(this.id);"/>
 
     <!-- editing -->
     <command id="cmd_cut" label="&cut.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
     <command id="cmd_copy" label="&copy.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
@@ -261,16 +262,20 @@
         <hbox id="bookmark-buttons">
           <button label="&bookmarkRemove.label;" oncommand="BookmarkHelper.remove()"/>
           <spacer flex="1"/>
           <button label="&bookmarkCancel.label;" oncommand="BookmarkHelper.close()"/>
           <button label="&bookmarkDone.label;" oncommand="BookmarkHelper.save()"/>
         </hbox>
       </vbox>
     </vbox>
+
+    <vbox id="addons-container" hidden="true" style="-moz-stack-sizing: ignore;" top="60" left="0">
+      <iframe id="addons-items-container" flex="1" src=""/>
+    </vbox>
   </stack>
 
   <vbox id="findpanel-placeholder" sizetopopup="always">
     <panel id="findpanel" onpopupshown="Browser.doFind()">
       <findbar id="findbar"/>
    </panel>
   </vbox>
 
--- a/mobile/chrome/jar.mn
+++ b/mobile/chrome/jar.mn
@@ -10,20 +10,22 @@ browser.jar:
   content/deckbrowser.xml              (content/deckbrowser.xml)
   content/browser.css                  (content/browser.css)
   content/scrollbars.css               (content/scrollbars.css)
   content/content.css                  (content/content.css)
 % content branding %branding/
 % locale branding @AB_CD@ %branding/
   branding/brand.dtd                   (locale/@AB_CD@/brand/brand.dtd)
   branding/brand.properties            (locale/@AB_CD@/brand/brand.properties)
+% style chrome://mozapps/content/extensions/extensions.xul chrome://browser/skin/extensions.css
 
 classic.jar:
 % skin browser classic/1.0 %
   browser.css                          (skin/browser.css)
+  extensions.css                       (skin/extensions.css)
   images/close.png                     (skin/images/close.png)
   images/close-small.png               (skin/images/close-small.png)
   images/default-favicon.png           (skin/images/default-favicon.png)
   images/identity.png                  (skin/images/identity.png)
   images/starred48.png                 (skin/images/starred48.png)
   images/page-starred.png              (skin/images/page-starred.png)
   images/tag.png                       (skin/images/tag.png)
   images/throbber.png                  (skin/images/throbber.png)
--- a/mobile/chrome/locale/en-US/browser.properties
+++ b/mobile/chrome/locale/en-US/browser.properties
@@ -1,16 +1,24 @@
 # Popup Blocker
 popupWarning=%S prevented this site from opening a pop-up window.
 popupWarningMultiple=%S prevented this site from opening %S pop-up windows.
 popupButtonAlwaysAllow=Always Allow
 popupButtonAlwaysAllow.accesskey=A
 popupButtonNeverWarn=Never tell me
 popupButtonNeverWarn.accesskey=N
 
+# XPInstall
+xpinstallPromptWarning=%S prevented this site (%S) from asking you to install software on your computer.
+xpinstallPromptAllowButton=Allow
+xpinstallPromptAllowButton.accesskey=A
+xpinstallDisabledMessageLocked=Software installation has been disabled by your system administrator.
+xpinstallDisabledMessage=Software installation is currently disabled. Click Enable and try again.
+xpinstallDisabledButton=Enable
+xpinstallDisabledButton.accesskey=n
 
 # Site Identity
 identity.identified.verifier=Verified by: %S
 identity.identified.verified_by_you=You have added a security exception for this site
 identity.identified.state_and_country=%S, %S
 identity.identified.title_with_country=%S (%S)
 identity.encrypted=Your connection to this web site is encrypted to prevent eavesdropping.
 identity.unencrypted=Your connection to this web site is not encrypted.