Bug 590283 - Bookmark folder item count should use correct plural forms. r=mak77 f=pike
authorMarek Stepien <marcoos@aviary.pl>
Wed, 14 Dec 2011 11:33:01 +0100
changeset 82539 82187424f0512e2b1622f3d2edadabd92f706d28
parent 82538 70dea177b9d9e1ec583a3c8e2092daf20414d5b6
child 82540 596e3eca4196e990e4dcddbdcb1642e6565fd781
push id21657
push userdgottwald@mozilla.com
push dateWed, 14 Dec 2011 10:40:28 +0000
treeherdermozilla-central@6ba6336681e0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmak77
bugs590283
milestone11.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 590283 - Bookmark folder item count should use correct plural forms. r=mak77 f=pike
browser/components/places/content/editBookmarkOverlay.js
browser/components/places/content/places.js
browser/components/places/src/PlacesUIUtils.jsm
browser/locales/en-US/chrome/browser/places/places.properties
--- a/browser/components/places/content/editBookmarkOverlay.js
+++ b/browser/components/places/content/editBookmarkOverlay.js
@@ -216,18 +216,19 @@ var gEditItemOverlay = {
           }
           else
             this._uris[i] = PlacesUtils.bookmarks.getBookmarkURI(this._itemIds[i]);
           this._tags[i] = PlacesUtils.tagging.getTagsForURI(this._uris[i]);
         }
         this._allTags = this._getCommonTags();
         this._initTextField("tagsField", this._allTags.join(", "), false);
         this._element("itemsCountText").value =
-          PlacesUIUtils.getFormattedString("detailsPane.multipleItems",
-                                           [this._itemIds.length]);
+          PlacesUIUtils.getPluralString("detailsPane.itemsCountLabel",
+                                        this._itemIds.length,
+                                        [this._itemIds.length]);
       }
 
       // tags selector
       this._rebuildTagsSelectorList();
     }
 
     // name picker
     this._initNamePicker();
--- a/browser/components/places/content/places.js
+++ b/browser/components/places/content/places.js
@@ -708,18 +708,18 @@ var PlacesOrganizer = {
       for (var i = 0; i < aNodeList.length; i++) {
         if (!PlacesUtils.nodeIsBookmark(aNodeList[i]) &&
             !PlacesUtils.nodeIsURI(aNodeList[i])) {
           detailsDeck.selectedIndex = 0;
           var selectItemDesc = document.getElementById("selectItemDescription");
           var itemsCountLabel = document.getElementById("itemsCountText");
           selectItemDesc.hidden = false;
           itemsCountLabel.value =
-            PlacesUIUtils.getFormattedString("detailsPane.multipleItems",
-                                             [aNodeList.length]);
+            PlacesUIUtils.getPluralString("detailsPane.itemsCountLabel",
+                                          aNodeList.length, [aNodeList.length]);
           infoBox.hidden = true;
           return;
         }
         itemIds[i] = aNodeList[i].itemId != -1 ? aNodeList[i].itemId :
                      PlacesUtils._uri(aNodeList[i].uri);
       }
       detailsDeck.selectedIndex = 1;
       gEditItemOverlay.initPanel(itemIds,
@@ -738,23 +738,19 @@ var PlacesOrganizer = {
       var itemsCountLabel = document.getElementById("itemsCountText");
       var rowCount = this._content.treeBoxObject.view.rowCount;
       if (rowCount == 0) {
         selectItemDesc.hidden = true;
         itemsCountLabel.value = PlacesUIUtils.getString("detailsPane.noItems");
       }
       else {
         selectItemDesc.hidden = false;
-        if (rowCount == 1)
-          itemsCountLabel.value = PlacesUIUtils.getString("detailsPane.oneItem");
-        else {
-          itemsCountLabel.value =
-            PlacesUIUtils.getFormattedString("detailsPane.multipleItems",
-                                             [rowCount]);
-        }
+        itemsCountLabel.value =
+          PlacesUIUtils.getPluralString("detailsPane.itemsCountLabel",
+                                        rowCount, [rowCount]);
       }
     }
   },
 
   // NOT YET USED
   _updateThumbnail: function PO__updateThumbnail() {
     var bo = document.getElementById("previewBox").boxObject;
     var width  = bo.width;
--- a/browser/components/places/src/PlacesUIUtils.jsm
+++ b/browser/components/places/src/PlacesUIUtils.jsm
@@ -45,16 +45,19 @@ var EXPORTED_SYMBOLS = ["PlacesUIUtils"]
 var Ci = Components.interfaces;
 var Cc = Components.classes;
 var Cr = Components.results;
 var Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
+XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
+                                  "resource://gre/modules/PluralForm.jsm");
+
 XPCOMUtils.defineLazyGetter(this, "PlacesUtils", function() {
   Cu.import("resource://gre/modules/PlacesUtils.jsm");
   return PlacesUtils;
 });
 
 var PlacesUIUtils = {
   ORGANIZER_LEFTPANE_VERSION: 7,
   ORGANIZER_FOLDER_ANNO: "PlacesOrganizer/OrganizerFolder",
@@ -74,16 +77,41 @@ var PlacesUIUtils = {
   createFixedURI: function PUIU_createFixedURI(aSpec) {
     return URIFixup.createFixupURI(aSpec, Ci.nsIURIFixup.FIXUP_FLAG_NONE);
   },
 
   getFormattedString: function PUIU_getFormattedString(key, params) {
     return bundle.formatStringFromName(key, params, params.length);
   },
 
+  /**
+   * Get a localized plural string for the specified key name and numeric value
+   * substituting parameters.
+   *
+   * @param   aKey
+   *          String, key for looking up the localized string in the bundle
+   * @param   aNumber
+   *          Number based on which the final localized form is looked up
+   * @param   aParams
+   *          Array whose items will substitute #1, #2,... #n parameters
+   *          in the string.
+   *
+   * @see https://developer.mozilla.org/en/Localization_and_Plurals
+   * @return The localized plural string.
+   */
+  getPluralString: function PUIU_getPluralString(aKey, aNumber, aParams) {
+    let str = PluralForm.get(aNumber, bundle.GetStringFromName(aKey));
+
+    // Replace #1 with aParams[0], #2 with aParams[1], and so on.
+    return str.replace(/\#(\d+)/g, function (matchedId, matchedNumber) {
+      let param = aParams[parseInt(matchedNumber, 10) - 1];
+      return param !== undefined ? param : matchedId;
+    });
+  },
+
   getString: function PUIU_getString(key) {
     return bundle.GetStringFromName(key);
   },
 
   get _copyableAnnotations() [
     this.DESCRIPTION_ANNO,
     this.LOAD_IN_SIDEBAR_ANNO,
     PlacesUtils.POST_DATA_ANNO,
--- a/browser/locales/en-US/chrome/browser/places/places.properties
+++ b/browser/locales/en-US/chrome/browser/places/places.properties
@@ -54,18 +54,21 @@ tabs.openWarningPromptMeBranded=Warn me 
 SelectImport=Import Bookmarks File
 EnterExport=Export Bookmarks File
 
 saveSearch.title=Save Search
 saveSearch.inputLabel=Name:
 saveSearch.inputDefaultText=New Search
 
 detailsPane.noItems=No items
-detailsPane.oneItem=One item
-detailsPane.multipleItems=%S items
+# LOCALIZATION NOTE (detailsPane.itemsCountLabel): Semi-colon list of plural forms.
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+# #1 number of items
+# example: 111 items
+detailsPane.itemsCountLabel=One item;#1 items
 
 mostVisitedTitle=Most Visited
 recentlyBookmarkedTitle=Recently Bookmarked
 recentTagsTitle=Recent Tags
 
 OrganizerQueryHistory=History
 OrganizerQueryDownloads=Downloads
 OrganizerQueryAllBookmarks=All Bookmarks