browser/base/content/newtab/page.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 represents the whole 'New Tab Page' and takes care of
michael@0 9 * initializing all its components.
michael@0 10 */
michael@0 11 let gPage = {
michael@0 12 /**
michael@0 13 * Initializes the page.
michael@0 14 */
michael@0 15 init: function Page_init() {
michael@0 16 // Add ourselves to the list of pages to receive notifications.
michael@0 17 gAllPages.register(this);
michael@0 18
michael@0 19 // Listen for 'unload' to unregister this page.
michael@0 20 addEventListener("unload", this, false);
michael@0 21
michael@0 22 // XXX bug 991111 - Not all click events are correctly triggered when
michael@0 23 // listening from xhtml nodes -- in particular middle clicks on sites, so
michael@0 24 // listen from the xul window and filter then delegate
michael@0 25 addEventListener("click", this, false);
michael@0 26
michael@0 27 // Initialize sponsored panel
michael@0 28 this._sponsoredPanel = document.getElementById("sponsored-panel");
michael@0 29 let link = this._sponsoredPanel.querySelector(".text-link");
michael@0 30 link.addEventListener("click", () => this._sponsoredPanel.hidePopup());
michael@0 31 if (UpdateChannel.get().startsWith("release")) {
michael@0 32 document.getElementById("sponsored-panel-trial-descr").style.display = "none";
michael@0 33 }
michael@0 34 else {
michael@0 35 document.getElementById("sponsored-panel-release-descr").style.display = "none";
michael@0 36 }
michael@0 37
michael@0 38 // Check if the new tab feature is enabled.
michael@0 39 let enabled = gAllPages.enabled;
michael@0 40 if (enabled)
michael@0 41 this._init();
michael@0 42
michael@0 43 this._updateAttributes(enabled);
michael@0 44 },
michael@0 45
michael@0 46 /**
michael@0 47 * True if the page is allowed to capture thumbnails using the background
michael@0 48 * thumbnail service.
michael@0 49 */
michael@0 50 get allowBackgroundCaptures() {
michael@0 51 // The preloader is bypassed altogether for private browsing windows, and
michael@0 52 // therefore allow-background-captures will not be set. In that case, the
michael@0 53 // page is not preloaded and so it's visible, so allow background captures.
michael@0 54 return inPrivateBrowsingMode() ||
michael@0 55 document.documentElement.getAttribute("allow-background-captures") ==
michael@0 56 "true";
michael@0 57 },
michael@0 58
michael@0 59 /**
michael@0 60 * Listens for notifications specific to this page.
michael@0 61 */
michael@0 62 observe: function Page_observe(aSubject, aTopic, aData) {
michael@0 63 if (aTopic == "nsPref:changed") {
michael@0 64 let enabled = gAllPages.enabled;
michael@0 65 this._updateAttributes(enabled);
michael@0 66
michael@0 67 // Initialize the whole page if we haven't done that, yet.
michael@0 68 if (enabled) {
michael@0 69 this._init();
michael@0 70 } else {
michael@0 71 gUndoDialog.hide();
michael@0 72 }
michael@0 73 } else if (aTopic == "page-thumbnail:create" && gGrid.ready) {
michael@0 74 for (let site of gGrid.sites) {
michael@0 75 if (site && site.url === aData) {
michael@0 76 site.refreshThumbnail();
michael@0 77 }
michael@0 78 }
michael@0 79 }
michael@0 80 },
michael@0 81
michael@0 82 /**
michael@0 83 * Updates the whole page and the grid when the storage has changed.
michael@0 84 * @param aOnlyIfHidden If true, the page is updated only if it's hidden in
michael@0 85 * the preloader.
michael@0 86 */
michael@0 87 update: function Page_update(aOnlyIfHidden=false) {
michael@0 88 let skipUpdate = aOnlyIfHidden && this.allowBackgroundCaptures;
michael@0 89 // The grid might not be ready yet as we initialize it asynchronously.
michael@0 90 if (gGrid.ready && !skipUpdate) {
michael@0 91 gGrid.refresh();
michael@0 92 }
michael@0 93 },
michael@0 94
michael@0 95 /**
michael@0 96 * Shows sponsored panel
michael@0 97 */
michael@0 98 showSponsoredPanel: function Page_showSponsoredPanel(aTarget) {
michael@0 99 if (this._sponsoredPanel.state == "closed") {
michael@0 100 let self = this;
michael@0 101 this._sponsoredPanel.addEventListener("popuphidden", function onPopupHidden(aEvent) {
michael@0 102 self._sponsoredPanel.removeEventListener("popuphidden", onPopupHidden, false);
michael@0 103 aTarget.removeAttribute("panelShown");
michael@0 104 });
michael@0 105 }
michael@0 106 aTarget.setAttribute("panelShown", "true");
michael@0 107 this._sponsoredPanel.openPopup(aTarget);
michael@0 108 },
michael@0 109
michael@0 110 /**
michael@0 111 * Internally initializes the page. This runs only when/if the feature
michael@0 112 * is/gets enabled.
michael@0 113 */
michael@0 114 _init: function Page_init() {
michael@0 115 if (this._initialized)
michael@0 116 return;
michael@0 117
michael@0 118 this._initialized = true;
michael@0 119
michael@0 120 gSearch.init();
michael@0 121
michael@0 122 this._mutationObserver = new MutationObserver(() => {
michael@0 123 if (this.allowBackgroundCaptures) {
michael@0 124 Services.telemetry.getHistogramById("NEWTAB_PAGE_SHOWN").add(true);
michael@0 125
michael@0 126 // Initialize type counting with the types we want to count
michael@0 127 let directoryCount = {};
michael@0 128 for (let type of DirectoryLinksProvider.linkTypes) {
michael@0 129 directoryCount[type] = 0;
michael@0 130 }
michael@0 131
michael@0 132 for (let site of gGrid.sites) {
michael@0 133 if (site) {
michael@0 134 site.captureIfMissing();
michael@0 135 let {type} = site.link;
michael@0 136 if (type in directoryCount) {
michael@0 137 directoryCount[type]++;
michael@0 138 }
michael@0 139 }
michael@0 140 }
michael@0 141
michael@0 142 // Record how many directory sites were shown, but place counts over the
michael@0 143 // default 9 in the same bucket
michael@0 144 for (let [type, count] of Iterator(directoryCount)) {
michael@0 145 let shownId = "NEWTAB_PAGE_DIRECTORY_" + type.toUpperCase() + "_SHOWN";
michael@0 146 let shownCount = Math.min(10, count);
michael@0 147 Services.telemetry.getHistogramById(shownId).add(shownCount);
michael@0 148 }
michael@0 149
michael@0 150 // content.js isn't loaded for the page while it's in the preloader,
michael@0 151 // which is why this is necessary.
michael@0 152 gSearch.setUpInitialState();
michael@0 153 }
michael@0 154 });
michael@0 155 this._mutationObserver.observe(document.documentElement, {
michael@0 156 attributes: true,
michael@0 157 attributeFilter: ["allow-background-captures"],
michael@0 158 });
michael@0 159
michael@0 160 gLinks.populateCache(function () {
michael@0 161 // Initialize and render the grid.
michael@0 162 gGrid.init();
michael@0 163
michael@0 164 // Initialize the drop target shim.
michael@0 165 gDropTargetShim.init();
michael@0 166
michael@0 167 #ifdef XP_MACOSX
michael@0 168 // Workaround to prevent a delay on MacOSX due to a slow drop animation.
michael@0 169 document.addEventListener("dragover", this, false);
michael@0 170 document.addEventListener("drop", this, false);
michael@0 171 #endif
michael@0 172 }.bind(this));
michael@0 173 },
michael@0 174
michael@0 175 /**
michael@0 176 * Updates the 'page-disabled' attributes of the respective DOM nodes.
michael@0 177 * @param aValue Whether the New Tab Page is enabled or not.
michael@0 178 */
michael@0 179 _updateAttributes: function Page_updateAttributes(aValue) {
michael@0 180 // Set the nodes' states.
michael@0 181 let nodeSelector = "#newtab-scrollbox, #newtab-toggle, #newtab-grid, #newtab-search-container";
michael@0 182 for (let node of document.querySelectorAll(nodeSelector)) {
michael@0 183 if (aValue)
michael@0 184 node.removeAttribute("page-disabled");
michael@0 185 else
michael@0 186 node.setAttribute("page-disabled", "true");
michael@0 187 }
michael@0 188
michael@0 189 // Enables/disables the control and link elements.
michael@0 190 let inputSelector = ".newtab-control, .newtab-link";
michael@0 191 for (let input of document.querySelectorAll(inputSelector)) {
michael@0 192 if (aValue)
michael@0 193 input.removeAttribute("tabindex");
michael@0 194 else
michael@0 195 input.setAttribute("tabindex", "-1");
michael@0 196 }
michael@0 197
michael@0 198 // Update the toggle button's title.
michael@0 199 let toggle = document.getElementById("newtab-toggle");
michael@0 200 toggle.setAttribute("title", newTabString(aValue ? "hide" : "show"));
michael@0 201 },
michael@0 202
michael@0 203 /**
michael@0 204 * Handles all page events.
michael@0 205 */
michael@0 206 handleEvent: function Page_handleEvent(aEvent) {
michael@0 207 switch (aEvent.type) {
michael@0 208 case "unload":
michael@0 209 if (this._mutationObserver)
michael@0 210 this._mutationObserver.disconnect();
michael@0 211 gAllPages.unregister(this);
michael@0 212 break;
michael@0 213 case "click":
michael@0 214 let {button, target} = aEvent;
michael@0 215 if (target.id == "newtab-toggle") {
michael@0 216 if (button == 0) {
michael@0 217 gAllPages.enabled = !gAllPages.enabled;
michael@0 218 }
michael@0 219 break;
michael@0 220 }
michael@0 221
michael@0 222 // Go up ancestors until we find a Site or not
michael@0 223 while (target) {
michael@0 224 if (target.hasOwnProperty("_newtabSite")) {
michael@0 225 target._newtabSite.onClick(aEvent);
michael@0 226 break;
michael@0 227 }
michael@0 228 target = target.parentNode;
michael@0 229 }
michael@0 230 break;
michael@0 231 case "dragover":
michael@0 232 if (gDrag.isValid(aEvent) && gDrag.draggedSite)
michael@0 233 aEvent.preventDefault();
michael@0 234 break;
michael@0 235 case "drop":
michael@0 236 if (gDrag.isValid(aEvent) && gDrag.draggedSite) {
michael@0 237 aEvent.preventDefault();
michael@0 238 aEvent.stopPropagation();
michael@0 239 }
michael@0 240 break;
michael@0 241 }
michael@0 242 }
michael@0 243 };

mercurial