Bug 894876 - part 2 - Let about:newtab d&d test actually initiate and complete a drag session; r=jaws

This commit is contained in:
Tim Taubert 2013-07-24 09:58:50 +02:00
Родитель de8617ccef
Коммит 97f3014cec
4 изменённых файлов: 179 добавлений и 30 удалений

Просмотреть файл

@ -8,16 +8,22 @@ function runTests() {
yield addNewTabPageTab(); yield addNewTabPageTab();
checkGrid("0,1,2,3,4,5,6,7,8"); checkGrid("0,1,2,3,4,5,6,7,8");
yield simulateDrop(1); yield simulateExternalDrop(1);
checkGrid("0,99p,1,2,3,4,5,6,7"); checkGrid("0,99p,1,2,3,4,5,6,7");
yield blockCell(1); yield blockCell(1);
checkGrid("0,1,2,3,4,5,6,7,8"); checkGrid("0,1,2,3,4,5,6,7,8");
yield simulateDrop(1); yield simulateExternalDrop(1);
checkGrid("0,99p,1,2,3,4,5,6,7"); checkGrid("0,99p,1,2,3,4,5,6,7");
// Simulate a restart and force the next about:newtab
// instance to read its data from the storage again.
NewTabUtils.blockedLinks.resetCache(); NewTabUtils.blockedLinks.resetCache();
// Update all open pages, e.g. preloaded ones.
NewTabUtils.allPages.update();
yield addNewTabPageTab(); yield addNewTabPageTab();
checkGrid("0,99p,1,2,3,4,5,6,7"); checkGrid("0,99p,1,2,3,4,5,6,7");

Просмотреть файл

@ -17,7 +17,7 @@ function runTests() {
yield addNewTabPageTab(); yield addNewTabPageTab();
checkGrid("0,1,2,3,4,5,6,7,8"); checkGrid("0,1,2,3,4,5,6,7,8");
yield simulateDrop(1, 0); yield simulateDrop(0, 1);
checkGrid("1,0p,2,3,4,5,6,7,8"); checkGrid("1,0p,2,3,4,5,6,7,8");
// drag a cell to its current cell and make sure it's not pinned afterwards // drag a cell to its current cell and make sure it's not pinned afterwards
@ -37,7 +37,7 @@ function runTests() {
yield addNewTabPageTab(); yield addNewTabPageTab();
checkGrid("0,1p,2p,3,4,5,6,7,8"); checkGrid("0,1p,2p,3,4,5,6,7,8");
yield simulateDrop(3, 0); yield simulateDrop(0, 3);
checkGrid("3,1p,2p,0p,4,5,6,7,8"); checkGrid("3,1p,2p,0p,4,5,6,7,8");
// pinned sites should always be moved around as blocks. if a pinned site is // pinned sites should always be moved around as blocks. if a pinned site is
@ -48,7 +48,7 @@ function runTests() {
yield addNewTabPageTab(); yield addNewTabPageTab();
checkGrid("0p,1p,2,3,4,5,6,7,8"); checkGrid("0p,1p,2,3,4,5,6,7,8");
yield simulateDrop(0, 2); yield simulateDrop(2, 0);
checkGrid("2p,0p,1p,3,4,5,6,7,8"); checkGrid("2p,0p,1p,3,4,5,6,7,8");
// pinned sites should not be pushed out of the grid (unless there are only // pinned sites should not be pushed out of the grid (unless there are only
@ -59,7 +59,7 @@ function runTests() {
yield addNewTabPageTab(); yield addNewTabPageTab();
checkGrid("0,1,2,3,4,5,6,7p,8p"); checkGrid("0,1,2,3,4,5,6,7p,8p");
yield simulateDrop(8, 2); yield simulateDrop(2, 8);
checkGrid("0,1,3,4,5,6,7p,8p,2p"); checkGrid("0,1,3,4,5,6,7p,8p,2p");
// make sure that pinned sites are re-positioned correctly // make sure that pinned sites are re-positioned correctly
@ -69,7 +69,7 @@ function runTests() {
yield addNewTabPageTab(); yield addNewTabPageTab();
checkGrid("0p,1p,2p,3,4,5p,6,7,8"); checkGrid("0p,1p,2p,3,4,5p,6,7,8");
yield simulateDrop(4, 0); yield simulateDrop(0, 4);
checkGrid("3,1p,2p,4,0p,5p,6,7,8"); checkGrid("3,1p,2p,4,0p,5p,6,7,8");
// drag a new site onto the very first cell // drag a new site onto the very first cell
@ -79,7 +79,7 @@ function runTests() {
yield addNewTabPageTab(); yield addNewTabPageTab();
checkGrid("0,1,2,3,4,5,6,7p,8p"); checkGrid("0,1,2,3,4,5,6,7p,8p");
yield simulateDrop(0); yield simulateExternalDrop(0);
checkGrid("99p,0,1,2,3,4,5,7p,8p"); checkGrid("99p,0,1,2,3,4,5,7p,8p");
// drag a new site onto the grid and make sure that pinned cells don't get // drag a new site onto the grid and make sure that pinned cells don't get
@ -90,7 +90,7 @@ function runTests() {
yield addNewTabPageTab(); yield addNewTabPageTab();
checkGrid("0,1,2,3,4,5,6,7p,8p"); checkGrid("0,1,2,3,4,5,6,7p,8p");
yield simulateDrop(7); yield simulateExternalDrop(7);
checkGrid("0,1,2,3,4,5,7p,99p,8p"); checkGrid("0,1,2,3,4,5,7p,99p,8p");
// drag a new site beneath a pinned cell and make sure the pinned cell is // drag a new site beneath a pinned cell and make sure the pinned cell is
@ -101,7 +101,7 @@ function runTests() {
yield addNewTabPageTab(); yield addNewTabPageTab();
checkGrid("0,1,2,3,4,5,6,7,8p"); checkGrid("0,1,2,3,4,5,6,7,8p");
yield simulateDrop(7); yield simulateExternalDrop(7);
checkGrid("0,1,2,3,4,5,6,99p,8p"); checkGrid("0,1,2,3,4,5,6,99p,8p");
// drag a new site onto a block of pinned sites and make sure they're shifted // drag a new site onto a block of pinned sites and make sure they're shifted
@ -112,6 +112,6 @@ function runTests() {
yield addNewTabPageTab(); yield addNewTabPageTab();
checkGrid("0p,1p,2p"); checkGrid("0p,1p,2p");
yield simulateDrop(1); yield simulateExternalDrop(1);
checkGrid("0p,99p,1p,2p,3,4,5,6,7"); checkGrid("0p,99p,1p,2p,3,4,5,6,7");
} }

Просмотреть файл

@ -43,12 +43,12 @@ function runTests() {
ok(oldResetButton.hasAttribute("modified"), "page is modified"); ok(oldResetButton.hasAttribute("modified"), "page is modified");
// insert a new cell by dragging // insert a new cell by dragging
yield simulateDrop(1); yield simulateExternalDrop(1);
checkGrid("0,99p,2,3,4,5,6,7,8"); checkGrid("0,99p,2,3,4,5,6,7,8");
checkGrid("0,99p,2,3,4,5,6,7,8", oldSites); checkGrid("0,99p,2,3,4,5,6,7,8", oldSites);
// drag a cell around // drag a cell around
yield simulateDrop(1, 2); yield simulateDrop(2, 1);
checkGrid("0,2p,99p,3,4,5,6,7,8"); checkGrid("0,2p,99p,3,4,5,6,7,8");
checkGrid("0,2p,99p,3,4,5,6,7,8", oldSites); checkGrid("0,2p,99p,3,4,5,6,7,8", oldSites);

Просмотреть файл

@ -6,16 +6,19 @@ const PREF_NEWTAB_ENABLED = "browser.newtabpage.enabled";
Services.prefs.setBoolPref(PREF_NEWTAB_ENABLED, true); Services.prefs.setBoolPref(PREF_NEWTAB_ENABLED, true);
let tmp = {}; let tmp = {};
Cu.import("resource://gre/modules/Promise.jsm", tmp);
Cu.import("resource://gre/modules/NewTabUtils.jsm", tmp); Cu.import("resource://gre/modules/NewTabUtils.jsm", tmp);
Cc["@mozilla.org/moz/jssubscript-loader;1"] Cc["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader) .getService(Ci.mozIJSSubScriptLoader)
.loadSubScript("chrome://browser/content/sanitize.js", tmp); .loadSubScript("chrome://browser/content/sanitize.js", tmp);
let {Promise, NewTabUtils, Sanitizer} = tmp;
let {NewTabUtils, Sanitizer} = tmp;
let uri = Services.io.newURI("about:newtab", null, null); let uri = Services.io.newURI("about:newtab", null, null);
let principal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(uri); let principal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(uri);
let isMac = ("nsILocalFileMac" in Ci);
let isLinux = ("@mozilla.org/gnome-gconf-service;1" in Cc);
let isWindows = ("@mozilla.org/windows-registry-key;1" in Cc);
let gWindow = window; let gWindow = window;
registerCleanupFunction(function () { registerCleanupFunction(function () {
@ -305,26 +308,166 @@ function unpinCell(aIndex) {
} }
/** /**
* Simulates a drop and drop operation. * Simulates a drag and drop operation.
* @param aDropIndex The cell index of the drop target. * @param aSourceIndex The cell index containing the dragged site.
* @param aDragIndex The cell index containing the dragged site (optional). * @param aDestIndex The cell index of the drop target.
*/ */
function simulateDrop(aDropIndex, aDragIndex) { function simulateDrop(aSourceIndex, aDestIndex) {
let draggedSite; let src = getCell(aSourceIndex).site.node;
let {gDrag: drag, gDrop: drop} = getContentWindow(); let dest = getCell(aDestIndex).node;
let event = createDragEvent("drop", "http://example.com/#99\nblank");
if (typeof aDragIndex != "undefined") // Drop 'src' onto 'dest' and continue testing when all newtab
draggedSite = getCell(aDragIndex).site; // pages have been updated (i.e. the drop operation is completed).
startAndCompleteDragOperation(src, dest, whenPagesUpdated);
}
if (draggedSite) /**
drag.start(draggedSite, event); * Simulates a drag and drop operation. Instead of rearranging a site that is
* is already contained in the newtab grid, this is used to simulate dragging
* an external link onto the grid e.g. the text from the URL bar.
* @param aDestIndex The cell index of the drop target.
*/
function simulateExternalDrop(aDestIndex) {
let dest = getCell(aDestIndex).node;
whenPagesUpdated(); // Create an iframe that contains the external link we'll drag.
drop.drop(getCell(aDropIndex), event); createExternalDropIframe().then(iframe => {
let link = iframe.contentDocument.getElementById("link");
if (draggedSite) // Drop 'link' onto 'dest'.
drag.end(draggedSite); startAndCompleteDragOperation(link, dest, () => {
// Wait until the drop operation is complete
// and all newtab pages have been updated.
whenPagesUpdated(() => {
// Clean up and remove the iframe.
iframe.remove();
// Continue testing.
TestRunner.next();
});
});
});
}
/**
* Starts and complete a drag-and-drop operation.
* @param aSource The node that is being dragged.
* @param aDest The node we're dragging aSource onto.
* @param aCallback The function that is called when we're done.
*/
function startAndCompleteDragOperation(aSource, aDest, aCallback) {
// Start by pressing the left mouse button.
synthesizeNativeMouseLDown(aSource);
// Move the mouse in 5px steps until the drag operation starts.
let offset = 0;
let interval = setInterval(() => {
synthesizeNativeMouseDrag(aSource, offset += 5);
}, 10);
// When the drag operation has started we'll move
// the dragged element to its target position.
aSource.addEventListener("dragstart", function onDragStart() {
aSource.removeEventListener("dragstart", onDragStart);
clearInterval(interval);
// Place the cursor above the drag target.
synthesizeNativeMouseMove(aDest);
});
// As soon as the dragged element hovers the target, we'll drop it.
aDest.addEventListener("dragenter", function onDragEnter() {
aDest.removeEventListener("dragenter", onDragEnter);
// Finish the drop operation.
synthesizeNativeMouseLUp(aDest);
aCallback();
});
}
/**
* Helper function that creates a temporary iframe in the about:newtab
* document. This will contain a link we can drag to the test the dropping
* of links from external documents.
*/
function createExternalDropIframe() {
const url = "data:text/html;charset=utf-8," +
"<a id='link' href='http://example.com/%2399'>link</a>";
let deferred = Promise.defer();
let doc = getContentDocument();
let iframe = doc.createElement("iframe");
iframe.setAttribute("src", url);
iframe.style.width = "50px";
iframe.style.height = "50px";
let margin = doc.getElementById("newtab-margin-top");
margin.appendChild(iframe);
iframe.addEventListener("load", function onLoad() {
iframe.removeEventListener("load", onLoad);
executeSoon(() => deferred.resolve(iframe));
});
return deferred.promise;
}
/**
* Fires a synthetic 'mousedown' event on the current about:newtab page.
* @param aElement The element used to determine the cursor position.
*/
function synthesizeNativeMouseLDown(aElement) {
if (isLinux) {
let win = aElement.ownerDocument.defaultView;
EventUtils.synthesizeMouseAtCenter(aElement, {type: "mousedown"}, win);
} else {
let msg = isWindows ? 2 : 1;
synthesizeNativeMouseEvent(aElement, msg);
}
}
/**
* Fires a synthetic 'mouseup' event on the current about:newtab page.
* @param aElement The element used to determine the cursor position.
*/
function synthesizeNativeMouseLUp(aElement) {
let msg = isWindows ? 4 : (isMac ? 2 : 7);
synthesizeNativeMouseEvent(aElement, msg);
}
/**
* Fires a synthetic mouse drag event on the current about:newtab page.
* @param aElement The element used to determine the cursor position.
* @param aOffsetX The left offset that is added to the position.
*/
function synthesizeNativeMouseDrag(aElement, aOffsetX) {
let msg = isMac ? 6 : 1;
synthesizeNativeMouseEvent(aElement, msg, aOffsetX);
}
/**
* Fires a synthetic 'mousemove' event on the current about:newtab page.
* @param aElement The element used to determine the cursor position.
*/
function synthesizeNativeMouseMove(aElement) {
let msg = isMac ? 5 : 1;
synthesizeNativeMouseEvent(aElement, msg);
}
/**
* Fires a synthetic mouse event on the current about:newtab page.
* @param aElement The element used to determine the cursor position.
* @param aOffsetX The left offset that is added to the position (optional).
* @param aOffsetY The top offset that is added to the position (optional).
*/
function synthesizeNativeMouseEvent(aElement, aMsg, aOffsetX = 0, aOffsetY = 0) {
let rect = aElement.getBoundingClientRect();
let win = aElement.ownerDocument.defaultView;
let x = aOffsetX + win.mozInnerScreenX + rect.left + rect.width / 2;
let y = aOffsetY + win.mozInnerScreenY + rect.top + rect.height / 2;
win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
.sendNativeMouseEvent(x, y, aMsg, 0, null);
} }
/** /**