/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ const TEST_URL = "http://www.mozilla.org"; const TEST_TITLE = "example_title"; var gBookmarksToolbar = window.document.getElementById("PersonalToolbar"); var dragDirections = { LEFT: 0, UP: 1, RIGHT: 2, DOWN: 3 }; /** * Tests dragging on toolbar. * * We must test these 2 cases: * - Dragging toward left, top, right should start a drag. * - Dragging toward down should should open the container if the item is a * container, drag the item otherwise. * * @param {object} aElement * DOM node element we will drag * @param {Array} aExpectedDragData * Array of flavors and values in the form: * [ ["text/plain: sometext", "text/html: sometext"], [...] ] * Pass an empty array to check that drag even has been canceled. * @param {number} aDirection * Direction for the dragging gesture, see dragDirections helper object. * @returns {Promise} Resolved once the drag gesture has been observed. */ function synthesizeDragWithDirection(aElement, aExpectedDragData, aDirection) { let promise = new Promise(resolve => { // Dragstart listener function. gBookmarksToolbar.addEventListener("dragstart", function listener(event) { info("A dragstart event has been trapped."); var dataTransfer = event.dataTransfer; is( dataTransfer.mozItemCount, aExpectedDragData.length, "Number of dragged items should be the same." ); for (var t = 0; t < dataTransfer.mozItemCount; t++) { var types = dataTransfer.mozTypesAt(t); var expecteditem = aExpectedDragData[t]; is( types.length, expecteditem.length, "Number of flavors for item " + t + " should be the same." ); for (var f = 0; f < types.length; f++) { is( types[f], expecteditem[f].substring(0, types[f].length), "Flavor " + types[f] + " for item " + t + " should be the same." ); is( dataTransfer.mozGetDataAt(types[f], t), expecteditem[f].substring(types[f].length + 2), "Contents for item " + t + " with flavor " + types[f] + " should be the same." ); } } if (!aExpectedDragData.length) { ok(event.defaultPrevented, "Drag has been canceled."); } event.preventDefault(); event.stopPropagation(); gBookmarksToolbar.removeEventListener("dragstart", listener); // This is likely to cause a click event, and, in case we are dragging a // bookmark, an unwanted page visit. Prevent the click event. aElement.addEventListener("click", prevent); EventUtils.synthesizeMouse( aElement, startingPoint.x + xIncrement * 9, startingPoint.y + yIncrement * 9, { type: "mouseup" } ); aElement.removeEventListener("click", prevent); // Cleanup eventually opened menus. if (aElement.localName == "menu" && aElement.open) { aElement.open = false; } resolve(); }); }); var prevent = function (aEvent) { aEvent.preventDefault(); }; var xIncrement = 0; var yIncrement = 0; switch (aDirection) { case dragDirections.LEFT: xIncrement = -1; break; case dragDirections.RIGHT: xIncrement = +1; break; case dragDirections.UP: yIncrement = -1; break; case dragDirections.DOWN: yIncrement = +1; break; } var rect = aElement.getBoundingClientRect(); var startingPoint = { x: (rect.right - rect.left) / 2, y: (rect.bottom - rect.top) / 2, }; EventUtils.synthesizeMouse(aElement, startingPoint.x, startingPoint.y, { type: "mousedown", }); EventUtils.synthesizeMouse( aElement, startingPoint.x + xIncrement * 1, startingPoint.y + yIncrement * 1, { type: "mousemove" } ); EventUtils.synthesizeMouse( aElement, startingPoint.x + xIncrement * 9, startingPoint.y + yIncrement * 9, { type: "mousemove" } ); return promise; } function getToolbarNodeForItemId(itemGuid) { var children = document.getElementById("PlacesToolbarItems").children; for (let child of children) { if (itemGuid == child._placesNode.bookmarkGuid) { return child; } } return null; } function getExpectedDataForPlacesNode(aNode) { var wrappedNode = []; var flavors = [ "text/x-moz-place", "text/x-moz-url", "text/plain", "text/html", ]; flavors.forEach(function (aFlavor) { var wrappedFlavor = aFlavor + ": " + PlacesUtils.wrapNode(aNode, aFlavor); wrappedNode.push(wrappedFlavor); }); return [wrappedNode]; } add_setup(async function () { var toolbar = document.getElementById("PersonalToolbar"); var wasCollapsed = toolbar.collapsed; // Uncollapse the personal toolbar if needed. if (wasCollapsed) { await promiseSetToolbarVisibility(toolbar, true); } registerCleanupFunction(async () => { // Collapse the personal toolbar if needed. await promiseSetToolbarVisibility(toolbar, false); }); }); add_task(async function test_drag_folder_on_toolbar() { let folder = await PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.toolbarGuid, title: TEST_TITLE, type: PlacesUtils.bookmarks.TYPE_FOLDER, }); var element = getToolbarNodeForItemId(folder.guid); isnot(element, null, "Found node on toolbar"); isnot( element._placesNode, null, "Toolbar node has an associated Places node." ); var expectedData = getExpectedDataForPlacesNode(element._placesNode); info("Dragging left"); await synthesizeDragWithDirection(element, expectedData, dragDirections.LEFT); info("Dragging right"); await synthesizeDragWithDirection( element, expectedData, dragDirections.RIGHT ); info("Dragging up"); await synthesizeDragWithDirection(element, expectedData, dragDirections.UP); info("Dragging down"); await synthesizeDragWithDirection(element, [], dragDirections.DOWN); await PlacesUtils.bookmarks.remove(folder); }); add_task(async function test_drag_bookmark_on_toolbar() { var bookmark = await PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.toolbarGuid, title: TEST_TITLE, url: TEST_URL, }); var element = getToolbarNodeForItemId(bookmark.guid); isnot(element, null, "Found node on toolbar"); isnot( element._placesNode, null, "Toolbar node has an associated Places node." ); var expectedData = getExpectedDataForPlacesNode(element._placesNode); info("Dragging left"); await synthesizeDragWithDirection(element, expectedData, dragDirections.LEFT); info("Dragging right"); await synthesizeDragWithDirection( element, expectedData, dragDirections.RIGHT ); info("Dragging up"); await synthesizeDragWithDirection(element, expectedData, dragDirections.UP); info("Dragging down"); synthesizeDragWithDirection(element, expectedData, dragDirections.DOWN); await PlacesUtils.bookmarks.remove(bookmark); });