From 4492b5f8e774bf3b4f21e4e468fc052cbcbb468a Mon Sep 17 00:00:00 2001 From: Thomas Groman Date: Mon, 16 Dec 2019 19:48:42 -0800 Subject: initial commit --- components/newtab/grid.js | 175 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 components/newtab/grid.js (limited to 'components/newtab/grid.js') diff --git a/components/newtab/grid.js b/components/newtab/grid.js new file mode 100644 index 0000000..e63ea54 --- /dev/null +++ b/components/newtab/grid.js @@ -0,0 +1,175 @@ +#ifdef 0 +/* 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/. */ +#endif + +/** + * This singleton represents the grid that contains all sites. + */ +var gGrid = { + /** + * The DOM node of the grid. + */ + _node: null, + _gridDefaultContent: null, + get node() { return this._node; }, + + /** + * The cached DOM fragment for sites. + */ + _siteFragment: null, + + /** + * All cells contained in the grid. + */ + _cells: [], + get cells() { return this._cells; }, + + /** + * All sites contained in the grid's cells. Sites may be empty. + */ + get sites() { + // return [for (cell of this.cells) cell.site]; + let aSites = []; + for (let cell of this.cells) { + aSites.push(cell.site); + } + return aSites; + }, + + // Tells whether the grid has already been initialized. + get ready() { return !!this._ready; }, + + // Returns whether the page has finished loading yet. + get isDocumentLoaded() { return document.readyState == "complete"; }, + + /** + * Initializes the grid. + * @param aSelector The query selector of the grid. + */ + init: function Grid_init() { + this._node = document.getElementById("newtab-grid"); + this._gridDefaultContent = this._node.lastChild; + this._createSiteFragment(); + + gLinks.populateCache(() => { + this._refreshGrid(); + this._ready = true; + }); + }, + + /** + * Creates a new site in the grid. + * @param aLink The new site's link. + * @param aCell The cell that will contain the new site. + * @return The newly created site. + */ + createSite: function Grid_createSite(aLink, aCell) { + let node = aCell.node; + node.appendChild(this._siteFragment.cloneNode(true)); + return new Site(node.firstElementChild, aLink); + }, + + /** + * Handles all grid events. + */ + handleEvent: function Grid_handleEvent(aEvent) { + // Any specific events should go here. + }, + + /** + * Locks the grid to block all pointer events. + */ + lock: function Grid_lock() { + this.node.setAttribute("locked", "true"); + }, + + /** + * Unlocks the grid to allow all pointer events. + */ + unlock: function Grid_unlock() { + this.node.removeAttribute("locked"); + }, + + /** + * Renders the grid. + */ + refresh() { + this._refreshGrid(); + }, + + /** + * Renders the grid, including cells and sites. + */ + _refreshGrid() { + let row = document.createElementNS(HTML_NAMESPACE, "div"); + row.classList.add("newtab-row"); + let cell = document.createElementNS(HTML_NAMESPACE, "div"); + cell.classList.add("newtab-cell"); + + // Clear the grid + this._node.innerHTML = ""; + + // Creates the structure of one row + for (let i = 0; i < gGridPrefs.gridColumns; i++) { + row.appendChild(cell.cloneNode(true)); + } + + // Creates the grid + for (let j = 0; j < gGridPrefs.gridRows; j++) { + this._node.appendChild(row.cloneNode(true)); + } + + // Create cell array. + let cellElements = this.node.querySelectorAll(".newtab-cell"); + let cells = Array.from(cellElements, (cell) => new Cell(this, cell)); + + // Fetch links. + let links = gLinks.getLinks(); + + // Create sites. + let numLinks = Math.min(links.length, cells.length); + for (let i = 0; i < numLinks; i++) { + if (links[i]) { + this.createSite(links[i], cells[i]); + } + } + + this._cells = cells; + }, + + /** + * Creates the DOM fragment that is re-used when creating sites. + */ + _createSiteFragment: function Grid_createSiteFragment() { + let site = document.createElementNS(HTML_NAMESPACE, "div"); + site.classList.add("newtab-site"); + site.setAttribute("draggable", "true"); + + // Create the site's inner HTML code. + site.innerHTML = + '' + + ' ' + + ' ' + + ' ' + + '' + + '' + + ''; + + this._siteFragment = document.createDocumentFragment(); + this._siteFragment.appendChild(site); + }, + + /** + * Test a tile at a given position for being pinned or history + * @param position Position in sites array + */ + _isHistoricalTile: function Grid_isHistoricalTile(aPos) { + let site = this.sites[aPos]; + return site && (site.isPinned() || site.link && site.link.type == "history"); + } + +}; -- cgit v1.2.3