Bug 518111 - Avoid using <stringbundle> and switch to nsIStringBundleService [r=mbrubeck r=vingtetun]
authorMark Finkle <mfinkle@mozilla.com>
Mon, 03 Jan 2011 15:07:41 -0500
changeset 67199 19abf479910b095c0f9457cd2c4ab65141d18be9
parent 67198 2b5e2c72e5c6aaea12292c538a87fa47c8126feb
child 67200 49fc3ddc19eb68301321734bf6a4c39239e21090
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)
reviewersmbrubeck, vingtetun
bugs518111
Bug 518111 - Avoid using <stringbundle> and switch to nsIStringBundleService [r=mbrubeck r=vingtetun]
mobile/app/profile/extensions/feedback@mobile.mozilla.org/content/overlay.js
mobile/chrome/content/bindings.xml
mobile/chrome/content/browser-ui.js
mobile/chrome/content/browser.js
mobile/chrome/content/browser.xul
mobile/chrome/content/console.js
mobile/chrome/content/downloads.js
mobile/chrome/content/extensions.js
mobile/chrome/content/preferences.js
mobile/chrome/tests/browser_addons.js
--- a/mobile/app/profile/extensions/feedback@mobile.mozilla.org/content/overlay.js
+++ b/mobile/app/profile/extensions/feedback@mobile.mozilla.org/content/overlay.js
@@ -88,18 +88,16 @@ var Feedback = {
     let formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].getService(Ci.nsIURLFormatter);
     let url = formatter.formatURLPref("app.releaseNotesURL");
     BrowserUI.newTab(url);
   },
 
   updateRestart: function updateRestart() {
     let msg = document.getElementById("feedback-messages");
     if (msg) {
-      let strings = Elements.browserBundle;
-
       let value = "restart-app";
       let notification = msg.getNotificationWithValue(value);
       if (notification) {
         // Check if the prefs are back to the initial state dismiss the restart
         // notification because if does not make sense anymore
         for each (let pref in this._prefs) {
           let value = Services.prefs.getPrefType(pref.name) == Ci.nsIPrefBranch.PREF_INVALID ? false : Services.prefs.getBoolPref(pref.name);
           if (value != pref.value)
@@ -117,21 +115,23 @@ var Feedback = {
   
         // If nothing aborted, quit the app
         if (cancelQuit.data == false) {
           let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup);
           appStartup.quit(Ci.nsIAppStartup.eRestart | Ci.nsIAppStartup.eAttemptQuit);
         }
       };
 
+      let strings = Strings.browser;
+
       let buttons = [ {
-        label: strings.getString("notificationRestart.button"),
+        label: strings.GetStringFromName("notificationRestart.button"),
         accessKey: "",
         callback: restartCallback
       } ];
   
-      let message = strings.getString("notificationRestart.normal");
+      let message = strings.GetStringFromName("notificationRestart.normal");
       msg.appendNotification(message, value, "", msg.PRIORITY_WARNING_LOW, buttons);
     }
   }
 };
 
 window.addEventListener("load", Feedback.init, false);
--- a/mobile/chrome/content/bindings.xml
+++ b/mobile/chrome/content/bindings.xml
@@ -315,17 +315,17 @@
 
           // Need to iterate over all our existing entries at a minimum, to make
           // sure they're either updated or cleared out. We might also have to
           // add extra items.
           let matchCount = this._matchCount;
           let children = items.childNodes;
           let iterCount = Math.max(children.length, matchCount);
 
