Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
1 // -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 'use strict';
7 /**
8 * singleton to provide data-level functionality to the views
9 */
10 let TopSites = {
11 prepareCache: function(aForce){
12 // front to the NewTabUtils' links cache
13 // -ensure NewTabUtils.links links are pre-cached
15 // avoid re-fetching links data while a fetch is in flight
16 if (this._promisedCache && !aForce) {
17 return this._promisedCache;
18 }
19 let deferred = Promise.defer();
20 this._promisedCache = deferred.promise;
22 NewTabUtils.links.populateCache(function () {
23 deferred.resolve();
24 this._promisedCache = null;
25 this._sites = null; // reset our sites cache so they are built anew
26 this._sitesDirty.clear();
27 }.bind(this), true);
28 return this._promisedCache;
29 },
31 _sites: null,
32 _sitesDirty: new Set(),
33 getSites: function() {
34 if (this._sites) {
35 return this._sites;
36 }
38 let links = NewTabUtils.links.getLinks();
39 let sites = links.map(function(aLink){
40 let site = new Site(aLink);
41 return site;
42 });
44 // reset state
45 this._sites = sites;
46 this._sitesDirty.clear();
47 return this._sites;
48 },
50 /**
51 * Get list of top site as in need of update/re-render
52 * @param aSite Optionally add Site arguments to be refreshed/updated
53 */
54 dirty: function() {
55 // add any arguments for more fine-grained updates rather than invalidating the whole collection
56 for (let i=0; i<arguments.length; i++) {
57 this._sitesDirty.add(arguments[i]);
58 }
59 return this._sitesDirty;
60 },
62 /**
63 * Cause update of top sites
64 */
65 update: function() {
66 NewTabUtils.allPages.update();
67 // then clear all the dirty flags
68 this._sitesDirty.clear();
69 },
71 /**
72 * Pin top site at a given index
73 * @param aSites array of sites to be pinned
74 * @param aSlotIndices indices corresponding to the site to be pinned
75 */
76 pinSites: function(aSites, aSlotIndices) {
77 if (aSites.length !== aSlotIndices.length)
78 throw new Error("TopSites.pinSites: Mismatched sites/indices arguments");
80 for (let i=0; i<aSites.length && i<aSlotIndices.length; i++){
81 let site = aSites[i],
82 idx = aSlotIndices[i];
83 if (!(site && site.url)) {
84 throw Cr.NS_ERROR_INVALID_ARG
85 }
86 // pinned state is a pref, using Storage apis therefore sync
87 NewTabUtils.pinnedLinks.pin(site, idx);
88 this.dirty(site);
89 }
90 this.update();
91 },
93 /**
94 * Unpin top sites
95 * @param aSites array of sites to be unpinned
96 */
97 unpinSites: function(aSites) {
98 for (let site of aSites) {
99 if (!(site && site.url)) {
100 throw Cr.NS_ERROR_INVALID_ARG
101 }
102 // pinned state is a pref, using Storage apis therefore sync
103 NewTabUtils.pinnedLinks.unpin(site);
104 this.dirty(site);
105 }
106 this.update();
107 },
109 /**
110 * Hide (block) top sites
111 * @param aSites array of sites to be unpinned
112 */
113 hideSites: function(aSites) {
114 for (let site of aSites) {
115 if (!(site && site.url)) {
116 throw Cr.NS_ERROR_INVALID_ARG
117 }
119 site._restorePinIndex = NewTabUtils.pinnedLinks._indexOfLink(site);
120 // blocked state is a pref, using Storage apis therefore sync
121 NewTabUtils.blockedLinks.block(site);
122 }
123 // clear out the cache, we'll fetch and re-render
124 this._sites = null;
125 this._sitesDirty.clear();
126 this.update();
127 },
129 /**
130 * Un-hide (restore) top sites
131 * @param aSites array of sites to be restored
132 */
133 restoreSites: function(aSites) {
134 for (let site of aSites) {
135 if (!(site && site.url)) {
136 throw Cr.NS_ERROR_INVALID_ARG
137 }
138 NewTabUtils.blockedLinks.unblock(site);
139 let pinIndex = site._restorePinIndex;
141 if (!isNaN(pinIndex) && pinIndex > -1) {
142 NewTabUtils.pinnedLinks.pin(site, pinIndex);
143 }
144 }
145 // clear out the cache, we'll fetch and re-render
146 this._sites = null;
147 this._sitesDirty.clear();
148 this.update();
149 },
151 _linkFromNode: function _linkFromNode(aNode) {
152 return {
153 url: aNode.getAttribute("value"),
154 title: aNode.getAttribute("label")
155 };
156 }
157 };