browser/base/content/newtab/drag.js

changeset 0
6474c204b198
     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 +};

mercurial