grid.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  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. * This singleton represents the grid that contains all sites.
  8. */
  9. var gGrid = {
  10. /**
  11. * The DOM node of the grid.
  12. */
  13. _node: null,
  14. _gridDefaultContent: null,
  15. get node() { return this._node; },
  16. /**
  17. * The cached DOM fragment for sites.
  18. */
  19. _siteFragment: null,
  20. /**
  21. * All cells contained in the grid.
  22. */
  23. _cells: [],
  24. get cells() { return this._cells; },
  25. /**
  26. * All sites contained in the grid's cells. Sites may be empty.
  27. */
  28. get sites() {
  29. // return [for (cell of this.cells) cell.site];
  30. let aSites = [];
  31. for (let cell of this.cells) {
  32. aSites.push(cell.site);
  33. }
  34. return aSites;
  35. },
  36. // Tells whether the grid has already been initialized.
  37. get ready() { return !!this._ready; },
  38. // Returns whether the page has finished loading yet.
  39. get isDocumentLoaded() { return document.readyState == "complete"; },
  40. /**
  41. * Initializes the grid.
  42. * @param aSelector The query selector of the grid.
  43. */
  44. init: function() {
  45. this._node = document.getElementById("newtab-grid");
  46. this._gridDefaultContent = this._node.lastChild;
  47. this._createSiteFragment();
  48. gLinks.populateCache(() => {
  49. this._refreshGrid();
  50. this._ready = true;
  51. });
  52. },
  53. /**
  54. * Creates a new site in the grid.
  55. * @param aLink The new site's link.
  56. * @param aCell The cell that will contain the new site.
  57. * @return The newly created site.
  58. */
  59. createSite: function(aLink, aCell) {
  60. let node = aCell.node;
  61. node.appendChild(this._siteFragment.cloneNode(true));
  62. return new Site(node.firstElementChild, aLink);
  63. },
  64. /**
  65. * Handles all grid events.
  66. */
  67. handleEvent: function(aEvent) {
  68. // Any specific events should go here.
  69. },
  70. /**
  71. * Locks the grid to block all pointer events.
  72. */
  73. lock: function() {
  74. this.node.setAttribute("locked", "true");
  75. },
  76. /**
  77. * Unlocks the grid to allow all pointer events.
  78. */
  79. unlock: function() {
  80. this.node.removeAttribute("locked");
  81. },
  82. /**
  83. * Renders the grid.
  84. */
  85. refresh() {
  86. this._refreshGrid();
  87. },
  88. /**
  89. * Renders the grid, including cells and sites.
  90. */
  91. _refreshGrid() {
  92. let row = document.createElementNS(HTML_NAMESPACE, "div");
  93. row.classList.add("newtab-row");
  94. let cell = document.createElementNS(HTML_NAMESPACE, "div");
  95. cell.classList.add("newtab-cell");
  96. // Clear the grid
  97. this._node.innerHTML = "";
  98. // Creates the structure of one row
  99. for (let i = 0; i < gGridPrefs.gridColumns; i++) {
  100. row.appendChild(cell.cloneNode(true));
  101. }
  102. // Creates the grid
  103. for (let j = 0; j < gGridPrefs.gridRows; j++) {
  104. this._node.appendChild(row.cloneNode(true));
  105. }
  106. // Create cell array.
  107. let cellElements = this.node.querySelectorAll(".newtab-cell");
  108. let cells = Array.from(cellElements, (cell) => new Cell(this, cell));
  109. // Fetch links.
  110. let links = gLinks.getLinks();
  111. // Create sites.
  112. let numLinks = Math.min(links.length, cells.length);
  113. for (let i = 0; i < numLinks; i++) {
  114. if (links[i]) {
  115. this.createSite(links[i], cells[i]);
  116. }
  117. }
  118. this._cells = cells;
  119. },
  120. /**
  121. * Creates the DOM fragment that is re-used when creating sites.
  122. */
  123. _createSiteFragment: function() {
  124. let site = document.createElementNS(HTML_NAMESPACE, "div");
  125. site.classList.add("newtab-site");
  126. site.setAttribute("draggable", "true");
  127. // Create the site's inner HTML code.
  128. site.innerHTML =
  129. '<a class="newtab-link">' +
  130. ' <span class="newtab-thumbnail placeholder"/>' +
  131. ' <span class="newtab-thumbnail thumbnail"/>' +
  132. ' <span class="newtab-title"/>' +
  133. '</a>' +
  134. '<input type="button" title="' + newTabString("pin") + '"' +
  135. ' class="newtab-control newtab-control-pin"/>' +
  136. '<input type="button" title="' + newTabString("block") + '"' +
  137. ' class="newtab-control newtab-control-block"/>';
  138. this._siteFragment = document.createDocumentFragment();
  139. this._siteFragment.appendChild(site);
  140. },
  141. /**
  142. * Test a tile at a given position for being pinned or history
  143. * @param position Position in sites array
  144. */
  145. _isHistoricalTile: function(aPos) {
  146. let site = this.sites[aPos];
  147. return site && (site.isPinned() || site.link && site.link.type == "history");
  148. }
  149. };