browser/base/content/newtab/drag.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 implements site dragging functionality.
michael@0 9 */
michael@0 10 let gDrag = {
michael@0 11 /**
michael@0 12 * The site offset to the drag start point.
michael@0 13 */
michael@0 14 _offsetX: null,
michael@0 15 _offsetY: null,
michael@0 16
michael@0 17 /**
michael@0 18 * The site that is dragged.
michael@0 19 */
michael@0 20 _draggedSite: null,
michael@0 21 get draggedSite() this._draggedSite,
michael@0 22
michael@0 23 /**
michael@0 24 * The cell width/height at the point the drag started.
michael@0 25 */
michael@0 26 _cellWidth: null,
michael@0 27 _cellHeight: null,
michael@0 28 get cellWidth() this._cellWidth,
michael@0 29 get cellHeight() this._cellHeight,
michael@0 30
michael@0 31 /**
michael@0 32 * Start a new drag operation.
michael@0 33 * @param aSite The site that's being dragged.
michael@0 34 * @param aEvent The 'dragstart' event.
michael@0 35 */
michael@0 36 start: function Drag_start(aSite, aEvent) {
michael@0 37 this._draggedSite = aSite;
michael@0 38
michael@0 39 // Mark nodes as being dragged.
michael@0 40 let selector = ".newtab-site, .newtab-control, .newtab-thumbnail";
michael@0 41 let parentCell = aSite.node.parentNode;
michael@0 42 let nodes = parentCell.querySelectorAll(selector);
michael@0 43 for (let i = 0; i < nodes.length; i++)
michael@0 44 nodes[i].setAttribute("dragged", "true");
michael@0 45
michael@0 46 parentCell.setAttribute("dragged", "true");
michael@0 47
michael@0 48 this._setDragData(aSite, aEvent);
michael@0 49
michael@0 50 // Store the cursor offset.
michael@0 51 let node = aSite.node;
michael@0 52 let rect = node.getBoundingClientRect();
michael@0 53 this._offsetX = aEvent.clientX - rect.left;
michael@0 54 this._offsetY = aEvent.clientY - rect.top;
michael@0 55
michael@0 56 // Store the cell dimensions.
michael@0 57 let cellNode = aSite.cell.node;
michael@0 58 this._cellWidth = cellNode.offsetWidth;
michael@0 59 this._cellHeight = cellNode.offsetHeight;
michael@0 60
michael@0 61 gTransformation.freezeSitePosition(aSite);
michael@0 62 },
michael@0 63
michael@0 64 /**
michael@0 65 * Handles the 'drag' event.
michael@0 66 * @param aSite The site that's being dragged.
michael@0 67 * @param aEvent The 'drag' event.
michael@0 68 */
michael@0 69 drag: function Drag_drag(aSite, aEvent) {
michael@0 70 // Get the viewport size.
michael@0 71 let {clientWidth, clientHeight} = document.documentElement;
michael@0 72
michael@0 73 // We'll want a padding of 5px.
michael@0 74 let border = 5;
michael@0 75
michael@0 76 // Enforce minimum constraints to keep the drag image inside the window.
michael@0 77 let left = Math.max(scrollX + aEvent.clientX - this._offsetX, border);
michael@0 78 let top = Math.max(scrollY + aEvent.clientY - this._offsetY, border);
michael@0 79
michael@0 80 // Enforce maximum constraints to keep the drag image inside the window.
michael@0 81 left = Math.min(left, scrollX + clientWidth - this.cellWidth - border);
michael@0 82 top = Math.min(top, scrollY + clientHeight - this.cellHeight - border);
michael@0 83
michael@0 84 // Update the drag image's position.
michael@0 85 gTransformation.setSitePosition(aSite, {left: left, top: top});
michael@0 86 },
michael@0 87
michael@0 88 /**
michael@0 89 * Ends the current drag operation.
michael@0 90 * @param aSite The site that's being dragged.
michael@0 91 * @param aEvent The 'dragend' event.
michael@0 92 */
michael@0 93 end: function Drag_end(aSite, aEvent) {
michael@0 94 let nodes = gGrid.node.querySelectorAll("[dragged]")
michael@0 95 for (let i = 0; i < nodes.length; i++)
michael@0 96 nodes[i].removeAttribute("dragged");
michael@0 97
michael@0 98 // Slide the dragged site back into its cell (may be the old or the new cell).
michael@0 99 gTransformation.slideSiteTo(aSite, aSite.cell, {unfreeze: true});
michael@0 100
michael@0 101 this._draggedSite = null;
michael@0 102 },
michael@0 103
michael@0 104 /**
michael@0 105 * Checks whether we're responsible for a given drag event.
michael@0 106 * @param aEvent The drag event to check.
michael@0 107 * @return Whether we should handle this drag and drop operation.
michael@0 108 */
michael@0 109 isValid: function Drag_isValid(aEvent) {
michael@0 110 let link = gDragDataHelper.getLinkFromDragEvent(aEvent);
michael@0 111
michael@0 112 // Check that the drag data is non-empty.
michael@0 113 // Can happen when dragging places folders.
michael@0 114 if (!link || !link.url) {
michael@0 115 return false;
michael@0 116 }
michael@0 117
michael@0 118 // Check that we're not accepting URLs which would inherit the caller's
michael@0 119 // principal (such as javascript: or data:).
michael@0 120 return gLinkChecker.checkLoadURI(link.url);
michael@0 121 },
michael@0 122
michael@0 123 /**
michael@0 124 * Initializes the drag data for the current drag operation.
michael@0 125 * @param aSite The site that's being dragged.
michael@0 126 * @param aEvent The 'dragstart' event.
michael@0 127 */
michael@0 128 _setDragData: function Drag_setDragData(aSite, aEvent) {
michael@0 129 let {url, title} = aSite;
michael@0 130
michael@0 131 let dt = aEvent.dataTransfer;
michael@0 132 dt.mozCursor = "default";
michael@0 133 dt.effectAllowed = "move";
michael@0 134 dt.setData("text/plain", url);
michael@0 135 dt.setData("text/uri-list", url);
michael@0 136 dt.setData("text/x-moz-url", url + "\n" + title);
michael@0 137 dt.setData("text/html", "<a href=\"" + url + "\">" + url + "</a>");
michael@0 138
michael@0 139 // Create and use an empty drag element. We don't want to use the default
michael@0 140 // drag image with its default opacity.
michael@0 141 let dragElement = document.createElementNS(HTML_NAMESPACE, "div");
michael@0 142 dragElement.classList.add("newtab-drag");
michael@0 143 let scrollbox = document.getElementById("newtab-scrollbox");
michael@0 144 scrollbox.appendChild(dragElement);
michael@0 145 dt.setDragImage(dragElement, 0, 0);
michael@0 146
michael@0 147 // After the 'dragstart' event has been processed we can remove the
michael@0 148 // temporary drag element from the DOM.
michael@0 149 setTimeout(function () scrollbox.removeChild(dragElement), 0);
michael@0 150 }
michael@0 151 };

mercurial