-          let searchSubtitle = Elements.browserBundle.stringBundle.formatStringFromName("opensearch.searchFor", [searchString], 1);
+          let searchSubtitle = Strings.browser.formatStringFromName("opensearch.searchFor", [searchString], 1);
 
           for (let i = 0; i < iterCount; ++i) {
             let item = children.item(i);
 
             // Create an item if needed
             if (!item) {
               item = document.createElementNS(this._XULNS, "xul:autocompleteresult");
               items.appendChild(item);
@@ -924,17 +924,17 @@
           this._folderParents[PlacesUtils.toolbarFolderId] = this._desktopFolderId;
         ]]>
       </constructor>
 
       <field name="_desktopFolderId">-1000</field>
       <field name="_desktopFolder"><![CDATA[
         ({
           itemId: this._desktopFolderId, tags: "", uri: "",
-          title: Elements.browserBundle.getString("bookmarkList.desktop"),
+          title: Strings.browser.GetStringFromName("bookmarkList.desktop"),
           type: Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER
         })
       ]]></field>
       <field name="_desktopChildren"><![CDATA[
         [
           {
             itemId: PlacesUtils.bookmarks.unfiledBookmarksFolder, tags: "", uri: "",
             title: PlacesUtils.bookmarks.getItemTitle(PlacesUtils.bookmarks.unfiledBookmarksFolder),
--- a/mobile/chrome/content/browser-ui.js
+++ b/mobile/chrome/content/browser-ui.js
@@ -70,17 +70,16 @@ XPCOMUtils.defineLazyServiceGetter(windo
 });
 
 /**
  * Cache of commonly used elements.
  */
 let Elements = {};
 
 [
-  ["browserBundle",      "bundle_browser"],
   ["contentShowing",     "bcast_contentShowing"],
   ["urlbarState",        "bcast_urlbarState"],
   ["stack",              "stack"],
   ["tabs",               "tabs-container"],
   ["controls",           "browser-controls"],
   ["panelUI",            "panel-container"],
   ["toolbarContainer",   "toolbar-container"],
   ["browsers",           "browsers"],
@@ -88,16 +87,30 @@ let Elements = {};
   ["contentNavigator",   "content-navigator"]
 ].forEach(function (aElementGlobal) {
   let [name, id] = aElementGlobal;
   XPCOMUtils.defineLazyGetter(Elements, name, function() {
     return document.getElementById(id);
   });
 });
 
+/**
+ * Cache of commonly used string bundles.
+ */
+var Strings = {};
+[
+  ["browser",    "chrome://browser/locale/browser.properties"],
+  ["brand",      "chrome://branding/locale/brand.properties"]
+].forEach(function (aStringBundle) {
+  let [name, bundle] = aStringBundle;
+  XPCOMUtils.defineLazyGetter(Strings, name, function() {
+    return Services.strings.createBundle(bundle);
+  });
+});
+
 const TOOLBARSTATE_LOADING  = 1;
 const TOOLBARSTATE_LOADED   = 2;
 
 var BrowserUI = {
   _edit: null,
   _title: null,
   _throbber: null,
   _favicon: null,
@@ -1106,19 +1119,18 @@ var BrowserUI = {
       case "cmd_closeTab":
         this.closeTab();
         break;
       case "cmd_undoCloseTab":
         this.undoCloseTab();
         break;
       case "cmd_sanitize":
       {
-        let strings = Elements.browserBundle;
-        let title = strings.getString("clearPrivateData.title");
-        let message = strings.getString("clearPrivateData.message");
+        let title = Strings.browser.GetStringFromName("clearPrivateData.title");
+        let message = Strings.browser.GetStringFromName("clearPrivateData.message");
         let clear = Services.prompt.confirm(window, title, message);
         if (clear) {
           // disable the button temporarily to indicate something happened
           let button = document.getElementById("prefs-clear-data");
           button.disabled = true;
           setTimeout(function() { button.disabled = false; }, 5000);
 
           Sanitizer.sanitize();
@@ -1147,20 +1159,20 @@ var BrowserUI = {
         // Zoom out (portrait) or in (landscape)
         Browser.zoom(Util.isPortrait() ? 1 : -1);
         break;
       case "cmd_lockscreen":
       {
         let locked = Services.prefs.getBoolPref("toolkit.screen.lock");
         Services.prefs.setBoolPref("toolkit.screen.lock", !locked);
 
-        let strings = Elements.browserBundle;
+        let strings = Strings.browser;
         let alerts = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
-        alerts.showAlertNotification(null, strings.getString("alertLockScreen"),
-                                     strings.getString("alertLockScreen." + (!locked ? "locked" : "unlocked")), false, "", null);
+        alerts.showAlertNotification(null, strings.GetStringFromName("alertLockScreen"),
+                                     strings.GetStringFromName("alertLockScreen." + (!locked ? "locked" : "unlocked")), false, "", null);
         break;
       }
     }
   }
 };
 
 var TapHighlightHelper = {
   get _overlay() {
@@ -1315,17 +1327,17 @@ var PageActions = {
 
     if (!this._loginManager.getLoginSavingEnabled(host.prePath)) {
       // If rememberSignons is false, then getLoginSavingEnabled returns false
       // for all pages, so we should just ignore it (Bug 601163).
       if (Services.prefs.getBoolPref("signon.rememberSignons"))
         permissions.push("pageactions.password");
     }
 
-    let descriptions = permissions.map(function(s) Elements.browserBundle.getString(s));
+    let descriptions = permissions.map(function(s) Strings.browser.GetStringFromName(s));
     aNode.setAttribute("description", descriptions.join(", "));
 
     return (permissions.length > 0);
   },
 
   updateForgetPassword: function updateForgetPassword(aNode) {
     let host = Browser.selectedBrowser.currentURI;
     let logins = this._loginManager.findLogins({}, host.prePath, "", "");
@@ -1392,19 +1404,18 @@ var PageActions = {
         if (i != 0)
           throw e;
         return;
       }
       file = attemptedFile;
       fileName = file.leafName;
     });
 #else
-    let strings = Elements.browserBundle;
     let picker = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
-    picker.init(window, strings.getString("pageactions.saveas.pdf"), Ci.nsIFilePicker.modeSave);
+    picker.init(window, Strings.browser.GetStringFromName("pageactions.saveas.pdf"), Ci.nsIFilePicker.modeSave);
     picker.appendFilter("PDF", "*.pdf");
     picker.defaultExtension = "pdf";
 
     picker.defaultString = fileName;
 
     picker.displayDirectory = downloadsDir;
     let rv = picker.show();
     if (rv == Ci.nsIFilePicker.returnCancel)
@@ -1501,17 +1512,17 @@ var NewTabPopup = {
       box.removeAttribute("left");
       box.setAttribute("right", margin);
     }
 
     return this.box = box;
   },
 
   _updateLabel: function nt_updateLabel() {
-    let newtabStrings = Elements.browserBundle.getString("newtabpopup.opened");
+    let newtabStrings = Strings.browser.GetStringFromName("newtabpopup.opened");
     let label = PluralForm.get(this._tabs.length, newtabStrings).replace("#1", this._tabs.length);
 
     this.box.firstChild.setAttribute("value", label);
   },
 
   hide: function nt_hide() {
     if (this._timeout) {
       clearTimeout(this._timeout);
--- a/mobile/chrome/content/browser.js
+++ b/mobile/chrome/content/browser.js
@@ -386,21 +386,21 @@ var Browser = {
       let button = document.getElementById("tool-console");
       button.hidden = false;
     }
 
     // If some add-ons were disabled during during an application update, alert user
     if (Services.prefs.prefHasUserValue("extensions.disabledAddons")) {
       let addons = Services.prefs.getCharPref("extensions.disabledAddons").split(",");
       if (addons.length > 0) {
-        let disabledStrings = Elements.browserBundle.getString("alertAddonsDisabled");
+        let disabledStrings = Strings.browser.GetStringFromName("alertAddonsDisabled");
         let label = PluralForm.get(addons.length, disabledStrings).replace("#1", addons.length);
 
         let alerts = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
-        alerts.showAlertNotification(URI_GENERIC_ICON_XPINSTALL, Elements.browserBundle.getString("alertAddons"),
+        alerts.showAlertNotification(URI_GENERIC_ICON_XPINSTALL, Strings.browser.GetStringFromName("alertAddons"),
                                      label, false, "", null);
       }
       Services.prefs.clearUserPref("extensions.disabledAddons");
     }
 
     messageManager.addMessageListener("Browser:ViewportMetadata", this);
     messageManager.addMessageListener("Browser:FormSubmit", this);
     messageManager.addMessageListener("Browser:KeyPress", this);
@@ -426,22 +426,22 @@ var Browser = {
     if (numTabs > 1) {
       let shouldPrompt = Services.prefs.getBoolPref("browser.tabs.warnOnClose");
       if (shouldPrompt) {
         let prompt = Services.prompt;
 
         // Default to true: if it were false, we wouldn't get this far
         let warnOnClose = { value: true };
 
-        let messageBase = Elements.browserBundle.getString("tabs.closeWarning");
+        let messageBase = Strings.browser.GetStringFromName("tabs.closeWarning");
         let message = PluralForm.get(numTabs, messageBase).replace("#1", numTabs);
 
-        let title = Elements.browserBundle.getString("tabs.closeWarningTitle");
-        let closeText = Elements.browserBundle.getString("tabs.closeButton");
-        let checkText = Elements.browserBundle.getString("tabs.closeWarningPromptMe");
+        let title = Strings.browser.GetStringFromName("tabs.closeWarningTitle");
+        let closeText = Strings.browser.GetStringFromName("tabs.closeButton");
+        let checkText = Strings.browser.GetStringFromName("tabs.closeWarningPromptMe");
         let buttons = (prompt.BUTTON_TITLE_IS_STRING * prompt.BUTTON_POS_0) +
                       (prompt.BUTTON_TITLE_CANCEL * prompt.BUTTON_POS_1);
 
         this._waitingToClose = true;
         let pressed = prompt.confirmEx(window, title, message, buttons, closeText, null, null, checkText, warnOnClose);
         this._waitingToClose = false;
 
         // Don't set the pref unless they press OK and it's false
@@ -1741,23 +1741,23 @@ ContentCustomKeySender.prototype = {
 
 
 /**
  * Utility class to handle manipulations of the identity indicators in the UI
  */
 function IdentityHandler() {
   this._staticStrings = {};
   this._staticStrings[this.IDENTITY_MODE_DOMAIN_VERIFIED] = {
-    encryption_label: Elements.browserBundle.getString("identity.encrypted2")
+    encryption_label: Strings.browser.GetStringFromName("identity.encrypted2")
   };
   this._staticStrings[this.IDENTITY_MODE_IDENTIFIED] = {
-    encryption_label: Elements.browserBundle.getString("identity.encrypted2")
+    encryption_label: Strings.browser.GetStringFromName("identity.encrypted2")
   };
   this._staticStrings[this.IDENTITY_MODE_UNKNOWN] = {
-    encryption_label: Elements.browserBundle.getString("identity.unencrypted2")
+    encryption_label: Strings.browser.GetStringFromName("identity.unencrypted2")
   };
 
   // Close the popup when reloading the page
   Elements.browsers.addEventListener("URLChanged", this, true);
 
   this._cacheElements();
 }
 
@@ -1847,48 +1847,46 @@ IdentityHandler.prototype = {
 
   /**
    * Set up the messages for the primary identity UI based on the specified mode,
    * and the details of the SSL cert, where applicable
    *
    * @param newMode The newly set identity mode.  Should be one of the IDENTITY_MODE_* constants.
    */
   setIdentityMessages: function(newMode) {
-    let strings = Elements.browserBundle;
+    let strings = Strings.browser;
 
     if (newMode == this.IDENTITY_MODE_DOMAIN_VERIFIED) {
       var iData = this.getIdentityData();
 
       // We need a port number for all lookups.  If one hasn't been specified, use
       // the https default
       var lookupHost = this._lastLocation.host;
       if (lookupHost.indexOf(':') < 0)
         lookupHost += ":443";
 
       // Cache the override service the first time we need to check it
       if (!this._overrideService)
         this._overrideService = Cc["@mozilla.org/security/certoverride;1"].getService(Ci.nsICertOverrideService);
 
       // Verifier is either the CA Org, for a normal cert, or a special string
       // for certs that are trusted because of a security exception.
-      var tooltip = strings.getFormattedString("identity.identified.verifier",
-                                               [iData.caOrg]);
+      var tooltip = strings.formatStringFromName("identity.identified.verifier", [iData.caOrg], 1);
 
       // Check whether this site is a security exception.
       if (iData.isException)
-        tooltip = strings.getString("identity.identified.verified_by_you");
+        tooltip = strings.GetStringFromName("identity.identified.verified_by_you");
     }
     else if (newMode == this.IDENTITY_MODE_IDENTIFIED) {
       // If it's identified, then we can populate the dialog with credentials
       iData = this.getIdentityData();
-      tooltip = strings.getFormattedString("identity.identified.verifier",
-                                           [iData.caOrg]);
+      tooltip = strings.formatStringFromName("identity.identified.verifier", [iData.caOrg], 1);
     }
     else {
-      tooltip = strings.getString("identity.unknown.tooltip");
+      tooltip = strings.GetStringFromName("identity.unknown.tooltip");
     }
 
     // Push the appropriate strings out to the UI
     this._identityBox.tooltipText = tooltip;
   },
 
   /**
    * Set up the title and content messages for the identity message popup,
@@ -1903,44 +1901,40 @@ IdentityHandler.prototype = {
 
     // Set the static strings up front
     this._identityPopupEncLabel.textContent = this._staticStrings[newMode].encryption_label;
 
     // Initialize the optional strings to empty values
     var supplemental = "";
     var verifier = "";
 
-    let strings = Elements.browserBundle;
-
     if (newMode == this.IDENTITY_MODE_DOMAIN_VERIFIED) {
       var iData = this.getIdentityData();
       var host = this.getEffectiveHost();
-      var owner = strings.getString("identity.ownerUnknown2");
+      var owner = strings.GetStringFromName("identity.ownerUnknown2");
       verifier = this._identityBox.tooltipText;
       supplemental = "";
     }
     else if (newMode == this.IDENTITY_MODE_IDENTIFIED) {
       // If it's identified, then we can populate the dialog with credentials
       iData = this.getIdentityData();
       host = this.getEffectiveHost();
       owner = iData.subjectOrg;
       verifier = this._identityBox.tooltipText;
 
       // Build an appropriate supplemental block out of whatever location data we have
       if (iData.city)
         supplemental += iData.city + " ";
       if (iData.state && iData.country)
-        supplemental += strings.getFormattedString("identity.identified.state_and_country",
-                                                   [iData.state, iData.country]);
+        supplemental += Strings.browser.formatStringFromName("identity.identified.state_and_country", [iData.state, iData.country], 2);
       else if (iData.state) // State only
         supplemental += iData.state;
       else if (iData.country) // Country only
         supplemental += iData.country;
-    }
-    else {
+    } else {
       // These strings will be hidden in CSS anyhow
       host = "";
       owner = "";
     }
 
     // Push the appropriate strings out to the UI
     this._identityPopupContentHost.textContent = host;
     this._identityPopupContentOwner.textContent = owner;
@@ -2039,46 +2033,45 @@ var PopupBlockerObserver = {
     if (result == Ci.nsIPermissionManager.DENY_ACTION)
       return;
 
     // Only show the notification again if we've not already shown it. Since
     // notifications are per-browser, we don't need to worry about re-adding
     // it.
     if (!cBrowser.pageReport.reported) {
       if (Services.prefs.getBoolPref("privacy.popups.showBrowserMessage")) {
-        var brandBundle = document.getElementById("bundle_brand");
-        var brandShortName = brandBundle.getString("brandShortName");
+        var brandShortName = Strings.brand.GetStringFromName("brandShortName");
         var message;
         var popupCount = cBrowser.pageReport.length;
 
-        let strings = Elements.browserBundle;
+        let strings = Strings.browser;
         if (popupCount > 1)
-          message = strings.getFormattedString("popupWarningMultiple", [brandShortName, popupCount]);
+          message = strings.formatStringFromName("popupWarningMultiple", [brandShortName, popupCount], 2);
         else
-          message = strings.getFormattedString("popupWarning", [brandShortName]);
+          message = strings.formatStringFromName("popupWarning", [brandShortName], 1);
 
         var notificationBox = Browser.getNotificationBox();
         var notification = notificationBox.getNotificationWithValue("popup-blocked");
         if (notification) {
           notification.label = message;
         }
         else {
           var buttons = [
             {
-              label: strings.getString("popupButtonAllowOnce"),
+              label: strings.GetStringFromName("popupButtonAllowOnce"),
               accessKey: null,
               callback: function() { PopupBlockerObserver.showPopupsForSite(); }
             },
             {
-              label: strings.getString("popupButtonAlwaysAllow2"),
+              label: strings.GetStringFromName("popupButtonAlwaysAllow2"),
               accessKey: null,
               callback: function() { PopupBlockerObserver.allowPopupsForSite(true); }
             },
             {
-              label: strings.getString("popupButtonNeverWarn2"),
+              label: strings.GetStringFromName("popupButtonNeverWarn2"),
               accessKey: null,
               callback: function() { PopupBlockerObserver.allowPopupsForSite(false); }
             }
           ];
 
           const priority = notificationBox.PRIORITY_WARNING_MEDIUM;
           notificationBox.appendNotification(message, "popup-blocked",
                                              "",
@@ -2122,60 +2115,57 @@ var PopupBlockerObserver = {
       }
     }
   }
 };
 
 var XPInstallObserver = {
   observe: function xpi_observer(aSubject, aTopic, aData)
   {
-    var brandBundle = document.getElementById("bundle_brand");
     switch (aTopic) {
       case "addon-install-started":
-        var messageString = Elements.browserBundle.getString("alertAddonsDownloading");
+        var messageString = Strings.browser.GetStringFromName("alertAddonsDownloading");
         ExtensionsView.showAlert(messageString);
         break;
       case "addon-install-blocked":
         var installInfo = aSubject.QueryInterface(Ci.amIWebInstallInfo);
         var host = installInfo.originatingURI.host;
-        var brandShortName = brandBundle.getString("brandShortName");
+        var brandShortName = Strings.brand.GetStringFromName("brandShortName");
         var notificationName, messageString, buttons;
-        var strings = Elements.browserBundle;
+        var strings = Strings.browser;
         var enabled = true;
         try {
           enabled = Services.prefs.getBoolPref("xpinstall.enabled");
         }
         catch (e) {}
         if (!enabled) {
           notificationName = "xpinstall-disabled";
           if (Services.prefs.prefIsLocked("xpinstall.enabled")) {
-            messageString = strings.getString("xpinstallDisabledMessageLocked");
+            messageString = strings.GetStringFromName("xpinstallDisabledMessageLocked");
             buttons = [];
           }
           else {
-            messageString = strings.getFormattedString("xpinstallDisabledMessage",
-                                                             [brandShortName, host]);
+            messageString = strings.formatStringFromName("xpinstallDisabledMessage", [brandShortName, host], 2);
             buttons = [{
-              label: strings.getString("xpinstallDisabledButton"),
+              label: strings.GetStringFromName("xpinstallDisabledButton"),
               accessKey: null,
               popup: null,
               callback: function editPrefs() {
                 Services.prefs.setBoolPref("xpinstall.enabled", true);
                 return false;
               }
             }];
           }
         }
         else {
           notificationName = "xpinstall";
-          messageString = strings.getFormattedString("xpinstallPromptWarning",
-                                                           [brandShortName, host]);
+          messageString = strings.formatStringFromName("xpinstallPromptWarning", [brandShortName, host], 2);
 
           buttons = [{
-            label: strings.getString("xpinstallPromptAllowButton"),
+            label: strings.GetStringFromName("xpinstallPromptAllowButton"),
             accessKey: null,
             popup: null,
             callback: function() {
               // Kick off the install
               installInfo.install();
               return false;
             }
           }];
@@ -2247,21 +2237,21 @@ var ContentCrashObserver = {
     })
 
     let dumpID = aSubject.hasKey("dumpID") ? aSubject.getProperty("dumpID") : null;
 
     // Execute the UI prompt after the notification has had a chance to return and close the child process
     setTimeout(function(self) {
       // Ask the user if we should reload or close the current tab. Other tabs
       // will be reloaded when selected.
-      let title = Elements.browserBundle.getString("tabs.crashWarningTitle");
-      let message = Elements.browserBundle.getString("tabs.crashWarningMsg");
-      let submitText = Elements.browserBundle.getString("tabs.crashSubmitReport");
-      let reloadText = Elements.browserBundle.getString("tabs.crashReload");
-      let closeText = Elements.browserBundle.getString("tabs.crashClose");
+      let title = Strings.browser.GetStringFromName("tabs.crashWarningTitle");
+      let message = Strings.browser.GetStringFromName("tabs.crashWarningMsg");
+      let submitText = Strings.browser.GetStringFromName("tabs.crashSubmitReport");
+      let reloadText = Strings.browser.GetStringFromName("tabs.crashReload");
+      let closeText = Strings.browser.GetStringFromName("tabs.crashClose");
       let buttons = Ci.nsIPrompt.BUTTON_POS_1_DEFAULT +
                     (Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_0) +
                     (Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_1);
 
       // Only show the submit checkbox if we have a crash report we can submit
       if (!dumpID)
         submitText = null;
 
@@ -2588,44 +2578,43 @@ var OfflineApps = {
       // this pref isn't set by default, ignore failures
     }
 
     let host = currentURI.asciiHost;
     let notificationID = "offline-app-requested-" + host;
     let notificationBox = Browser.getNotificationBox();
 
     let notification = notificationBox.getNotificationWithValue(notificationID);
-    let strings = Elements.browserBundle;
+    let strings = Strings.browser;
     if (notification) {
       notification.documents.push(aRequest);
     } else {
       let buttons = [{
-        label: strings.getString("offlineApps.allow"),
+        label: strings.GetStringFromName("offlineApps.allow"),
         accessKey: null,
         callback: function() {
           for (let i = 0; i < notification.documents.length; i++)
             OfflineApps.allowSite(notification.documents[i], aTarget);
         }
       },{
-        label: strings.getString("offlineApps.never"),
+        label: strings.GetStringFromName("offlineApps.never"),
         accessKey: null,
         callback: function() {
           for (let i = 0; i < notification.documents.length; i++)
             OfflineApps.disallowSite(notification.documents[i]);
         }
       },{
-        label: strings.getString("offlineApps.notNow"),
+        label: strings.GetStringFromName("offlineApps.notNow"),
         accessKey: null,
         callback: function() { /* noop */ }
       }];
 
       const priority = notificationBox.PRIORITY_INFO_LOW;
-      let message = strings.getFormattedString("offlineApps.available", [host]);
-      notification = notificationBox.appendNotification(message, notificationID,
-                                                        "", priority, buttons);
+      let message = strings.formatStringFromName("offlineApps.available", [host], 1);
+      notification = notificationBox.appendNotification(message, notificationID, "", priority, buttons);
       notification.documents = [aRequest];
     }
   },
 
   allowSite: function(aRequest, aTarget) {
     let currentURI = Services.io.newURI(aRequest.location, aRequest.charset, null);
     Services.perms.add(currentURI, "offline-app", Ci.nsIPermissionManager.ALLOW_ACTION);
 
--- a/mobile/chrome/content/browser.xul
+++ b/mobile/chrome/content/browser.xul
@@ -89,21 +89,16 @@
   <script type="application/javascript" src="chrome://browser/content/console.js"/>
   <script type="application/javascript" src="chrome://browser/content/Util.js"/>
   <script type="application/javascript" src="chrome://browser/content/input.js"/>
   <script type="application/javascript" src="chrome://browser/content/AnimatedZoom.js"/>
 #ifdef MOZ_SERVICES_SYNC
   <script type="application/javascript" src="chrome://browser/content/sync.js"/>
 #endif
 
-  <stringbundleset id="stringbundleset">
-    <stringbundle id="bundle_browser" src="chrome://browser/locale/browser.properties"/>
-    <stringbundle id="bundle_brand" src="chrome://branding/locale/brand.properties"/>
-  </stringbundleset>
-
   <broadcasterset id="broadcasterset">
     <broadcaster id="bcast_contentShowing"/>
     <broadcaster id="bcast_urlbarState" mode="view"/>
   </broadcasterset>
 
   <observerset id="observerset">
     <observes id="observe_contentShowing" element="bcast_contentShowing" attribute="disabled" onbroadcast="BrowserUI.updateUIFocus();"/>
   </observerset>
--- a/mobile/chrome/content/console.js
+++ b/mobile/chrome/content/console.js
@@ -45,17 +45,17 @@ let ConsoleView = {
   _showChromeErrors: -1,
 
   init: function cv_init() {
     if (this._list)
       return;
 
     this._list = document.getElementById("console-box");
     this._evalTextbox = document.getElementById("console-eval-textbox");
-    this._bundle = Elements.browserBundle;
+    this._bundle = Strings.browser;
 
     this._count = 0;
     this.limit = 250;
 
     let self = this;
     let panels = document.getElementById("panel-items");
 
     panels.addEventListener("select",
@@ -137,17 +137,17 @@ let ConsoleView = {
   appendError: function cv_appendError(aObject) {
     let row = this.createConsoleRow();
     let nsIScriptError = Ci.nsIScriptError;
 
     // Is this error actually just a non-fatal warning?
     let warning = aObject.flags & nsIScriptError.warningFlag != 0;
 
     let typetext = warning ? "typeWarning" : "typeError";
-    row.setAttribute("typetext", this._bundle.getString(typetext));
+    row.setAttribute("typetext", this._bundle.GetStringFromName(typetext));
     row.setAttribute("type", warning ? "warning" : "error");
     row.setAttribute("msg", aObject.errorMessage);
     row.setAttribute("category", aObject.category);
     if (aObject.lineNumber || aObject.sourceName) {
       row.setAttribute("href", aObject.sourceName);
       row.setAttribute("line", aObject.lineNumber);
     }
     else {
--- a/mobile/chrome/content/downloads.js
+++ b/mobile/chrome/content/downloads.js
@@ -112,17 +112,17 @@ var DownloadsView = {
     let header = document.getElementById("downloads-list-header");
     while (header.nextSibling)
       this._list.removeChild(header.nextSibling);
   },
   
   _ifEmptyShowMessage: function dv__ifEmptyShowMessage() {
     // The header row is not counted in the list itemCount
     if (this._list.itemCount == 0) {
-      let emptyString = Elements.browserBundle.getString("downloadsEmpty");
+      let emptyString = Strings.browser.GetStringFromName("downloadsEmpty");
       let emptyItem = this._list.appendItem(emptyString);
       emptyItem.id = "dl-empty-message";
     }
   },
 
   get visible() {
     let items = document.getElementById("panel-items");
     if (BrowserUI.isPanelVisible() && items.selectedPanel.id == "downloads-container")
@@ -289,46 +289,46 @@ var DownloadsView = {
     while (next && next.inProgress)
       next = next.nextSibling;
 
     // Move the item
     this._list.insertBefore(element, next);
   },
 
   _updateStatus: function dv__updateStatus(aItem) {
-    let strings = Elements.browserBundle;
+    let strings = Strings.browser;
 
     let status = "";
 
     // Display the file size, but show "Unknown" for negative sizes
     let fileSize = Number(aItem.getAttribute("maxBytes"));
-    let sizeText = strings.getString("downloadsUnknownSize");
+    let sizeText = strings.GetStringFromName("downloadsUnknownSize");
     if (fileSize >= 0) {
       let [size, unit] = DownloadUtils.convertByteUnits(fileSize);
-      sizeText = this._replaceInsert(strings.getString("downloadsKnownSize"), 1, size);
+      sizeText = this._replaceInsert(strings.GetStringFromName("downloadsKnownSize"), 1, size);
       sizeText = this._replaceInsert(sizeText, 2, unit);
     }
 
     // Insert 1 is the download size
-    status = this._replaceInsert(strings.getString("downloadsStatus"), 1, sizeText);
+    status = this._replaceInsert(strings.GetStringFromName("downloadsStatus"), 1, sizeText);
 
     // Insert 2 is the eTLD + 1 or other variations of the host
     let [displayHost, fullHost] = DownloadUtils.getURIHost(this._getReferrerOrSource(aItem));
     status = this._replaceInsert(status, 2, displayHost);
   
     // Insert 3 is the left time if download status is DOWNLOADING
     let currstate = Number(aItem.getAttribute("state"));
     if (currstate == Ci.nsIDownloadManager.DOWNLOAD_DOWNLOADING) {
       let downloadSize = Number(aItem.getAttribute("currBytes"));
       let passedTime = (Date.now() - aItem.getAttribute("startTime"))/1000;
       let totalTime = (passedTime / downloadSize) * fileSize;
       let leftTime = totalTime - passedTime;
       let [time, lastTime] = DownloadUtils.getTimeLeft(leftTime);
 
-      let stringTime = this._replaceInsert(strings.getString("downloadsTime"), 1, time);
+      let stringTime = this._replaceInsert(strings.GetStringFromName("downloadsTime"), 1, time);
       status = status + " " + stringTime;
     } 
       
     aItem.setAttribute("status", status);
   },
 
   _updateTime: function dv__updateTime(aItem) {
     // Don't bother updating for things that aren't finished
@@ -339,38 +339,38 @@ var DownloadsView = {
 
     // Figure out when today begins
     let now = new Date();
     let today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
 
     // Get the end time to display
     let end = new Date(parseInt(aItem.getAttribute("endTime")));
 
-    let strings = Elements.browserBundle;
+    let strings = Strings.browser;
 
     // Figure out if the end time is from today, yesterday, this week, etc.
     let dateTime;
     if (end >= today) {
       // Download finished after today started, show the time
       dateTime = dts.FormatTime("", dts.timeFormatNoSeconds, end.getHours(), end.getMinutes(), 0);
     }
     else if (today - end < (24 * 60 * 60 * 1000)) {
       // Download finished after yesterday started, show yesterday
-      dateTime = strings.getString("donwloadsYesterday");
+      dateTime = strings.GetStringFromName("donwloadsYesterday");
     }
     else if (today - end < (6 * 24 * 60 * 60 * 1000)) {
       // Download finished after last week started, show day of week
       dateTime = end.toLocaleFormat("%A");
     }
     else {
       // Download must have been from some time ago.. show month/day
       let month = end.toLocaleFormat("%B");
       // Remove leading 0 by converting the date string to a number
       let date = Number(end.toLocaleFormat("%d"));
-      dateTime = this._replaceInsert(strings.getString("downloadsMonthDate"), 1, month);
+      dateTime = this._replaceInsert(strings.GetStringFromName("downloadsMonthDate"), 1, month);
       dateTime = this._replaceInsert(dateTime, 2, date);
     }
 
     aItem.setAttribute("datetime", dateTime);
   },
 
   _replaceInsert: function dv__replaceInsert(aText, aIndex, aValue) {
     return aText.replace("#" + aIndex, aValue);
@@ -385,19 +385,18 @@ var DownloadsView = {
     try {
       f.launch();
     } catch (ex) { }
 
     // TODO: add back the code for "dontAsk"?
   },
 
   removeDownload: function dv_removeDownload(aItem) {
-    let strings = Elements.browserBundle;
     let f = this._getLocalFile(aItem.getAttribute("file"));
-    let res = Services.prompt.confirm(null, strings.getString("downloadsDeleteTitle"), f.leafName);
+    let res = Services.prompt.confirm(null, Strings.browser.GetStringFromName("downloadsDeleteTitle"), f.leafName);
     if(res) {
       this._dlmgr.removeDownload(aItem.getAttribute("downloadID"));
       if (f.exists())
           f.remove(false);
     }
   },
 
   cancelDownload: function dv_cancelDownload(aItem) {
@@ -434,20 +433,19 @@ var DownloadsView = {
 
     // Callback for tapping on the alert popup
     let observer = {
       observe: function (aSubject, aTopic, aData) {
         if (aTopic == "alertclickcallback")
           BrowserUI.showPanel("downloads-container");
       }
     };
-    let strings = Elements.browserBundle;
-    
+
     if (!aTitle)
-      aTitle = strings.getString("alertDownloads");
+      aTitle = Strings.browser.GetStringFromName("alertDownloads");
     if (!aIcon)
       aIcon = URI_GENERIC_ICON_DOWNLOAD;
 
     notifier.showAlertNotification(aIcon, aTitle, aMessage, true, "", observer, aName);
   },
 
   observe: function (aSubject, aTopic, aData) {
     if (aTopic == "download-manager-remove-download") {
@@ -463,34 +461,33 @@ var DownloadsView = {
       let element = this.getElementForDownload(id.data);
       this._removeItem(element);
 
       // Show empty message if needed
       this._ifEmptyShowMessage();
     }
     else {
       let download = aSubject.QueryInterface(Ci.nsIDownload);
-      let strings = Elements.browserBundle;
       let msgKey = "";
 
       if (aTopic == "dl-start") {
         msgKey = "alertDownloadsStart";
         if (!this._progressAlert) {
           if (!this._dlmgr)
             this._dlmgr = Cc["@mozilla.org/download-manager;1"].getService(Ci.nsIDownloadManager);
           this._progressAlert = new AlertDownloadProgressListener();
           this._dlmgr.addListener(this._progressAlert);
         }
       } else if (aTopic == "dl-done") {
         msgKey = "alertDownloadsDone";
       }
 
       if (msgKey)
         this.showAlert(download.target.spec.replace("file:", "download:"),
-                       strings.getFormattedString(msgKey, [download.displayName]));
+                       Strings.browser.formatStringFromName(msgKey, [download.displayName], 1));
     }
   },
 
   QueryInterface: function (aIID) {
     if (!aIID.equals(Ci.nsIObserver) &&
         !aIID.equals(Ci.nsISupportsWeakReference) &&
         !aIID.equals(Ci.nsISupports))
       throw Components.results.NS_ERROR_NO_INTERFACE;
@@ -588,27 +585,27 @@ DownloadProgressListener.prototype = {
 
 // AlertDownloadProgressListener is used to display progress in the alert notifications.
 function AlertDownloadProgressListener() { }
 
 AlertDownloadProgressListener.prototype = {
   //////////////////////////////////////////////////////////////////////////////
   //// nsIDownloadProgressListener
   onProgressChange: function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress, aDownload) {
-    let strings = Elements.browserBundle;
+    let strings = Strings.browser;
     let availableSpace = -1;
     try {
       // diskSpaceAvailable is not implemented on all systems
       let availableSpace = aDownload.targetFile.diskSpaceAvailable;
     } catch(ex) { }
     let contentLength = aDownload.size;
     if (availableSpace > 0 && contentLength > 0 && contentLength > availableSpace) {
       DownloadsView.showAlert(aDownload.target.spec.replace("file:", "download:"),
-                              strings.getString("alertDownloadsNoSpace"),
-                              strings.getString("alertDownloadsSize"));
+                              strings.GetStringFromName("alertDownloadsNoSpace"),
+                              strings.GetStringFromName("alertDownloadsSize"));
 
       Cc["@mozilla.org/download-manager;1"].getService(Ci.nsIDownloadManager).cancelDownload(aDownload.id);
     }
 
 #ifdef ANDROID
     if (aDownload.percentComplete == -1) {
       // Undetermined progress is not supported yet
       return;
--- a/mobile/chrome/content/extensions.js
+++ b/mobile/chrome/content/extensions.js
@@ -154,20 +154,20 @@ var ExtensionsView = {
     // Increment the count in case the view is not completely initialized
     this._restartCount++;
 
     // Pick the right message key from the properties file
     aMode = aMode || "normal";
 
     if (this._msg) {
       this.hideAlerts();
-      let strings = Elements.browserBundle;
+      let strings = Strings.browser;
       let message = "notificationRestart." + aMode;
-      this.showMessage(strings.getString(message), "restart-app",
-                       strings.getString("notificationRestart.button"), false, "addons-restart-app");
+      this.showMessage(strings.GetStringFromName(message), "restart-app",
+                       strings.GetStringFromName("notificationRestart.button"), false, "addons-restart-app");
     }
   },
 
   hideRestart: function ev_hideRestart() {
     this._restartCount--;
     if (this._restartCount == 0 && this._msg) {
       let notification = this._msg.getNotificationWithValue("restart-app");
       if (notification)
@@ -246,21 +246,21 @@ var ExtensionsView = {
     // Show the restart notification in case a restart is needed, but the view
     // was not visible at the time
     let notification = this._msg.getNotificationWithValue("restart-app");
     if (this._restartCount > 0 && !notification) {
       this.showRestart();
       this._restartCount--; // showRestart() always increments
     }
 
-    let strings = Elements.browserBundle;
-    this._strings["addonType.extension"] = strings.getString("addonType.2");
-    this._strings["addonType.theme"] = strings.getString("addonType.4");
-    this._strings["addonType.locale"] = strings.getString("addonType.8");
-    this._strings["addonType.search"] = strings.getString("addonType.1024");
+    let strings = Strings.browser;
+    this._strings["addonType.extension"] = strings.GetStringFromName("addonType.2");
+    this._strings["addonType.theme"] = strings.GetStringFromName("addonType.4");
+    this._strings["addonType.locale"] = strings.GetStringFromName("addonType.8");
+    this._strings["addonType.search"] = strings.GetStringFromName("addonType.1024");
 
     let self = this;
     setTimeout(function() {
       self.getAddonsFromLocal();
       self.getAddonsFromRepo("");
     }, 0);
   },
 
@@ -278,35 +278,35 @@ var ExtensionsView = {
       this.hideOptions();
   },
 
   getAddonsFromLocal: function ev_getAddonsFromLocal() {
     this.clearSection("local");
 
     let self = this;
     AddonManager.getAddonsByTypes(["extension", "theme", "locale"], function(items) {
-      let strings = Elements.browserBundle;
+      let strings = Strings.browser;
       let anyUpdateable = false;
       for (let i = 0; i < items.length; i++) {
         let addon = items[i];
         let appManaged = (addon.scope == AddonManager.SCOPE_APPLICATION);
         let opType = self._getOpTypeForOperations(addon.pendingOperations);
         let updateable = (addon.permissions & AddonManager.PERM_CAN_UPGRADE) > 0;
         let uninstallable = (addon.permissions & AddonManager.PERM_CAN_UNINSTALL) > 0;
 
         let blocked = "";
         switch(addon.blocklistState) {
           case Ci.nsIBlocklistService.STATE_BLOCKED:
-            blocked = strings.getString("addonBlocked.blocked")
+            blocked = strings.GetStringFromName("addonBlocked.blocked")
             break;
           case Ci.nsIBlocklistService.STATE_SOFTBLOCKED:
-            blocked = strings.getString("addonBlocked.softBlocked");
+            blocked = strings.GetStringFromName("addonBlocked.softBlocked");
             break;
           case Ci.nsIBlocklistService.STATE_OUTDATED:
-            blocked = srings.getString("addonBlocked.outdated");
+            blocked = srings.GetStringFromName("addonBlocked.outdated");
             break;
         }            
 
         if (updateable)
           anyUpdateable = true;
 
         let listitem = self._createItem(addon, "local");
         listitem.setAttribute("isDisabled", !addon.isActive);
@@ -323,17 +323,17 @@ var ExtensionsView = {
         self._list.insertBefore(listitem, self._repoItem);
       }
 
       // Load the search engines
       let defaults = Services.search.getDefaultEngines({ }).map(function (e) e.name);
       function isDefault(aEngine)
         defaults.indexOf(aEngine.name) != -1
 
-      let defaultDescription = strings.getString("addonsSearchEngine.description");
+      let defaultDescription = strings.GetStringFromName("addonsSearchEngine.description");
 
       let engines = Services.search.getEngines({ });
       for (let e = 0; e < engines.length; e++) {
         let engine = engines[e];
         let addon = {};
         addon.id = engine.name;
         addon.type = "search";
         addon.name = engine.name;
@@ -348,17 +348,17 @@ var ExtensionsView = {
         listitem.setAttribute("description", engine.description || defaultDescription);
         listitem.setAttribute("optionsURL", "");
         listitem.setAttribute("opType", engine.hidden ? "needs-disable" : "");
         listitem.setAttribute("updateable", "false");
         self._list.insertBefore(listitem, self._repoItem);
       }
 
       if (engines.length + items.length == 0)
-        self.displaySectionMessage("local", strings.getString("addonsLocalNone.label"), null, true);
+        self.displaySectionMessage("local", strings.GetStringFromName("addonsLocalNone.label"), null, true);
 
       if (!anyUpdateable)
         document.getElementById("addons-update-all").disabled = true;
     });
   },
 
   enable: function ev_enable(aItem) {
     let opType;
@@ -494,24 +494,24 @@ var ExtensionsView = {
     this.clearSection("repo");
 
     // Make sure we're online before attempting to load
     Util.forceOnline();
 
     if (AddonRepository.isSearching)
       AddonRepository.cancelSearch();
 
-    let strings = Elements.browserBundle;
+    let strings = Strings.browser;
     if (aTerms) {
       AddonSearchResults.selectFirstResult = aSelectFirstResult;
-      this.displaySectionMessage("repo", strings.getString("addonsSearchStart.label"), strings.getString("addonsSearchStart.button"), false);
+      this.displaySectionMessage("repo", strings.GetStringFromName("addonsSearchStart.label"), strings.GetStringFromName("addonsSearchStart.button"), false);
       AddonRepository.searchAddons(aTerms, Services.prefs.getIntPref(PREF_GETADDONS_MAXRESULTS), AddonSearchResults);
     }
     else {
-      this.displaySectionMessage("repo", strings.getString("addonsSearchStart.label"), strings.getString("addonsSearchStart.button"), false);
+      this.displaySectionMessage("repo", strings.GetStringFromName("addonsSearchStart.label"), strings.GetStringFromName("addonsSearchStart.button"), false);
       AddonRepository.retrieveRecommendedAddons(Services.prefs.getIntPref(PREF_GETADDONS_MAXRESULTS), RecommendedSearchResults);
     }
   },
 
   appendSearchResults: function(aAddons, aShowRating, aShowCount) {
     let urlproperties = [ "iconURL", "homepageURL" ];
     let foundItem = false;
     for (let i = 0; i < aAddons.length; i++) {
@@ -576,35 +576,34 @@ var ExtensionsView = {
   },
 
   displayRecommendedResults: function ev_displaySearchResults(aRecommendedAddons, aBrowseAddons) {
     this.clearSection("repo");
 
     let formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].getService(Ci.nsIURLFormatter);
     let browseURL = formatter.formatURLPref("extensions.getAddons.browseAddons");
 
-    let strings = Elements.browserBundle;
-    let brandBundle = document.getElementById("bundle_brand");
-    let brandShortName = brandBundle.getString("brandShortName");
+    let strings = Strings.browser;
+    let brandShortName = Strings.brand.GetStringFromName("brandShortName");
 
     let whatare = document.createElement("richlistitem");
     whatare.setAttribute("typeName", "banner");
-    whatare.setAttribute("label", strings.getString("addonsWhatAre.label"));
+    whatare.setAttribute("label", strings.GetStringFromName("addonsWhatAre.label"));
 
-    let desc = strings.getString("addonsWhatAre.description");
+    let desc = strings.GetStringFromName("addonsWhatAre.description");
     desc = desc.replace(/#1/g, brandShortName);
     whatare.setAttribute("description", desc);
 
-    whatare.setAttribute("button", strings.getString("addonsWhatAre.button"));
+    whatare.setAttribute("button", strings.GetStringFromName("addonsWhatAre.button"));
     whatare.setAttribute("onbuttoncommand", "BrowserUI.newTab('" + browseURL + "');");
     this._list.appendChild(whatare);
 
     if (aRecommendedAddons.length == 0 && aBrowseAddons.length == 0) {
-      let msg = strings.getString("addonsSearchNone.recommended");
-      let button = strings.getString("addonsSearchNone.button");
+      let msg = strings.GetStringFromName("addonsSearchNone.recommended");
+      let button = strings.GetStringFromName("addonsSearchNone.button");
       let item = this.displaySectionMessage("repo", msg, button, true);
 
       this._list.scrollBoxObject.scrollToElement(item);
       return;
     }
 
     // Locale sensitive sort
     function nameCompare(a, b) {
@@ -622,35 +621,35 @@ var ExtensionsView = {
     // can see more by pressing the "Show More" button
     this.appendSearchResults(aRecommendedAddons, false, aRecommendedAddons.length);
     this.appendSearchResults(aBrowseAddons, true, (aRecommendedAddons.length >= kAddonPageSize ? 0 : kAddonPageSize));
 
     let totalAddons = aRecommendedAddons.length + aBrowseAddons.length;
 
     let showmore = document.createElement("richlistitem");
     showmore.setAttribute("typeName", "showmore");
-    showmore.setAttribute("pagelabel", strings.getString("addonsBrowseAll.seeMore"));
+    showmore.setAttribute("pagelabel", strings.GetStringFromName("addonsBrowseAll.seeMore"));
     showmore.setAttribute("onpagecommand", "ExtensionsView.showMoreSearchResults();");
     showmore.setAttribute("hidepage", totalAddons > kAddonPageSize ? "false" : "true");
-    showmore.setAttribute("sitelabel", strings.getString("addonsBrowseAll.browseSite"));
+    showmore.setAttribute("sitelabel", strings.GetStringFromName("addonsBrowseAll.browseSite"));
     showmore.setAttribute("onsitecommand", "ExtensionsView.showMoreResults('" + browseURL + "');");
     this._list.appendChild(showmore);
 
     let evt = document.createEvent("Events");
     evt.initEvent("ViewChanged", true, false);
     this._list.dispatchEvent(evt);
   },
 
   displaySearchResults: function ev_displaySearchResults(aAddons, aTotalResults, aSelectFirstResult) {
     this.clearSection("repo");
 
-    let strings = Elements.browserBundle;
+    let strings = Strings.browser;
     if (aAddons.length == 0) {
-      let msg = strings.getString("addonsSearchNone.search");
-      let button = strings.getString("addonsSearchSuccess2.button");
+      let msg = strings.GetStringFromName("addonsSearchNone.search");
+      let button = strings.GetStringFromName("addonsSearchSuccess2.button");
       let item = this.displaySectionMessage("repo", msg, button, true);
 
       if (aSelectFirstResult)
         this._list.scrollBoxObject.scrollToElement(item);
       return;
     }
 
     let firstItem = this.appendSearchResults(aAddons, true);
@@ -661,29 +660,29 @@ var ExtensionsView = {
 
     let formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].getService(Ci.nsIURLFormatter);
 
     if (aTotalResults > aAddons.length) {
       let showmore = document.createElement("richlistitem");
       showmore.setAttribute("typeName", "showmore");
       showmore.setAttribute("hidepage", "true");
 
-      let labelBase = strings.getString("addonsSearchMore.label");
+      let labelBase = strings.GetStringFromName("addonsSearchMore.label");
       let label = PluralForm.get(aTotalResults, labelBase).replace("#1", aTotalResults);
 
       showmore.setAttribute("sitelabel", label);
 
       let url = Services.prefs.getCharPref("extensions.getAddons.search.browseURL");
       url = url.replace(/%TERMS%/g, encodeURIComponent(this.searchBox.value));
       url = formatter.formatURL(url);
       showmore.setAttribute("onsitecommand", "ExtensionsView.showMoreResults('" + url + "');");
       this._list.appendChild(showmore);
     }
 
-    this.displaySectionMessage("repo", null, strings.getString("addonsSearchSuccess2.button"), true);
+    this.displaySectionMessage("repo", null, strings.GetStringFromName("addonsSearchSuccess2.button"), true);
   },
 
   showPage: function ev_showPage(aItem) {
     let uri = aItem.getAttribute("homepageURL");
     if (uri)
       BrowserUI.newTab(uri);
   },
 
@@ -717,100 +716,101 @@ var ExtensionsView = {
 
   observe: function ev_observe(aSubject, aTopic, aData) {
     if (!document)
       return;
 
     let json = aSubject.QueryInterface(Ci.nsISupportsString).data;
     let update = JSON.parse(json);
 
-    let strings = Elements.browserBundle;
+    let strings = Strings.browser;
     let element = this.getElementForAddon(update.id);
     if (!element)
       return;
 
     let addon = element.addon;
 
     switch (aTopic) {
       case "addon-update-started":
-        element.setAttribute("updateStatus", strings.getString("addonUpdate.checking"));
+        element.setAttribute("updateStatus", strings.GetStringFromName("addonUpdate.checking"));
         break;
       case "addon-update-ended":
         let updateable = false;
         let statusMsg = null;
         switch (aData) {
           case "update":
-            statusMsg = strings.getFormattedString("addonUpdate.updating", [update.version]);
+            statusMsg = strings.formatStringFromName("addonUpdate.updating", [update.version], 1);
             updateable = true;
             break;
           case "compatibility":
-            statusMsg = strings.getString("addonUpdate.compatibility");
+            statusMsg = strings.GetStringFromName("addonUpdate.compatibility");
             if (addon.pendingOperations & AddonManager.PENDING_INSTALL || addon.pendingOperations & AddonManager.PENDING_UPGRADE)
               updateable = true;
             break;
           case "error":
-            statusMsg = strings.getString("addonUpdate.error");
+            statusMsg = strings.GetStringFromName("addonUpdate.error");
             break;
           case "no-update":
             // Ignore if no updated was found. Just let the message go blank.
-            //statusMsg = strings.getString("addonUpdate.noupdate");
+            //statusMsg = strings.GetStringFromName("addonUpdate.noupdate");
             break;
           default:
             // Ignore if no updated was found. Just let the message go blank.
-            //statusMsg = strings.getString("addonUpdate.noupdate");
+            //statusMsg = strings.GetStringFromName("addonUpdate.noupdate");
         }
 
         if (statusMsg)
           element.setAttribute("updateStatus", statusMsg);
         else
           element.removeAttribute("updateStatus");
 
         // Tag the add-on so the AddonInstallListener knows it's an update
         if (updateable)
           element.setAttribute("updating", "true");
         break;
     }
   },
+
   showAlert: function ev_showAlert(aMessage) {
     if (this.visible)
       return;
 
-    let strings = Elements.browserBundle;
+    let strings = Strings.browser;
 
     let observer = {
       observe: function (aSubject, aTopic, aData) {
         if (aTopic == "alertclickcallback")
           BrowserUI.showPanel("addons-container");
       }
     };
 
     let alerts = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
-    alerts.showAlertNotification(URI_GENERIC_ICON_XPINSTALL, strings.getString("alertAddons"),
+    alerts.showAlertNotification(URI_GENERIC_ICON_XPINSTALL, strings.GetStringFromName("alertAddons"),
                                  aMessage, true, "", observer, "addons");
   },
 
   hideAlerts: function ev_hideAlerts() {
 #ifdef ANDROID
     let alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
     let progressListener = alertsService.QueryInterface(Ci.nsIAlertsProgressListener);
     progressListener.onCancel("addons");
 #endif
   },
 };
 
 
 function searchFailed() {
   ExtensionsView.clearSection("repo");
 
-  let strings = Elements.browserBundle;
-  let brand = document.getElementById("bundle_brand");
+  let strings = Strings.browser;
+  let brand = Strings.brand;
 
-  let failLabel = strings.getFormattedString("addonsSearchFail.label",
-                                             [brand.getString("brandShortName")]);
-  let failButton = strings.getString("addonsSearchFail.button");
+  let failLabel = strings.formatStringFromName("addonsSearchFail.label",
+                                             [brand.GetStringFromName("brandShortName")], 1);
+  let failButton = strings.GetStringFromName("addonsSearchFail.button");
   ExtensionsView.displaySectionMessage("repo", failLabel, failButton, true);
 }
 
 
 ///////////////////////////////////////////////////////////////////////////////
 // callback for the recommended search
 var RecommendedSearchResults = {
   cache: null,
@@ -861,18 +861,18 @@ AddonInstallListener.prototype = {
 
     let element = ExtensionsView.getElementForAddon(aAddon.id);
     if (element) {  
       element.setAttribute("opType", "needs-restart");
       element.setAttribute("status", "success");
   
       // If we are updating an add-on, change the status
       if (element.hasAttribute("updating")) {
-        let strings = Elements.browserBundle;
-        element.setAttribute("updateStatus", strings.getFormattedString("addonUpdate.updated", [aAddon.version]));
+        let strings = Strings.browser;
+        element.setAttribute("updateStatus", strings.formatStringFromName("addonUpdate.updated", [aAddon.version], 1));
         element.removeAttribute("updating");
       }
     }
     this._showInstallCompleteAlert(true);
   },
 
   onInstallFailed: function(aInstall, aError) {
     this._showInstallCompleteAlert(false);
@@ -926,44 +926,44 @@ AddonInstallListener.prototype = {
     element.setAttribute("progress", progress);
   },
 
   onDownloadFailed: function(aInstall, aError) {
     this.onInstallFailed(aInstall, aError);
   },
 
   onDownloadCancelled: function(aInstall, aAddon) {
-    let strings = Elements.browserBundle;
-    let brandBundle = document.getElementById("bundle_brand");
-    let brandShortName = brandBundle.getString("brandShortName");
+    let strings = Strings.browser;
+    let brandBundle = Strings.brand;
+    let brandShortName = brandBundle.GetStringFromName("brandShortName");
     let host = (aInstall.originatingURI instanceof Ci.nsIStandardURL) && aInstall.originatingURI.host;
     if (!host)
       host = (aInstall.sourceURI instanceof Ci.nsIStandardURL) && aInstall.sourceURI.host;
 
     let error = (host || aInstall.error == 0) ? "addonError" : "addonLocalError";
     if (aInstall.error != 0)
       error += aInstall.error;
     else if (aInstall.addon.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED)
       error += "Blocklisted";
     else if (!aInstall.addon.isCompatible || !aInstall.addon.isPlatformCompatible)
       error += "Incompatible";
     else {
       ExtensionsView.hideAlerts();
       return; // no need to show anything in this case
     }
 
-    let messageString = strings.getString(error);
+    let messageString = strings.GetStringFromName(error);
     messageString = messageString.replace("#1", aInstall.name);
     if (host)
       messageString = messageString.replace("#2", host);
     messageString = messageString.replace("#3", brandShortName);
     messageString = messageString.replace("#4", Services.appinfo.version);
     
     ExtensionsView.showAlert(messageString);
   },
 
   _showInstallCompleteAlert: function xpidm_showAlert(aSucceeded) {
-    let strings = Elements.browserBundle;
-    let msg = aSucceeded ? strings.getString("alertAddonsInstalled") :
-                           strings.getString("alertAddonsFail");
+    let strings = Strings.browser;
+    let msg = aSucceeded ? strings.GetStringFromName("alertAddonsInstalled") :
+                           strings.GetStringFromName("alertAddonsFail");
     ExtensionsView.showAlert(msg);
   },
 };
--- a/mobile/chrome/content/preferences.js
+++ b/mobile/chrome/content/preferences.js
@@ -77,19 +77,19 @@ var PreferencesView = {
     this._msg.appendNotification(aMsg, aValue, "", this._msg.PRIORITY_WARNING_LOW, buttons).hideclose = !aShowCloseButton;
   },
 
   showRestart: function ev_showRestart() {
     // Increment the count in case the view is not completely initialized
     this._restartCount++;
 
     if (this._msg) {
-      let strings = Elements.browserBundle;
-      this.showMessage(strings.getString("notificationRestart.normal"), "restart-app",
-                       strings.getString("notificationRestart.button"), false, "prefs-restart-app");
+      let strings = Strings.browser;
+      this.showMessage(strings.GetStringFromName("notificationRestart.normal"), "restart-app",
+                       strings.GetStringFromName("notificationRestart.button"), false, "prefs-restart-app");
     }
   },
 
   hideRestart: function ev_hideRestart() {
     this._restartCount--;
     if (this._restartCount == 0 && this._msg) {
       let notification = this._msg.getNotificationWithValue("restart-app");
       if (notification)
@@ -223,17 +223,17 @@ var PreferencesView = {
 
     // Show or hide the title or URL of the custom homepage
     this._showHomePageHint(display);
 
     // Add the helper "Custom Page" item in the menulist, if needed
     let options = document.getElementById("prefs-homepage-options");
     if (value == "custom") {
       // Make sure nothing is selected and just use a label to show the state
-      options.appendItem(Elements.browserBundle.getString("homepage.custom2"), "custom");
+      options.appendItem(Strings.browser.GetStringFromName("homepage.custom2"), "custom");
     }
 
     // Select the right menulist item
     options.value = value;
   },
 
   updateHomePageList: function updateHomePageMenuList() {
     // Update the "Use Current Page" item in the menulist by disabling it if
@@ -286,17 +286,17 @@ var PreferencesView = {
     if (items && items.length)
       helper = items[0];
 
     // Update the helper "Custom Page" item in the menulist
     if (value == "currentpage") {
       // If the helper item is not already in the list, we need to put it there
       // (this can happen when changing from one custom page to another)
       if (!helper)
-        helper = options.appendItem(Elements.browserBundle.getString("homepage.custom2"), "custom");
+        helper = options.appendItem(Strings.browser.GetStringFromName("homepage.custom2"), "custom");
 
       options.selectedItem = helper;
     } else {
       if (helper)
         options.menupopup.removeChild(helper);
 
       options.selectedItem = options.menupopup.getElementsByAttribute("value", value)[0];
     }
--- a/mobile/chrome/tests/browser_addons.js
+++ b/mobile/chrome/tests/browser_addons.js
@@ -56,17 +56,17 @@ var addons = [{
   willFail: false,
 }];
 
 
 var gPendingTests = [];
 var gTestsRun = 0;
 var gTestStart = null;
 var gDate = new Date(2010, 7, 1);
-var gApp = document.getElementById("bundle_brand").getString("brandShortName");
+var gApp = Strings.brand.GetStringFromName("brandShortName");
 var gCategoryUtilities;
 var gSearchCount = 0;
 var gProvider = null;
 
 function test() {
   waitForExplicitFinish();
   Services.prefs.setCharPref(PREF_GETADDONS_GETRECOMMENDED,      TESTROOT + "browser_install.xml");
   Services.prefs.setCharPref(PREF_GETADDONS_BROWSERECOMMENDED,   TESTROOT + "browser_install.xml");