browser/base/content/newtab/drag.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial