Bug 951396 - Bookmark toolbar now can show icons in HiDPI resolution using a new helper function in PlacesUIUtils.jsm. r=MattN,mak
authorBernardo P. Rittmeyer <bernardo@rittme.com>
Thu, 31 Jul 2014 19:29:57 -0700
changeset 197168 8301ecf9f05f14ac7d2cfb72451aeb04fa57502f
parent 197167 8d7b53cc415e4d347f5c61c152bfa71ed8eb28b0
child 197169 b5f3d8eaa7571a48e5aa94211d422fec3fc6640a
push id8006
push usermozilla@noorenberghe.ca
push dateFri, 01 Aug 2014 02:30:44 +0000
treeherderfx-team@b5f3d8eaa757 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMattN, mak
bugs951396
milestone34.0a1
Bug 951396 - Bookmark toolbar now can show icons in HiDPI resolution using a new helper function in PlacesUIUtils.jsm. r=MattN,mak
browser/components/places/PlacesUIUtils.jsm
browser/components/places/content/browserPlacesViews.js
toolkit/components/places/nsFaviconService.cpp
--- a/browser/components/places/PlacesUIUtils.jsm
+++ b/browser/components/places/PlacesUIUtils.jsm
@@ -1009,16 +1009,43 @@ this.PlacesUIUtils = {
 
   shouldEnableTabsFromOtherComputersMenuitem: function() {
     // The tabs engine might never be inited (if services.sync.registerEngines
     // is modified), so make sure we avoid undefined errors.
     return Weave.Service.isLoggedIn &&
            Weave.Service.engineManager.get("tabs") &&
            Weave.Service.engineManager.get("tabs").enabled;
   },
+
+  /**
+   * Returns the passed URL with a #moz-resolution fragment
+   * for the specified dimensions and devicePixelRatio.
+   *
+   * @param aWindow
+   *        A window from where we want to get the device
+   *        pixel Ratio
+   *
+   * @param aURL
+   *        The URL where we should add the fragment
+   *
+   * @param aWidth
+   *        The target image width
+   *
+   * @param aHeight
+   *        The target image height
+   *
+   * @return The URL with the fragment at the end
+   */
+  getImageURLForResolution:
+  function PUIU_getImageURLForResolution(aWindow, aURL, aWidth = 16, aHeight = 16) {
+    let width  = Math.round(aWidth * aWindow.devicePixelRatio);
+    let height = Math.round(aHeight * aWindow.devicePixelRatio);
+    return aURL + (aURL.contains("#") ? "&" : "#") +
+           "-moz-resolution=" + width + "," + height;
+  },
 };
 
 XPCOMUtils.defineLazyServiceGetter(PlacesUIUtils, "RDF",
                                    "@mozilla.org/rdf/rdf-service;1",
                                    "nsIRDFService");
 
 XPCOMUtils.defineLazyGetter(PlacesUIUtils, "localStore", function() {
   return PlacesUIUtils.RDF.GetDataSource("rdf:local-store");
--- a/browser/components/places/content/browserPlacesViews.js
+++ b/browser/components/places/content/browserPlacesViews.js
@@ -357,17 +357,18 @@ PlacesViewBase.prototype = {
       }
       else
         throw "Unexpected node";
 
       element.setAttribute("label", PlacesUIUtils.getBestTitle(aPlacesNode));
 
       let icon = aPlacesNode.icon;
       if (icon)
-        element.setAttribute("image", icon);
+        element.setAttribute("image",
+                             PlacesUIUtils.getImageURLForResolution(window, icon));
     }
 
     element._placesNode = aPlacesNode;
     if (!this._domNodes.has(aPlacesNode))
       this._domNodes.set(aPlacesNode, element);
 
     return element;
   },
@@ -495,17 +496,18 @@ PlacesViewBase.prototype = {
     // Here we need the <menu>.
     if (elt.localName == "menupopup")
       elt = elt.parentNode;
 
     let icon = aPlacesNode.icon;
     if (!icon)
       elt.removeAttribute("image");
     else if (icon != elt.getAttribute("image"))
-      elt.setAttribute("image", icon);
+      elt.setAttribute("image",
+                       PlacesUIUtils.getImageURLForResolution(window, icon));
   },
 
   nodeAnnotationChanged:
   function PVB_nodeAnnotationChanged(aPlacesNode, aAnno) {
     let elt = this._getDOMNodeForPlacesNode(aPlacesNode);
 
     // All livemarks have a feedURI, so use it as our indicator of a livemark
     // being modified.
@@ -1011,17 +1013,18 @@ PlacesToolbar.prototype = {
       button = document.createElement("toolbarseparator");
     }
     else {
       button = document.createElement("toolbarbutton");
       button.className = "bookmark-item";
       button.setAttribute("label", aChild.title);
       let icon = aChild.icon;
       if (icon)
-        button.setAttribute("image", icon);
+        button.setAttribute("image",
+                            PlacesUIUtils.getImageURLForResolution(window, icon));
 
       if (PlacesUtils.containerTypes.indexOf(type) != -1) {
         button.setAttribute("type", "menu");
         button.setAttribute("container", "true");
 
         if (PlacesUtils.nodeIsQuery(aChild)) {
           button.setAttribute("query", "true");
           if (PlacesUtils.nodeIsTagQuery(aChild))
@@ -1835,17 +1838,18 @@ PlacesPanelMenuView.prototype = {
     else {
       button = document.createElement("toolbarbutton");
       button.className = "bookmark-item";
       if (typeof this.options.extraClasses.entry == "string")
         button.classList.add(this.options.extraClasses.entry);
       button.setAttribute("label", aChild.title);
       let icon = aChild.icon;
       if (icon)
-        button.setAttribute("image", icon);
+        button.setAttribute("image",
+                            PlacesUIUtils.getImageURLForResolution(window, icon));
 
       if (PlacesUtils.containerTypes.indexOf(type) != -1) {
         button.setAttribute("container", "true");
 
         if (PlacesUtils.nodeIsQuery(aChild)) {
           button.setAttribute("query", "true");
           if (PlacesUtils.nodeIsTagQuery(aChild))
             button.setAttribute("tagContainer", "true");
--- a/toolkit/components/places/nsFaviconService.cpp
+++ b/toolkit/components/places/nsFaviconService.cpp
@@ -574,17 +574,22 @@ nsFaviconService::GetFaviconDataAsync(ns
                                       mozIStorageStatementCallback *aCallback)
 {
   NS_ASSERTION(aCallback, "Doesn't make sense to call this without a callback");
   nsCOMPtr<mozIStorageAsyncStatement> stmt = mDB->GetAsyncStatement(
     "SELECT f.data, f.mime_type FROM moz_favicons f WHERE url = :icon_url"
   );
   NS_ENSURE_STATE(stmt);
 
-  nsresult rv = URIBinder::Bind(stmt, NS_LITERAL_CSTRING("icon_url"), aFaviconURI);
+  // Ignore the ref part of the URI before querying the database because
+  // we may have added the #-moz-resolution ref for rendering purposes.
+
+  nsAutoCString faviconURI;
+  aFaviconURI->GetSpecIgnoringRef(faviconURI);
+  nsresult rv = URIBinder::Bind(stmt, NS_LITERAL_CSTRING("icon_url"), faviconURI);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<mozIStoragePendingStatement> pendingStatement;
   return stmt->ExecuteAsync(aCallback, getter_AddRefs(pendingStatement));
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 //// ExpireFaviconsStatementCallbackNotifier