|
1 #ifdef 0 |
|
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 file, |
|
4 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 #endif |
|
6 |
|
7 /** |
|
8 * This singleton represents the grid that contains all sites. |
|
9 */ |
|
10 let gGrid = { |
|
11 /** |
|
12 * The DOM node of the grid. |
|
13 */ |
|
14 _node: null, |
|
15 get node() this._node, |
|
16 |
|
17 /** |
|
18 * The cached DOM fragment for sites. |
|
19 */ |
|
20 _siteFragment: null, |
|
21 |
|
22 /** |
|
23 * All cells contained in the grid. |
|
24 */ |
|
25 _cells: null, |
|
26 get cells() this._cells, |
|
27 |
|
28 /** |
|
29 * All sites contained in the grid's cells. Sites may be empty. |
|
30 */ |
|
31 get sites() [cell.site for each (cell in this.cells)], |
|
32 |
|
33 // Tells whether the grid has already been initialized. |
|
34 get ready() !!this._node, |
|
35 |
|
36 /** |
|
37 * Initializes the grid. |
|
38 * @param aSelector The query selector of the grid. |
|
39 */ |
|
40 init: function Grid_init() { |
|
41 this._node = document.getElementById("newtab-grid"); |
|
42 this._createSiteFragment(); |
|
43 this._render(); |
|
44 }, |
|
45 |
|
46 /** |
|
47 * Creates a new site in the grid. |
|
48 * @param aLink The new site's link. |
|
49 * @param aCell The cell that will contain the new site. |
|
50 * @return The newly created site. |
|
51 */ |
|
52 createSite: function Grid_createSite(aLink, aCell) { |
|
53 let node = aCell.node; |
|
54 node.appendChild(this._siteFragment.cloneNode(true)); |
|
55 return new Site(node.firstElementChild, aLink); |
|
56 }, |
|
57 |
|
58 /** |
|
59 * Refreshes the grid and re-creates all sites. |
|
60 */ |
|
61 refresh: function Grid_refresh() { |
|
62 // Remove all sites. |
|
63 this.cells.forEach(function (cell) { |
|
64 let node = cell.node; |
|
65 let child = node.firstElementChild; |
|
66 |
|
67 if (child) |
|
68 node.removeChild(child); |
|
69 }, this); |
|
70 |
|
71 // Render the grid again. |
|
72 this._render(); |
|
73 }, |
|
74 |
|
75 /** |
|
76 * Locks the grid to block all pointer events. |
|
77 */ |
|
78 lock: function Grid_lock() { |
|
79 this.node.setAttribute("locked", "true"); |
|
80 }, |
|
81 |
|
82 /** |
|
83 * Unlocks the grid to allow all pointer events. |
|
84 */ |
|
85 unlock: function Grid_unlock() { |
|
86 this.node.removeAttribute("locked"); |
|
87 }, |
|
88 |
|
89 /** |
|
90 * Creates the newtab grid. |
|
91 */ |
|
92 _renderGrid: function Grid_renderGrid() { |
|
93 let row = document.createElementNS(HTML_NAMESPACE, "div"); |
|
94 let cell = document.createElementNS(HTML_NAMESPACE, "div"); |
|
95 row.classList.add("newtab-row"); |
|
96 cell.classList.add("newtab-cell"); |
|
97 |
|
98 // Clear the grid |
|
99 this._node.innerHTML = ""; |
|
100 |
|
101 // Creates the structure of one row |
|
102 for (let i = 0; i < gGridPrefs.gridColumns; i++) { |
|
103 row.appendChild(cell.cloneNode(true)); |
|
104 } |
|
105 // Creates the grid |
|
106 for (let j = 0; j < gGridPrefs.gridRows; j++) { |
|
107 this._node.appendChild(row.cloneNode(true)); |
|
108 } |
|
109 |
|
110 // (Re-)initialize all cells. |
|
111 let cellElements = this.node.querySelectorAll(".newtab-cell"); |
|
112 this._cells = [new Cell(this, cell) for (cell of cellElements)]; |
|
113 }, |
|
114 |
|
115 /** |
|
116 * Creates the DOM fragment that is re-used when creating sites. |
|
117 */ |
|
118 _createSiteFragment: function Grid_createSiteFragment() { |
|
119 let site = document.createElementNS(HTML_NAMESPACE, "div"); |
|
120 site.classList.add("newtab-site"); |
|
121 site.setAttribute("draggable", "true"); |
|
122 |
|
123 // Create the site's inner HTML code. |
|
124 site.innerHTML = |
|
125 '<a class="newtab-link">' + |
|
126 ' <span class="newtab-thumbnail"/>' + |
|
127 ' <span class="newtab-title"/>' + |
|
128 '</a>' + |
|
129 '<input type="button" title="' + newTabString("pin") + '"' + |
|
130 ' class="newtab-control newtab-control-pin"/>' + |
|
131 '<input type="button" title="' + newTabString("block") + '"' + |
|
132 ' class="newtab-control newtab-control-block"/>' + |
|
133 '<input type="button" title="' + newTabString("sponsored") + '"' + |
|
134 ' class="newtab-control newtab-control-sponsored"/>'; |
|
135 |
|
136 this._siteFragment = document.createDocumentFragment(); |
|
137 this._siteFragment.appendChild(site); |
|
138 }, |
|
139 |
|
140 /** |
|
141 * Renders the sites, creates all sites and puts them into their cells. |
|
142 */ |
|
143 _renderSites: function Grid_renderSites() { |
|
144 let cells = this.cells; |
|
145 // Put sites into the cells. |
|
146 let links = gLinks.getLinks(); |
|
147 let length = Math.min(links.length, cells.length); |
|
148 |
|
149 for (let i = 0; i < length; i++) { |
|
150 if (links[i]) |
|
151 this.createSite(links[i], cells[i]); |
|
152 } |
|
153 }, |
|
154 |
|
155 /** |
|
156 * Renders the grid. |
|
157 */ |
|
158 _render: function Grid_render() { |
|
159 if (this._shouldRenderGrid()) { |
|
160 this._renderGrid(); |
|
161 } |
|
162 |
|
163 this._renderSites(); |
|
164 }, |
|
165 |
|
166 _shouldRenderGrid : function Grid_shouldRenderGrid() { |
|
167 let rowsLength = this._node.querySelectorAll(".newtab-row").length; |
|
168 let cellsLength = this._node.querySelectorAll(".newtab-cell").length; |
|
169 |
|
170 return (rowsLength != gGridPrefs.gridRows || |
|
171 cellsLength != (gGridPrefs.gridRows * gGridPrefs.gridColumns)); |
|
172 } |
|
173 }; |