browser/base/content/newtab/updater.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 #ifdef 0
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 4 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5 #endif
michael@0 6
michael@0 7 /**
michael@0 8 * This singleton provides functionality to update the current grid to a new
michael@0 9 * set of pinned and blocked sites. It adds, moves and removes sites.
michael@0 10 */
michael@0 11 let gUpdater = {
michael@0 12 /**
michael@0 13 * Updates the current grid according to its pinned and blocked sites.
michael@0 14 * This removes old, moves existing and creates new sites to fill gaps.
michael@0 15 * @param aCallback The callback to call when finished.
michael@0 16 */
michael@0 17 updateGrid: function Updater_updateGrid(aCallback) {
michael@0 18 let links = gLinks.getLinks().slice(0, gGrid.cells.length);
michael@0 19
michael@0 20 // Find all sites that remain in the grid.
michael@0 21 let sites = this._findRemainingSites(links);
michael@0 22
michael@0 23 let self = this;
michael@0 24
michael@0 25 // Remove sites that are no longer in the grid.
michael@0 26 this._removeLegacySites(sites, function () {
michael@0 27 // Freeze all site positions so that we can move their DOM nodes around
michael@0 28 // without any visual impact.
michael@0 29 self._freezeSitePositions(sites);
michael@0 30
michael@0 31 // Move the sites' DOM nodes to their new position in the DOM. This will
michael@0 32 // have no visual effect as all the sites have been frozen and will
michael@0 33 // remain in their current position.
michael@0 34 self._moveSiteNodes(sites);
michael@0 35
michael@0 36 // Now it's time to animate the sites actually moving to their new
michael@0 37 // positions.
michael@0 38 self._rearrangeSites(sites, function () {
michael@0 39 // Try to fill empty cells and finish.
michael@0 40 self._fillEmptyCells(links, aCallback);
michael@0 41
michael@0 42 // Update other pages that might be open to keep them synced.
michael@0 43 gAllPages.update(gPage);
michael@0 44 });
michael@0 45 });
michael@0 46 },
michael@0 47
michael@0 48 /**
michael@0 49 * Takes an array of links and tries to correlate them to sites contained in
michael@0 50 * the current grid. If no corresponding site can be found (i.e. the link is
michael@0 51 * new and a site will be created) then just set it to null.
michael@0 52 * @param aLinks The array of links to find sites for.
michael@0 53 * @return Array of sites mapped to the given links (can contain null values).
michael@0 54 */
michael@0 55 _findRemainingSites: function Updater_findRemainingSites(aLinks) {
michael@0 56 let map = {};
michael@0 57
michael@0 58 // Create a map to easily retrieve the site for a given URL.
michael@0 59 gGrid.sites.forEach(function (aSite) {
michael@0 60 if (aSite)
michael@0 61 map[aSite.url] = aSite;
michael@0 62 });
michael@0 63
michael@0 64 // Map each link to its corresponding site, if any.
michael@0 65 return aLinks.map(function (aLink) {
michael@0 66 return aLink && (aLink.url in map) && map[aLink.url];
michael@0 67 });
michael@0 68 },
michael@0 69
michael@0 70 /**
michael@0 71 * Freezes the given sites' positions.
michael@0 72 * @param aSites The array of sites to freeze.
michael@0 73 */
michael@0 74 _freezeSitePositions: function Updater_freezeSitePositions(aSites) {
michael@0 75 aSites.forEach(function (aSite) {
michael@0 76 if (aSite)
michael@0 77 gTransformation.freezeSitePosition(aSite);
michael@0 78 });
michael@0 79 },
michael@0 80
michael@0 81 /**
michael@0 82 * Moves the given sites' DOM nodes to their new positions.
michael@0 83 * @param aSites The array of sites to move.
michael@0 84 */
michael@0 85 _moveSiteNodes: function Updater_moveSiteNodes(aSites) {
michael@0 86 let cells = gGrid.cells;
michael@0 87
michael@0 88 // Truncate the given array of sites to not have more sites than cells.
michael@0 89 // This can happen when the user drags a bookmark (or any other new kind
michael@0 90 // of link) onto the grid.
michael@0 91 let sites = aSites.slice(0, cells.length);
michael@0 92
michael@0 93 sites.forEach(function (aSite, aIndex) {
michael@0 94 let cell = cells[aIndex];
michael@0 95 let cellSite = cell.site;
michael@0 96
michael@0 97 // The site's position didn't change.
michael@0 98 if (!aSite || cellSite != aSite) {
michael@0 99 let cellNode = cell.node;
michael@0 100
michael@0 101 // Empty the cell if necessary.
michael@0 102 if (cellSite)
michael@0 103 cellNode.removeChild(cellSite.node);
michael@0 104
michael@0 105 // Put the new site in place, if any.
michael@0 106 if (aSite)
michael@0 107 cellNode.appendChild(aSite.node);
michael@0 108 }
michael@0 109 }, this);
michael@0 110 },
michael@0 111
michael@0 112 /**
michael@0 113 * Rearranges the given sites and slides them to their new positions.
michael@0 114 * @param aSites The array of sites to re-arrange.
michael@0 115 * @param aCallback The callback to call when finished.
michael@0 116 */
michael@0 117 _rearrangeSites: function Updater_rearrangeSites(aSites, aCallback) {
michael@0 118 let options = {callback: aCallback, unfreeze: true};
michael@0 119 gTransformation.rearrangeSites(aSites, options);
michael@0 120 },
michael@0 121
michael@0 122 /**
michael@0 123 * Removes all sites from the grid that are not in the given links array or
michael@0 124 * exceed the grid.
michael@0 125 * @param aSites The array of sites remaining in the grid.
michael@0 126 * @param aCallback The callback to call when finished.
michael@0 127 */
michael@0 128 _removeLegacySites: function Updater_removeLegacySites(aSites, aCallback) {
michael@0 129 let batch = [];
michael@0 130
michael@0 131 // Delete sites that were removed from the grid.
michael@0 132 gGrid.sites.forEach(function (aSite) {
michael@0 133 // The site must be valid and not in the current grid.
michael@0 134 if (!aSite || aSites.indexOf(aSite) != -1)
michael@0 135 return;
michael@0 136
michael@0 137 let deferred = Promise.defer();
michael@0 138 batch.push(deferred.promise);
michael@0 139
michael@0 140 // Fade out the to-be-removed site.
michael@0 141 gTransformation.hideSite(aSite, function () {
michael@0 142 let node = aSite.node;
michael@0 143
michael@0 144 // Remove the site from the DOM.
michael@0 145 node.parentNode.removeChild(node);
michael@0 146 deferred.resolve();
michael@0 147 });
michael@0 148 });
michael@0 149
michael@0 150 Promise.all(batch).then(aCallback);
michael@0 151 },
michael@0 152
michael@0 153 /**
michael@0 154 * Tries to fill empty cells with new links if available.
michael@0 155 * @param aLinks The array of links.
michael@0 156 * @param aCallback The callback to call when finished.
michael@0 157 */
michael@0 158 _fillEmptyCells: function Updater_fillEmptyCells(aLinks, aCallback) {
michael@0 159 let {cells, sites} = gGrid;
michael@0 160 let batch = [];
michael@0 161
michael@0 162 // Find empty cells and fill them.
michael@0 163 sites.forEach(function (aSite, aIndex) {
michael@0 164 if (aSite || !aLinks[aIndex])
michael@0 165 return;
michael@0 166
michael@0 167 let deferred = Promise.defer();
michael@0 168 batch.push(deferred.promise);
michael@0 169
michael@0 170 // Create the new site and fade it in.
michael@0 171 let site = gGrid.createSite(aLinks[aIndex], cells[aIndex]);
michael@0 172
michael@0 173 // Set the site's initial opacity to zero.
michael@0 174 site.node.style.opacity = 0;
michael@0 175
michael@0 176 // Flush all style changes for the dynamically inserted site to make
michael@0 177 // the fade-in transition work.
michael@0 178 window.getComputedStyle(site.node).opacity;
michael@0 179 gTransformation.showSite(site, function () deferred.resolve());
michael@0 180 });
michael@0 181
michael@0 182 Promise.all(batch).then(aCallback);
michael@0 183 }
michael@0 184 };

mercurial