1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/base/content/newtab/drag.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,151 @@ 1.4 +#ifdef 0 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.7 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 +#endif 1.9 + 1.10 +/** 1.11 + * This singleton implements site dragging functionality. 1.12 + */ 1.13 +let gDrag = { 1.14 + /** 1.15 + * The site offset to the drag start point. 1.16 + */ 1.17 + _offsetX: null, 1.18 + _offsetY: null, 1.19 + 1.20 + /** 1.21 + * The site that is dragged. 1.22 + */ 1.23 + _draggedSite: null, 1.24 + get draggedSite() this._draggedSite, 1.25 + 1.26 + /** 1.27 + * The cell width/height at the point the drag started. 1.28 + */ 1.29 + _cellWidth: null, 1.30 + _cellHeight: null, 1.31 + get cellWidth() this._cellWidth, 1.32 + get cellHeight() this._cellHeight, 1.33 + 1.34 + /** 1.35 + * Start a new drag operation. 1.36 + * @param aSite The site that's being dragged. 1.37 + * @param aEvent The 'dragstart' event. 1.38 + */ 1.39 + start: function Drag_start(aSite, aEvent) { 1.40 + this._draggedSite = aSite; 1.41 + 1.42 + // Mark nodes as being dragged. 1.43 + let selector = ".newtab-site, .newtab-control, .newtab-thumbnail"; 1.44 + let parentCell = aSite.node.parentNode; 1.45 + let nodes = parentCell.querySelectorAll(selector); 1.46 + for (let i = 0; i < nodes.length; i++) 1.47 + nodes[i].setAttribute("dragged", "true"); 1.48 + 1.49 + parentCell.setAttribute("dragged", "true"); 1.50 + 1.51 + this._setDragData(aSite, aEvent); 1.52 + 1.53 + // Store the cursor offset. 1.54 + let node = aSite.node; 1.55 + let rect = node.getBoundingClientRect(); 1.56 + this._offsetX = aEvent.clientX - rect.left; 1.57 + this._offsetY = aEvent.clientY - rect.top; 1.58 + 1.59 + // Store the cell dimensions. 1.60 + let cellNode = aSite.cell.node; 1.61 + this._cellWidth = cellNode.offsetWidth; 1.62 + this._cellHeight = cellNode.offsetHeight; 1.63 + 1.64 + gTransformation.freezeSitePosition(aSite); 1.65 + }, 1.66 + 1.67 + /** 1.68 + * Handles the 'drag' event. 1.69 + * @param aSite The site that's being dragged. 1.70 + * @param aEvent The 'drag' event. 1.71 + */ 1.72 + drag: function Drag_drag(aSite, aEvent) { 1.73 + // Get the viewport size. 1.74 + let {clientWidth, clientHeight} = document.documentElement; 1.75 + 1.76 + // We'll want a padding of 5px. 1.77 + let border = 5; 1.78 + 1.79 + // Enforce minimum constraints to keep the drag image inside the window. 1.80 + let left = Math.max(scrollX + aEvent.clientX - this._offsetX, border); 1.81 + let top = Math.max(scrollY + aEvent.clientY - this._offsetY, border); 1.82 + 1.83 + // Enforce maximum constraints to keep the drag image inside the window. 1.84 + left = Math.min(left, scrollX + clientWidth - this.cellWidth - border); 1.85 + top = Math.min(top, scrollY + clientHeight - this.cellHeight - border); 1.86 + 1.87 + // Update the drag image's position. 1.88 + gTransformation.setSitePosition(aSite, {left: left, top: top}); 1.89 + }, 1.90 + 1.91 + /** 1.92 + * Ends the current drag operation. 1.93 + * @param aSite The site that's being dragged. 1.94 + * @param aEvent The 'dragend' event. 1.95 + */ 1.96 + end: function Drag_end(aSite, aEvent) { 1.97 + let nodes = gGrid.node.querySelectorAll("[dragged]") 1.98 + for (let i = 0; i < nodes.length; i++) 1.99 + nodes[i].removeAttribute("dragged"); 1.100 + 1.101 + // Slide the dragged site back into its cell (may be the old or the new cell). 1.102 + gTransformation.slideSiteTo(aSite, aSite.cell, {unfreeze: true}); 1.103 + 1.104 + this._draggedSite = null; 1.105 + }, 1.106 + 1.107 + /** 1.108 + * Checks whether we're responsible for a given drag event. 1.109 + * @param aEvent The drag event to check. 1.110 + * @return Whether we should handle this drag and drop operation. 1.111 + */ 1.112 + isValid: function Drag_isValid(aEvent) { 1.113 + let link = gDragDataHelper.getLinkFromDragEvent(aEvent); 1.114 + 1.115 + // Check that the drag data is non-empty. 1.116 + // Can happen when dragging places folders. 1.117 + if (!link || !link.url) { 1.118 + return false; 1.119 + } 1.120 + 1.121 + // Check that we're not accepting URLs which would inherit the caller's 1.122 + // principal (such as javascript: or data:). 1.123 + return gLinkChecker.checkLoadURI(link.url); 1.124 + }, 1.125 + 1.126 + /** 1.127 + * Initializes the drag data for the current drag operation. 1.128 + * @param aSite The site that's being dragged. 1.129 + * @param aEvent The 'dragstart' event. 1.130 + */ 1.131 + _setDragData: function Drag_setDragData(aSite, aEvent) { 1.132 + let {url, title} = aSite; 1.133 + 1.134 + let dt = aEvent.dataTransfer; 1.135 + dt.mozCursor = "default"; 1.136 + dt.effectAllowed = "move"; 1.137 + dt.setData("text/plain", url); 1.138 + dt.setData("text/uri-list", url); 1.139 + dt.setData("text/x-moz-url", url + "\n" + title); 1.140 + dt.setData("text/html", "<a href=\"" + url + "\">" + url + "</a>"); 1.141 + 1.142 + // Create and use an empty drag element. We don't want to use the default 1.143 + // drag image with its default opacity. 1.144 + let dragElement = document.createElementNS(HTML_NAMESPACE, "div"); 1.145 + dragElement.classList.add("newtab-drag"); 1.146 + let scrollbox = document.getElementById("newtab-scrollbox"); 1.147 + scrollbox.appendChild(dragElement); 1.148 + dt.setDragImage(dragElement, 0, 0); 1.149 + 1.150 + // After the 'dragstart' event has been processed we can remove the 1.151 + // temporary drag element from the DOM. 1.152 + setTimeout(function () scrollbox.removeChild(dragElement), 0); 1.153 + } 1.154 +};