1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/metro/base/content/TopSites.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,158 @@ 1.4 +// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*- 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 +'use strict'; 1.9 + 1.10 +/** 1.11 + * singleton to provide data-level functionality to the views 1.12 + */ 1.13 +let TopSites = { 1.14 + prepareCache: function(aForce){ 1.15 + // front to the NewTabUtils' links cache 1.16 + // -ensure NewTabUtils.links links are pre-cached 1.17 + 1.18 + // avoid re-fetching links data while a fetch is in flight 1.19 + if (this._promisedCache && !aForce) { 1.20 + return this._promisedCache; 1.21 + } 1.22 + let deferred = Promise.defer(); 1.23 + this._promisedCache = deferred.promise; 1.24 + 1.25 + NewTabUtils.links.populateCache(function () { 1.26 + deferred.resolve(); 1.27 + this._promisedCache = null; 1.28 + this._sites = null; // reset our sites cache so they are built anew 1.29 + this._sitesDirty.clear(); 1.30 + }.bind(this), true); 1.31 + return this._promisedCache; 1.32 + }, 1.33 + 1.34 + _sites: null, 1.35 + _sitesDirty: new Set(), 1.36 + getSites: function() { 1.37 + if (this._sites) { 1.38 + return this._sites; 1.39 + } 1.40 + 1.41 + let links = NewTabUtils.links.getLinks(); 1.42 + let sites = links.map(function(aLink){ 1.43 + let site = new Site(aLink); 1.44 + return site; 1.45 + }); 1.46 + 1.47 + // reset state 1.48 + this._sites = sites; 1.49 + this._sitesDirty.clear(); 1.50 + return this._sites; 1.51 + }, 1.52 + 1.53 + /** 1.54 + * Get list of top site as in need of update/re-render 1.55 + * @param aSite Optionally add Site arguments to be refreshed/updated 1.56 + */ 1.57 + dirty: function() { 1.58 + // add any arguments for more fine-grained updates rather than invalidating the whole collection 1.59 + for (let i=0; i<arguments.length; i++) { 1.60 + this._sitesDirty.add(arguments[i]); 1.61 + } 1.62 + return this._sitesDirty; 1.63 + }, 1.64 + 1.65 + /** 1.66 + * Cause update of top sites 1.67 + */ 1.68 + update: function() { 1.69 + NewTabUtils.allPages.update(); 1.70 + // then clear all the dirty flags 1.71 + this._sitesDirty.clear(); 1.72 + }, 1.73 + 1.74 + /** 1.75 + * Pin top site at a given index 1.76 + * @param aSites array of sites to be pinned 1.77 + * @param aSlotIndices indices corresponding to the site to be pinned 1.78 + */ 1.79 + pinSites: function(aSites, aSlotIndices) { 1.80 + if (aSites.length !== aSlotIndices.length) 1.81 + throw new Error("TopSites.pinSites: Mismatched sites/indices arguments"); 1.82 + 1.83 + for (let i=0; i<aSites.length && i<aSlotIndices.length; i++){ 1.84 + let site = aSites[i], 1.85 + idx = aSlotIndices[i]; 1.86 + if (!(site && site.url)) { 1.87 + throw Cr.NS_ERROR_INVALID_ARG 1.88 + } 1.89 + // pinned state is a pref, using Storage apis therefore sync 1.90 + NewTabUtils.pinnedLinks.pin(site, idx); 1.91 + this.dirty(site); 1.92 + } 1.93 + this.update(); 1.94 + }, 1.95 + 1.96 + /** 1.97 + * Unpin top sites 1.98 + * @param aSites array of sites to be unpinned 1.99 + */ 1.100 + unpinSites: function(aSites) { 1.101 + for (let site of aSites) { 1.102 + if (!(site && site.url)) { 1.103 + throw Cr.NS_ERROR_INVALID_ARG 1.104 + } 1.105 + // pinned state is a pref, using Storage apis therefore sync 1.106 + NewTabUtils.pinnedLinks.unpin(site); 1.107 + this.dirty(site); 1.108 + } 1.109 + this.update(); 1.110 + }, 1.111 + 1.112 + /** 1.113 + * Hide (block) top sites 1.114 + * @param aSites array of sites to be unpinned 1.115 + */ 1.116 + hideSites: function(aSites) { 1.117 + for (let site of aSites) { 1.118 + if (!(site && site.url)) { 1.119 + throw Cr.NS_ERROR_INVALID_ARG 1.120 + } 1.121 + 1.122 + site._restorePinIndex = NewTabUtils.pinnedLinks._indexOfLink(site); 1.123 + // blocked state is a pref, using Storage apis therefore sync 1.124 + NewTabUtils.blockedLinks.block(site); 1.125 + } 1.126 + // clear out the cache, we'll fetch and re-render 1.127 + this._sites = null; 1.128 + this._sitesDirty.clear(); 1.129 + this.update(); 1.130 + }, 1.131 + 1.132 + /** 1.133 + * Un-hide (restore) top sites 1.134 + * @param aSites array of sites to be restored 1.135 + */ 1.136 + restoreSites: function(aSites) { 1.137 + for (let site of aSites) { 1.138 + if (!(site && site.url)) { 1.139 + throw Cr.NS_ERROR_INVALID_ARG 1.140 + } 1.141 + NewTabUtils.blockedLinks.unblock(site); 1.142 + let pinIndex = site._restorePinIndex; 1.143 + 1.144 + if (!isNaN(pinIndex) && pinIndex > -1) { 1.145 + NewTabUtils.pinnedLinks.pin(site, pinIndex); 1.146 + } 1.147 + } 1.148 + // clear out the cache, we'll fetch and re-render 1.149 + this._sites = null; 1.150 + this._sitesDirty.clear(); 1.151 + this.update(); 1.152 + }, 1.153 + 1.154 + _linkFromNode: function _linkFromNode(aNode) { 1.155 + return { 1.156 + url: aNode.getAttribute("value"), 1.157 + title: aNode.getAttribute("label") 1.158 + }; 1.159 + } 1.160 +}; 1.161 +