mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-05 23:07:31 +09:00
Issue #517 Part 1: Import newtab page from Basilisk (sans directory service provider module)
This commit is contained in:
parent
a179019413
commit
48cdeab201
20 changed files with 4821 additions and 314 deletions
|
|
@ -4,6 +4,9 @@
|
|||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#endif
|
||||
|
||||
// The amount of time we wait while coalescing updates for hidden pages.
|
||||
const SCHEDULE_UPDATE_TIMEOUT_MS = 1000;
|
||||
|
||||
/**
|
||||
* This singleton represents the whole 'New Tab Page' and takes care of
|
||||
* initializing all its components.
|
||||
|
|
@ -19,9 +22,10 @@ var gPage = {
|
|||
// Listen for 'unload' to unregister this page.
|
||||
addEventListener("unload", this, false);
|
||||
|
||||
// Listen for toggle button clicks.
|
||||
let button = document.getElementById("newtab-toggle");
|
||||
button.addEventListener("click", this, false);
|
||||
// XXX bug 991111 - Not all click events are correctly triggered when
|
||||
// listening from xhtml nodes -- in particular middle clicks on sites, so
|
||||
// listen from the xul window and filter then delegate
|
||||
addEventListener("click", this, false);
|
||||
|
||||
// Check if the new tab feature is enabled.
|
||||
let enabled = gAllPages.enabled;
|
||||
|
|
@ -29,31 +33,75 @@ var gPage = {
|
|||
this._init();
|
||||
|
||||
this._updateAttributes(enabled);
|
||||
|
||||
// Initialize customize controls.
|
||||
gCustomize.init();
|
||||
},
|
||||
|
||||
/**
|
||||
* Listens for notifications specific to this page.
|
||||
*/
|
||||
observe: function Page_observe() {
|
||||
let enabled = gAllPages.enabled;
|
||||
this._updateAttributes(enabled);
|
||||
observe: function Page_observe(aSubject, aTopic, aData) {
|
||||
if (aTopic == "nsPref:changed") {
|
||||
gCustomize.updateSelected();
|
||||
|
||||
// Initialize the whole page if we haven't done that, yet.
|
||||
if (enabled) {
|
||||
this._init();
|
||||
} else {
|
||||
gUndoDialog.hide();
|
||||
let enabled = gAllPages.enabled;
|
||||
this._updateAttributes(enabled);
|
||||
|
||||
// Update thumbnails to the new enhanced setting
|
||||
if (aData == "browser.newtabpage.enhanced") {
|
||||
this.update();
|
||||
}
|
||||
|
||||
// Initialize the whole page if we haven't done that, yet.
|
||||
if (enabled) {
|
||||
this._init();
|
||||
} else {
|
||||
gUndoDialog.hide();
|
||||
}
|
||||
} else if (aTopic == "page-thumbnail:create" && gGrid.ready) {
|
||||
for (let site of gGrid.sites) {
|
||||
if (site && site.url === aData) {
|
||||
site.refreshThumbnail();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the whole page and the grid when the storage has changed.
|
||||
* Updates the page's grid right away for visible pages. If the page is
|
||||
* currently hidden, i.e. in a background tab or in the preloader, then we
|
||||
* batch multiple update requests and refresh the grid once after a short
|
||||
* delay. Accepts a single parameter the specifies the reason for requesting
|
||||
* a page update. The page may decide to delay or prevent a requested updated
|
||||
* based on the given reason.
|
||||
*/
|
||||
update: function Page_update() {
|
||||
// The grid might not be ready yet as we initialize it asynchronously.
|
||||
if (gGrid.ready) {
|
||||
gGrid.refresh();
|
||||
update(reason = "") {
|
||||
// Update immediately if we're visible.
|
||||
if (!document.hidden) {
|
||||
// Ignore updates where reason=links-changed as those signal that the
|
||||
// provider's set of links changed. We don't want to update visible pages
|
||||
// in that case, it is ok to wait until the user opens the next tab.
|
||||
if (reason != "links-changed" && gGrid.ready) {
|
||||
gGrid.refresh();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Bail out if we scheduled before.
|
||||
if (this._scheduleUpdateTimeout) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._scheduleUpdateTimeout = setTimeout(() => {
|
||||
// Refresh if the grid is ready.
|
||||
if (gGrid.ready) {
|
||||
gGrid.refresh();
|
||||
}
|
||||
|
||||
this._scheduleUpdateTimeout = null;
|
||||
}, SCHEDULE_UPDATE_TIMEOUT_MS);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -66,19 +114,35 @@ var gPage = {
|
|||
|
||||
this._initialized = true;
|
||||
|
||||
gLinks.populateCache(function () {
|
||||
// Initialize and render the grid.
|
||||
gGrid.init();
|
||||
// Set submit button label for when CSS background are disabled (e.g.
|
||||
// high contrast mode).
|
||||
document.getElementById("newtab-search-submit").value =
|
||||
document.body.getAttribute("dir") == "ltr" ? "\u25B6" : "\u25C0";
|
||||
|
||||
// Initialize the drop target shim.
|
||||
gDropTargetShim.init();
|
||||
if (Services.prefs.getBoolPref("browser.newtabpage.compact")) {
|
||||
document.body.classList.add("compact");
|
||||
}
|
||||
|
||||
// Initialize search.
|
||||
gSearch.init();
|
||||
|
||||
if (document.hidden) {
|
||||
addEventListener("visibilitychange", this);
|
||||
} else {
|
||||
setTimeout(() => this.onPageFirstVisible());
|
||||
}
|
||||
|
||||
// Initialize and render the grid.
|
||||
gGrid.init();
|
||||
|
||||
// Initialize the drop target shim.
|
||||
gDropTargetShim.init();
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// Workaround to prevent a delay on MacOSX due to a slow drop animation.
|
||||
document.addEventListener("dragover", this, false);
|
||||
document.addEventListener("drop", this, false);
|
||||
// Workaround to prevent a delay on MacOSX due to a slow drop animation.
|
||||
document.addEventListener("dragover", this, false);
|
||||
document.addEventListener("drop", this, false);
|
||||
#endif
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -87,7 +151,7 @@ var gPage = {
|
|||
*/
|
||||
_updateAttributes: function Page_updateAttributes(aValue) {
|
||||
// Set the nodes' states.
|
||||
let nodeSelector = "#newtab-scrollbox, #newtab-toggle, #newtab-grid";
|
||||
let nodeSelector = "#newtab-grid, #newtab-search-container";
|
||||
for (let node of document.querySelectorAll(nodeSelector)) {
|
||||
if (aValue)
|
||||
node.removeAttribute("page-disabled");
|
||||
|
|
@ -98,15 +162,28 @@ var gPage = {
|
|||
// Enables/disables the control and link elements.
|
||||
let inputSelector = ".newtab-control, .newtab-link";
|
||||
for (let input of document.querySelectorAll(inputSelector)) {
|
||||
if (aValue)
|
||||
if (aValue)
|
||||
input.removeAttribute("tabindex");
|
||||
else
|
||||
input.setAttribute("tabindex", "-1");
|
||||
}
|
||||
},
|
||||
|
||||
// Update the toggle button's title.
|
||||
let toggle = document.getElementById("newtab-toggle");
|
||||
toggle.setAttribute("title", newTabString(aValue ? "hide" : "show"));
|
||||
/**
|
||||
* Handles unload event
|
||||
*/
|
||||
_handleUnloadEvent: function Page_handleUnloadEvent() {
|
||||
gAllPages.unregister(this);
|
||||
// compute page life-span and send telemetry probe: using milli-seconds will leave
|
||||
// many low buckets empty. Instead we use half-second precision to make low end
|
||||
// of histogram linear and not lose the change in user attention
|
||||
let delta = Math.round((Date.now() - this._firstVisibleTime) / 500);
|
||||
if (this._suggestedTilePresent) {
|
||||
Services.telemetry.getHistogramById("NEWTAB_PAGE_LIFE_SPAN_SUGGESTED").add(delta);
|
||||
}
|
||||
else {
|
||||
Services.telemetry.getHistogramById("NEWTAB_PAGE_LIFE_SPAN").add(delta);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -114,11 +191,22 @@ var gPage = {
|
|||
*/
|
||||
handleEvent: function Page_handleEvent(aEvent) {
|
||||
switch (aEvent.type) {
|
||||
case "load":
|
||||
this.onPageVisibleAndLoaded();
|
||||
break;
|
||||
case "unload":
|
||||
gAllPages.unregister(this);
|
||||
this._handleUnloadEvent();
|
||||
break;
|
||||
case "click":
|
||||
gAllPages.enabled = !gAllPages.enabled;
|
||||
let {button, target} = aEvent;
|
||||
// Go up ancestors until we find a Site or not
|
||||
while (target) {
|
||||
if (target.hasOwnProperty("_newtabSite")) {
|
||||
target._newtabSite.onClick(aEvent);
|
||||
break;
|
||||
}
|
||||
target = target.parentNode;
|
||||
}
|
||||
break;
|
||||
case "dragover":
|
||||
if (gDrag.isValid(aEvent) && gDrag.draggedSite)
|
||||
|
|
@ -130,6 +218,80 @@ var gPage = {
|
|||
aEvent.stopPropagation();
|
||||
}
|
||||
break;
|
||||
case "visibilitychange":
|
||||
// Cancel any delayed updates for hidden pages now that we're visible.
|
||||
if (this._scheduleUpdateTimeout) {
|
||||
clearTimeout(this._scheduleUpdateTimeout);
|
||||
this._scheduleUpdateTimeout = null;
|
||||
|
||||
// An update was pending so force an update now.
|
||||
this.update();
|
||||
}
|
||||
|
||||
setTimeout(() => this.onPageFirstVisible());
|
||||
removeEventListener("visibilitychange", this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onPageFirstVisible: function () {
|
||||
// Record another page impression.
|
||||
Services.telemetry.getHistogramById("NEWTAB_PAGE_SHOWN").add(true);
|
||||
|
||||
for (let site of gGrid.sites) {
|
||||
if (site) {
|
||||
// The site may need to modify and/or re-render itself if
|
||||
// something changed after newtab was created by preloader.
|
||||
// For example, the suggested tile endTime may have passed.
|
||||
site.onFirstVisible();
|
||||
}
|
||||
}
|
||||
|
||||
// save timestamp to compute page life-span delta
|
||||
this._firstVisibleTime = Date.now();
|
||||
|
||||
if (document.readyState == "complete") {
|
||||
this.onPageVisibleAndLoaded();
|
||||
} else {
|
||||
addEventListener("load", this);
|
||||
}
|
||||
},
|
||||
|
||||
onPageVisibleAndLoaded() {
|
||||
// Send the index of the last visible tile.
|
||||
this.reportLastVisibleTileIndex();
|
||||
// Maybe tell the user they can undo an initial automigration
|
||||
this.maybeShowAutoMigrationUndoNotification();
|
||||
},
|
||||
|
||||
reportLastVisibleTileIndex() {
|
||||
let cwu = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
|
||||
let rect = cwu.getBoundsWithoutFlushing(gGrid.node);
|
||||
let nodes = cwu.nodesFromRect(rect.left, rect.top, 0, rect.width,
|
||||
rect.height, 0, true, false);
|
||||
|
||||
let i = -1;
|
||||
let lastIndex = -1;
|
||||
let sites = gGrid.sites;
|
||||
|
||||
for (let node of nodes) {
|
||||
if (node.classList && node.classList.contains("newtab-cell")) {
|
||||
if (sites[++i]) {
|
||||
lastIndex = i;
|
||||
if (sites[i].link.targetedSite) {
|
||||
// record that suggested tile is shown to use suggested-tiles-histogram
|
||||
this._suggestedTilePresent = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DirectoryLinksProvider.reportSitesAction(sites, "view", lastIndex);
|
||||
},
|
||||
|
||||
maybeShowAutoMigrationUndoNotification() {
|
||||
// sendAsyncMessage("NewTab:MaybeShowAutoMigrationUndoNotification");
|
||||
},
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue