Bug 951396 - Bookmark toolbar now can show icons in HiDPI resolution using a new helper function in PlacesUIUtils.jsm. r=MattN,mak
--- 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