mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
362 lines
9.2 KiB
JavaScript
362 lines
9.2 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
const PREF_NEWTAB_ENABLED = "browser.newtabpage.enabled";
|
|
|
|
Services.prefs.setBoolPref(PREF_NEWTAB_ENABLED, true);
|
|
|
|
let tmp = {};
|
|
Cu.import("resource:///modules/NewTabUtils.jsm", tmp);
|
|
Cc["@mozilla.org/moz/jssubscript-loader;1"]
|
|
.getService(Ci.mozIJSSubScriptLoader)
|
|
.loadSubScript("chrome://browser/content/sanitize.js", tmp);
|
|
|
|
let {NewTabUtils, Sanitizer} = tmp;
|
|
|
|
let uri = Services.io.newURI("about:newtab", null, null);
|
|
let principal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(uri);
|
|
|
|
let sm = Services.domStorageManager;
|
|
let storage = sm.getLocalStorageForPrincipal(principal, "");
|
|
|
|
registerCleanupFunction(function () {
|
|
while (gBrowser.tabs.length > 1)
|
|
gBrowser.removeTab(gBrowser.tabs[1]);
|
|
|
|
Services.prefs.clearUserPref(PREF_NEWTAB_ENABLED);
|
|
});
|
|
|
|
/**
|
|
* Provide the default test function to start our test runner.
|
|
*/
|
|
function test() {
|
|
TestRunner.run();
|
|
}
|
|
|
|
/**
|
|
* The test runner that controls the execution flow of our tests.
|
|
*/
|
|
let TestRunner = {
|
|
/**
|
|
* Starts the test runner.
|
|
*/
|
|
run: function () {
|
|
waitForExplicitFinish();
|
|
|
|
this._iter = runTests();
|
|
this.next();
|
|
},
|
|
|
|
/**
|
|
* Runs the next available test or finishes if there's no test left.
|
|
*/
|
|
next: function () {
|
|
try {
|
|
TestRunner._iter.next();
|
|
} catch (e if e instanceof StopIteration) {
|
|
TestRunner.finish();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Finishes all tests and cleans up.
|
|
*/
|
|
finish: function () {
|
|
function cleanupAndFinish() {
|
|
clearHistory();
|
|
whenPagesUpdated(finish);
|
|
NewTabUtils.restore();
|
|
}
|
|
|
|
let callbacks = NewTabUtils.links._populateCallbacks;
|
|
let numCallbacks = callbacks.length;
|
|
|
|
if (numCallbacks)
|
|
callbacks.splice(0, numCallbacks, cleanupAndFinish);
|
|
else
|
|
cleanupAndFinish();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Returns the selected tab's content window.
|
|
* @return The content window.
|
|
*/
|
|
function getContentWindow() {
|
|
return gBrowser.selectedBrowser.contentWindow;
|
|
}
|
|
|
|
/**
|
|
* Returns the selected tab's content document.
|
|
* @return The content document.
|
|
*/
|
|
function getContentDocument() {
|
|
return gBrowser.selectedBrowser.contentDocument;
|
|
}
|
|
|
|
/**
|
|
* Returns the newtab grid of the selected tab.
|
|
* @return The newtab grid.
|
|
*/
|
|
function getGrid() {
|
|
return getContentWindow().gGrid;
|
|
}
|
|
|
|
/**
|
|
* Returns the cell at the given index of the selected tab's newtab grid.
|
|
* @param aIndex The cell index.
|
|
* @return The newtab cell.
|
|
*/
|
|
function getCell(aIndex) {
|
|
return getGrid().cells[aIndex];
|
|
}
|
|
|
|
/**
|
|
* Allows to provide a list of links that is used to construct the grid.
|
|
* @param aLinksPattern the pattern (see below)
|
|
*
|
|
* Example: setLinks("1,2,3")
|
|
* Result: [{url: "http://example.com/#1", title: "site#1"},
|
|
* {url: "http://example.com/#2", title: "site#2"}
|
|
* {url: "http://example.com/#3", title: "site#3"}]
|
|
*/
|
|
function setLinks(aLinks) {
|
|
let links = aLinks;
|
|
|
|
if (typeof links == "string") {
|
|
links = aLinks.split(/\s*,\s*/).map(function (id) {
|
|
return {url: "http://example.com/#" + id, title: "site#" + id};
|
|
});
|
|
}
|
|
|
|
clearHistory();
|
|
fillHistory(links, function () {
|
|
NewTabUtils.links.populateCache(function () {
|
|
NewTabUtils.allPages.update();
|
|
TestRunner.next();
|
|
}, true);
|
|
});
|
|
}
|
|
|
|
function clearHistory() {
|
|
PlacesUtils.history.removeAllPages();
|
|
}
|
|
|
|
function fillHistory(aLinks, aCallback) {
|
|
let numLinks = aLinks.length;
|
|
let transitionLink = Ci.nsINavHistoryService.TRANSITION_LINK;
|
|
|
|
for (let link of aLinks.reverse()) {
|
|
let place = {
|
|
uri: makeURI(link.url),
|
|
title: link.title,
|
|
visits: [{visitDate: Date.now() * 1000, transitionType: transitionLink}]
|
|
};
|
|
|
|
PlacesUtils.asyncHistory.updatePlaces(place, {
|
|
handleError: function () ok(false, "couldn't add visit to history"),
|
|
handleResult: function () {},
|
|
handleCompletion: function () {
|
|
if (--numLinks == 0)
|
|
aCallback();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Allows to specify the list of pinned links (that have a fixed position in
|
|
* the grid.
|
|
* @param aLinksPattern the pattern (see below)
|
|
*
|
|
* Example: setPinnedLinks("3,,1")
|
|
* Result: 'http://example.com/#3' is pinned in the first cell. 'http://example.com/#1' is
|
|
* pinned in the third cell.
|
|
*/
|
|
function setPinnedLinks(aLinks) {
|
|
let links = aLinks;
|
|
|
|
if (typeof links == "string") {
|
|
links = aLinks.split(/\s*,\s*/).map(function (id) {
|
|
if (id)
|
|
return {url: "http://example.com/#" + id, title: "site#" + id};
|
|
});
|
|
}
|
|
|
|
storage.setItem("pinnedLinks", JSON.stringify(links));
|
|
NewTabUtils.pinnedLinks.resetCache();
|
|
NewTabUtils.allPages.update();
|
|
}
|
|
|
|
/**
|
|
* Restore the grid state.
|
|
*/
|
|
function restore() {
|
|
whenPagesUpdated();
|
|
NewTabUtils.restore();
|
|
}
|
|
|
|
/**
|
|
* Creates a new tab containing 'about:newtab'.
|
|
*/
|
|
function addNewTabPageTab() {
|
|
let tab = gBrowser.selectedTab = gBrowser.addTab("about:newtab");
|
|
let browser = tab.linkedBrowser;
|
|
|
|
// Wait for the new tab page to be loaded.
|
|
browser.addEventListener("load", function onLoad() {
|
|
browser.removeEventListener("load", onLoad, true);
|
|
|
|
if (NewTabUtils.allPages.enabled) {
|
|
// Continue when the link cache has been populated.
|
|
NewTabUtils.links.populateCache(function () {
|
|
executeSoon(TestRunner.next);
|
|
});
|
|
} else {
|
|
TestRunner.next();
|
|
}
|
|
}, true);
|
|
}
|
|
|
|
/**
|
|
* Compares the current grid arrangement with the given pattern.
|
|
* @param the pattern (see below)
|
|
* @param the array of sites to compare with (optional)
|
|
*
|
|
* Example: checkGrid("3p,2,,1p")
|
|
* Result: We expect the first cell to contain the pinned site 'http://example.com/#3'.
|
|
* The second cell contains 'http://example.com/#2'. The third cell is empty.
|
|
* The fourth cell contains the pinned site 'http://example.com/#4'.
|
|
*/
|
|
function checkGrid(aSitesPattern, aSites) {
|
|
let length = aSitesPattern.split(",").length;
|
|
let sites = (aSites || getGrid().sites).slice(0, length);
|
|
let current = sites.map(function (aSite) {
|
|
if (!aSite)
|
|
return "";
|
|
|
|
let pinned = aSite.isPinned();
|
|
let pinButton = aSite.node.querySelector(".newtab-control-pin");
|
|
let hasPinnedAttr = pinButton.hasAttribute("pinned");
|
|
|
|
if (pinned != hasPinnedAttr)
|
|
ok(false, "invalid state (site.isPinned() != site[pinned])");
|
|
|
|
return aSite.url.replace(/^http:\/\/example\.com\/#(\d+)$/, "$1") + (pinned ? "p" : "");
|
|
});
|
|
|
|
is(current, aSitesPattern, "grid status = " + aSitesPattern);
|
|
}
|
|
|
|
/**
|
|
* Blocks a site from the grid.
|
|
* @param aIndex The cell index.
|
|
*/
|
|
function blockCell(aIndex) {
|
|
whenPagesUpdated();
|
|
getCell(aIndex).site.block();
|
|
}
|
|
|
|
/**
|
|
* Pins a site on a given position.
|
|
* @param aIndex The cell index.
|
|
* @param aPinIndex The index the defines where the site should be pinned.
|
|
*/
|
|
function pinCell(aIndex, aPinIndex) {
|
|
getCell(aIndex).site.pin(aPinIndex);
|
|
}
|
|
|
|
/**
|
|
* Unpins the given cell's site.
|
|
* @param aIndex The cell index.
|
|
*/
|
|
function unpinCell(aIndex) {
|
|
whenPagesUpdated();
|
|
getCell(aIndex).site.unpin();
|
|
}
|
|
|
|
/**
|
|
* Simulates a drop and drop operation.
|
|
* @param aDropIndex The cell index of the drop target.
|
|
* @param aDragIndex The cell index containing the dragged site (optional).
|
|
*/
|
|
function simulateDrop(aDropIndex, aDragIndex) {
|
|
let draggedSite;
|
|
let {gDrag: drag, gDrop: drop} = getContentWindow();
|
|
let event = createDragEvent("drop", "http://example.com/#99\nblank");
|
|
|
|
if (typeof aDragIndex != "undefined")
|
|
draggedSite = getCell(aDragIndex).site;
|
|
|
|
if (draggedSite)
|
|
drag.start(draggedSite, event);
|
|
|
|
whenPagesUpdated();
|
|
drop.drop(getCell(aDropIndex), event);
|
|
|
|
if (draggedSite)
|
|
drag.end(draggedSite);
|
|
}
|
|
|
|
/**
|
|
* Sends a custom drag event to a given DOM element.
|
|
* @param aEventType The drag event's type.
|
|
* @param aTarget The DOM element that the event is dispatched to.
|
|
* @param aData The event's drag data (optional).
|
|
*/
|
|
function sendDragEvent(aEventType, aTarget, aData) {
|
|
let event = createDragEvent(aEventType, aData);
|
|
let ifaceReq = getContentWindow().QueryInterface(Ci.nsIInterfaceRequestor);
|
|
let windowUtils = ifaceReq.getInterface(Ci.nsIDOMWindowUtils);
|
|
windowUtils.dispatchDOMEventViaPresShell(aTarget, event, true);
|
|
}
|
|
|
|
/**
|
|
* Creates a custom drag event.
|
|
* @param aEventType The drag event's type.
|
|
* @param aData The event's drag data (optional).
|
|
* @return The drag event.
|
|
*/
|
|
function createDragEvent(aEventType, aData) {
|
|
let dataTransfer = {
|
|
mozUserCancelled: false,
|
|
setData: function () null,
|
|
setDragImage: function () null,
|
|
getData: function () aData,
|
|
|
|
types: {
|
|
contains: function (aType) aType == "text/x-moz-url"
|
|
},
|
|
|
|
mozGetDataAt: function (aType, aIndex) {
|
|
if (aIndex || aType != "text/x-moz-url")
|
|
return null;
|
|
|
|
return aData;
|
|
}
|
|
};
|
|
|
|
let event = getContentDocument().createEvent("DragEvents");
|
|
event.initDragEvent(aEventType, true, true, getContentWindow(), 0, 0, 0, 0, 0,
|
|
false, false, false, false, 0, null, dataTransfer);
|
|
|
|
return event;
|
|
}
|
|
|
|
/**
|
|
* Resumes testing when all pages have been updated.
|
|
*/
|
|
function whenPagesUpdated(aCallback) {
|
|
let page = {
|
|
update: function () {
|
|
NewTabUtils.allPages.unregister(this);
|
|
executeSoon(aCallback || TestRunner.next);
|
|
}
|
|
};
|
|
|
|
NewTabUtils.allPages.register(page);
|
|
registerCleanupFunction(function () {
|
|
NewTabUtils.allPages.unregister(page);
|
|
});
|
|
}
|