Bug 892632 - Hook up tile ribbon color in History tiles via new shared View module; refactor TopSitesView and BookmarksView to use same. r=mbrubeck
authorSam Foster <sfoster@mozilla.com>
Fri, 19 Jul 2013 18:17:08 -0700
changeset 151642 d08889089d68ae0f14bfcc0c4b09272f3e3d348c
parent 151641 4fbaa3b2d2efc3d514f054c56d684f8098c10efb
child 151643 e35ac8d3e9e47687cd488f11c88ca4b166ec9911
push id2859
push userakeybl@mozilla.com
push dateMon, 16 Sep 2013 19:14:59 +0000
treeherdermozilla-beta@87d3c51cd2bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmbrubeck
bugs892632
milestone25.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 892632 - Hook up tile ribbon color in History tiles via new shared View module; refactor TopSitesView and BookmarksView to use same. r=mbrubeck
browser/metro/base/content/TopSites.js
browser/metro/base/content/bookmarks.js
browser/metro/base/content/browser-scripts.js
browser/metro/base/content/history.js
browser/metro/modules/View.jsm
browser/metro/modules/moz.build
--- a/browser/metro/base/content/TopSites.js
+++ b/browser/metro/base/content/TopSites.js
@@ -180,17 +180,17 @@ function TopSitesView(aGrid, aMaxSites, 
   }
 
   NewTabUtils.allPages.register(this);
   TopSites.prepareCache().then(function(){
     this.populateGrid();
   }.bind(this));
 }
 
-TopSitesView.prototype = {
+TopSitesView.prototype = Util.extend(Object.create(View.prototype), {
   _set:null,
   _topSitesMax: null,
   // _lastSelectedSites used to temporarily store blocked/removed sites for undo/restore-ing
   _lastSelectedSites: null,
   // isUpdating used only for testing currently
   isUpdating: false,
 
   handleItemClick: function tabview_handleItemClick(aItem) {
@@ -302,33 +302,17 @@ TopSitesView.prototype = {
       this.isUpdating = true;
       // destroy and recreate all item nodes, skip calling arrangeItems
       grid.clearAll(true);
       this.populateGrid();
     }
   },
 
   updateTile: function(aTileNode, aSite, aArrangeGrid) {
-    PlacesUtils.favicons.getFaviconURLForPage(Util.makeURI(aSite.url), function(iconURLfromSiteURL) {
-      if (!iconURLfromSiteURL) {
-        return;
-      }
-      aTileNode.iconSrc = iconURLfromSiteURL.spec;
-      let faviconURL = (PlacesUtils.favicons.getFaviconLinkForIcon(iconURLfromSiteURL)).spec;
-      let xpFaviconURI = Util.makeURI(faviconURL.replace("moz-anno:favicon:",""));
-      let successAction = function(foreground, background) {
-	      aTileNode.style.color = foreground; //color text
-        aTileNode.setAttribute("customColor", background);
-        if (aTileNode.refresh) {
-          aTileNode.refresh();
-        }
-      };
-      let failureAction = function() {};
-      ColorUtils.getForegroundAndBackgroundIconColors(xpFaviconURI, successAction, failureAction);
-    });
+    this._updateFavicon(aTileNode, Util.makeURI(aSite.url));
 
     if (this._useThumbs) {
       Task.spawn(function() {
         let filepath = PageThumbsStorage.getFilePathForURL(aSite.url);
         if (yield OS.File.exists(filepath)) {
           aSite.backgroundImage = 'url("'+PageThumbs.getThumbnailURL(aSite.url)+'")';
           if ("isBound" in aTileNode && aTileNode.isBound) {
             aTileNode.backgroundImage = aSite.backgroundImage;
@@ -432,17 +416,17 @@ TopSitesView.prototype = {
   QueryInterface: function(iid) {
     if (iid.equals(Components.interfaces.nsINavHistoryObserver) ||
         iid.equals(Components.interfaces.nsISupports)) {
       return this;
     }
     throw Cr.NS_ERROR_NO_INTERFACE;
   }
 
-};
+});
 
 let TopSitesStartView = {
   _view: null,
   get _grid() { return document.getElementById("start-topsites-grid"); },
 
   init: function init() {
     this._view = new TopSitesView(this._grid, 8, true);
     if (this._view.isFirstRun()) {
--- a/browser/metro/base/content/bookmarks.js
+++ b/browser/metro/base/content/bookmarks.js
@@ -88,17 +88,17 @@ function BookmarksView(aSet, aLimit, aRo
   this._pinHelper = new ItemPinHelper("metro.bookmarks.unpinned");
   this._bookmarkService.addObserver(this._changes, false);
   window.addEventListener('MozAppbarDismissing', this, false);
   window.addEventListener('BookmarksNeedsRefresh', this, false);
 
   this.root = aRoot;
 }
 
-BookmarksView.prototype = {
+BookmarksView.prototype = Util.extend(Object.create(View.prototype), {
   _limit: null,
   _set: null,
   _changes: null,
   _root: null,
   _sort: 0, // Natural bookmark order.
   _toRemove: null,
 
   get sort() {
@@ -211,45 +211,25 @@ BookmarksView.prototype = {
 
   addBookmark: function bv_addBookmark(aBookmarkId, aPos) {
     let index = this._bookmarkService.getItemIndex(aBookmarkId);
     let uri = this._bookmarkService.getBookmarkURI(aBookmarkId);
     let title = this._bookmarkService.getItemTitle(aBookmarkId) || uri.spec;
     let item = this._set.insertItemAt(aPos || index, title, uri.spec, this._inBatch);
     item.setAttribute("bookmarkId", aBookmarkId);
     this._setContextActions(item);
-    this._updateFavicon(aBookmarkId, item, uri);
+    this._updateFavicon(item, uri);
   },
 
   _setContextActions: function bv__setContextActions(aItem) {
     let itemId = this._getBookmarkIdForItem(aItem);
     aItem.setAttribute("data-contextactions", "delete," + (this._pinHelper.isPinned(itemId) ? "unpin" : "pin"));
     if (aItem.refresh) aItem.refresh();
   },
 
-  _updateFavicon: function bv__updateFavicon(aBookmarkId, aItem, aUri) {
-    PlacesUtils.favicons.getFaviconURLForPage(aUri, this._gotIcon.bind(this, aBookmarkId, aItem));
-  },
-
-  _gotIcon: function bv__gotIcon(aBookmarkId, aItem, aIconUri) {
-    aItem.setAttribute("iconURI", aIconUri ? aIconUri.spec : "");
-    if (!aIconUri) {
-      return;
-    }
-    let successAction = function(foregroundColor, backgroundColor) {
-      aItem.style.color = foregroundColor; //color text
-      aItem.setAttribute("customColor", backgroundColor); //set background
-      if (aItem.refresh) {
-        aItem.refresh();
-      }
-    };
-    let failureAction = function() {};
-    ColorUtils.getForegroundAndBackgroundIconColors(aIconUri, successAction, failureAction);
-  },
-
   _sendNeedsRefresh: function bv__sendNeedsRefresh(){
     // Event sent when all view instances need to refresh.
     let event = document.createEvent("Events");
     event.initEvent("BookmarksNeedsRefresh", true, false);
     window.dispatchEvent(event);
   },
 
   updateBookmark: function bv_updateBookmark(aBookmarkId) {
@@ -268,17 +248,17 @@ BookmarksView.prototype = {
     }
 
     let uri = this._bookmarkService.getBookmarkURI(aBookmarkId);
     let title = this._bookmarkService.getItemTitle(aBookmarkId) || uri.spec;
 
     item.setAttribute("value", uri.spec);
     item.setAttribute("label", title);
 
-    this._updateFavicon(aBookmarkId, item, uri);
+    this._updateFavicon(item, uri);
   },
 
   removeBookmark: function bv_removeBookmark(aBookmarkId) {
     let item = this._getItemForBookmarkId(aBookmarkId);
     let index = this._set.getIndexOfItem(item);
     this._set.removeItemAt(index, this._inBatch);
   },
 
@@ -365,17 +345,17 @@ BookmarksView.prototype = {
         }
         break;
 
       case "BookmarksNeedsRefresh":
         this.getBookmarks(true);
         break;
     }
   }
-};
+});
 
 var BookmarksStartView = {
   _view: null,
   get _grid() { return document.getElementById("start-bookmarks-grid"); },
 
   init: function init() {
     this._view = new BookmarksView(this._grid, StartUI.maxResultsPerSection, Bookmarks.metroRoot, true);
     this._view.getBookmarks();
--- a/browser/metro/base/content/browser-scripts.js
+++ b/browser/metro/base/content/browser-scripts.js
@@ -35,16 +35,19 @@ XPCOMUtils.defineLazyModuleGetter(this, 
                                   "resource://gre/modules/Task.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "CrossSlide",
                                   "resource:///modules/CrossSlide.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "OS",
                                   "resource://gre/modules/osfile.jsm");
 
+XPCOMUtils.defineLazyModuleGetter(this, "View",
+                                  "resource:///modules/View.jsm");
+
 /*
  * Services
  */
 
 #ifdef XP_WIN
 XPCOMUtils.defineLazyServiceGetter(this, "MetroUtils",
                                    "@mozilla.org/windows-metroutils;1",
                                    "nsIWinMetroUtils");
--- a/browser/metro/base/content/history.js
+++ b/browser/metro/base/content/history.js
@@ -1,12 +1,12 @@
-// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
 'use strict';
 
 function HistoryView(aSet, aLimit, aFilterUnpinned) {
   this._set = aSet;
   this._set.controller = this;
   this._inBatch = 0;
 
   this._limit = aLimit;
@@ -15,17 +15,17 @@ function HistoryView(aSet, aLimit, aFilt
   this._navHistoryService = gHistSvc;
 
   this._pinHelper = new ItemPinHelper("metro.history.unpinned");
   this._historyService.addObserver(this, false);
   window.addEventListener('MozAppbarDismissing', this, false);
   window.addEventListener('HistoryNeedsRefresh', this, false);
 }
 
-HistoryView.prototype = {
+HistoryView.prototype = Util.extend(Object.create(View.prototype), {
   _set: null,
   _toRemove: null,
 
   handleItemClick: function tabview_handleItemClick(aItem) {
     let url = aItem.getAttribute("value");
     BrowserUI.goToURI(url);
   },
 
@@ -92,18 +92,18 @@ HistoryView.prototype = {
   destruct: function destruct() {
     this._historyService.removeObserver(this);
     window.removeEventListener('MozAppbarDismissing', this, false);
     window.removeEventListener('HistoryNeedsRefresh', this, false);
   },
 
   addItemToSet: function addItemToSet(aURI, aTitle, aIcon, aPos) {
     let item = this._set.insertItemAt(aPos || 0, aTitle, aURI, this._inBatch);
-    item.setAttribute("iconURI", aIcon);
     this._setContextActions(item);
+    this._updateFavicon(item, aURI);
   },
 
   _setContextActions: function bv__setContextActions(aItem) {
     let uri = aItem.getAttribute("value");
     aItem.setAttribute("data-contextactions", "delete," + (this._pinHelper.isPinned(uri) ? "unpin" : "pin"));
     if (aItem.refresh) aItem.refresh();
   },
 
@@ -268,17 +268,17 @@ HistoryView.prototype = {
 
   QueryInterface: function(iid) {
     if (iid.equals(Components.interfaces.nsINavHistoryObserver) ||
         iid.equals(Components.interfaces.nsISupports)) {
       return this;
     }
     throw Cr.NS_ERROR_NO_INTERFACE;
   }
-};
+});
 
 let HistoryStartView = {
   _view: null,
   get _grid() { return document.getElementById("start-history-grid"); },
 
   show: function show() {
     this._grid.arrangeItems();
   },
new file mode 100644
--- /dev/null
+++ b/browser/metro/modules/View.jsm
@@ -0,0 +1,63 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict";
+
+this.EXPORTED_SYMBOLS = ["View"];
+
+Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
+Components.utils.import("resource:///modules/colorUtils.jsm");
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+// --------------------------------
+// module helpers
+//
+
+function makeURI(aURL, aOriginCharset, aBaseURI) {
+  return Services.io.newURI(aURL, aOriginCharset, aBaseURI);
+}
+
+// --------------------------------
+
+
+// --------------------------------
+// View prototype for shared functionality
+
+function View() {
+}
+
+View.prototype = {
+
+  _updateFavicon: function pv__updateFavicon(aItem, aUri) {
+    if ("string" == typeof aUri) {
+      aUri = makeURI(aUri);
+    }
+    PlacesUtils.favicons.getFaviconURLForPage(aUri, this._gotIcon.bind(this, aItem));
+  },
+
+  _gotIcon: function pv__gotIcon(aItem, aIconUri) {
+    if (!aIconUri) {
+      aItem.removeAttribute("iconURI");
+      if (aItem.refresh) {
+        aItem.refresh();
+      }
+      return;
+    }
+    if ("string" == typeof aIconUri) {
+      aIconUri = makeURI(aIconUri);
+    }
+    aItem.iconSrc = aIconUri.spec;
+    let faviconURL = (PlacesUtils.favicons.getFaviconLinkForIcon(aIconUri)).spec;
+    let xpFaviconURI = makeURI(faviconURL.replace("moz-anno:favicon:",""));
+    let successAction = function(foreground, background) {
+      aItem.style.color = foreground; //color text
+      aItem.setAttribute("customColor", background);
+      if (aItem.refresh) {
+        aItem.refresh();
+      }
+    };
+    let failureAction = function() {};
+    ColorUtils.getForegroundAndBackgroundIconColors(xpFaviconURI, successAction, failureAction);
+  }
+
+};
--- a/browser/metro/modules/moz.build
+++ b/browser/metro/modules/moz.build
@@ -1,11 +1,12 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 EXTRA_JS_MODULES += [
     'CrossSlide.jsm',
+    'View.jsm',
     'colorUtils.jsm',
 ]