Bug 1207594, don't set dropEffect and effectAllowed in tab bar dragover event, which allows drops of data that aren't links, r=dao
authorNeil Deakin <neil@mozilla.com>
Tue, 27 Oct 2015 08:53:00 -0400
changeset 304866 dcd16953417bee8297fbd412a0654b63c3e98b5d
parent 304865 34564c10054d5864e98152b238c9c16b0bad1b80
child 304867 90edb8c62dee69fe55faf84507d70570f9d8eaad
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdao
bugs1207594
milestone44.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1207594, don't set dropEffect and effectAllowed in tab bar dragover event, which allows drops of data that aren't links, r=dao
browser/base/content/tabbrowser.xml
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -5131,86 +5131,84 @@
               ele.removeAttribute("notifybgtab");
             }, 150, this._animateElement);
           }
         ]]></body>
       </method>
 
       <method name="_getDragTargetTab">
         <parameter name="event"/>
+        <parameter name="isLink"/>
         <body><![CDATA[
           let tab = event.target.localName == "tab" ? event.target : null;
-          if (tab &&
-              (event.type == "drop" || event.type == "dragover") &&
-              event.dataTransfer.dropEffect == "link") {
+          if (tab && isLink) {
             let boxObject = tab.boxObject;
             if (event.screenX < boxObject.screenX + boxObject.width * .25 ||
                 event.screenX > boxObject.screenX + boxObject.width * .75)
               return null;
           }
           return tab;
         ]]></body>
       </method>
 
       <method name="_getDropIndex">
         <parameter name="event"/>
+        <parameter name="isLink"/>
         <body><![CDATA[
           var tabs = this.childNodes;
-          var tab = this._getDragTargetTab(event);
+          var tab = this._getDragTargetTab(event, isLink);
           if (window.getComputedStyle(this, null).direction == "ltr") {
             for (let i = tab ? tab._tPos : 0; i < tabs.length; i++)
               if (event.screenX < tabs[i].boxObject.screenX + tabs[i].boxObject.width / 2)
                 return i;
           } else {
             for (let i = tab ? tab._tPos : 0; i < tabs.length; i++)
               if (event.screenX > tabs[i].boxObject.screenX + tabs[i].boxObject.width / 2)
                 return i;
           }
           return tabs.length;
         ]]></body>
       </method>
 
-      <method name="_setEffectAllowedForDataTransfer">
+      <method name="_getDropEffectForTabDrag">
         <parameter name="event"/>
         <body><![CDATA[
           var dt = event.dataTransfer;
           // Disallow dropping multiple items
           if (dt.mozItemCount > 1)
-            return dt.effectAllowed = "none";
+            return "none";
 
           var types = dt.mozTypesAt(0);
           var sourceNode = null;
           // tabs are always added as the first type
           if (types[0] == TAB_DROP_TYPE) {
             var sourceNode = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
             if (sourceNode instanceof XULElement &&
                 sourceNode.localName == "tab" &&
                 sourceNode.ownerDocument.defaultView instanceof ChromeWindow &&
                 sourceNode.ownerDocument.documentElement.getAttribute("windowtype") == "navigator:browser" &&
                 sourceNode.ownerDocument.defaultView.gBrowser.tabContainer == sourceNode.parentNode) {
               // Do not allow transfering a private tab to a non-private window
               // and vice versa.
               if (PrivateBrowsingUtils.isWindowPrivate(window) !=
                   PrivateBrowsingUtils.isWindowPrivate(sourceNode.ownerDocument.defaultView))
-                return dt.effectAllowed = "none";
+                return "none";
 
               if (window.gMultiProcessBrowser !=
                   sourceNode.ownerDocument.defaultView.gMultiProcessBrowser)
-                return dt.effectAllowed = "none";
-
-              let copyModifier = this.tabbrowser.AppConstants.platform == "macosx" ? event.altKey : event.ctrlKey;
-              return dt.effectAllowed = copyModifier ? "copy" : "move";
+                return "none";
+
+              return dt.dropEffect == "copy" ? "copy" : "move";
             }
           }
 
           if (browserDragAndDrop.canDropLink(event)) {
-            // Here we need to do this manually
-            return dt.effectAllowed = dt.dropEffect = "link";
+            return "link";
           }
-          return dt.effectAllowed = "none";
+          return "none";
         ]]></body>
       </method>
 
       <method name="_handleNewTab">
         <parameter name="tab"/>
         <body><![CDATA[
           if (tab.parentNode != this)
             return;
@@ -5477,17 +5475,17 @@
             // Consume the keydown event for the above keyboard
             // shortcuts only.
             return;
         }
         event.preventDefault();
       ]]></handler>
 
       <handler event="dragstart"><![CDATA[
-        var tab = this._getDragTargetTab(event);
+        var tab = this._getDragTargetTab(event, false);
         if (!tab || this._isCustomizing)
           return;
 
         let dt = event.dataTransfer;
         dt.mozSetDataAt(TAB_DROP_TYPE, tab, 0);
         let browser = tab.linkedBrowser;
 
         // We must not set text/x-moz-url or text/plain data here,
@@ -5551,17 +5549,17 @@
           scrollX: this.mTabstrip.scrollPosition,
           screenX: event.screenX
         };
 
         event.stopPropagation();
       ]]></handler>
 
       <handler event="dragover"><![CDATA[
-        var effects = this._setEffectAllowedForDataTransfer(event);
+        var effects = this._getDropEffectForTabDrag(event);
 
         var ind = this._tabDropIndicator;
         if (effects == "" || effects == "none") {
           ind.collapsed = true;
           return;
         }
         event.preventDefault();
         event.stopPropagation();
@@ -5592,17 +5590,17 @@
           ind.collapsed = true;
           this._animateTabMove(event);
           return;
         }
 
         this._finishAnimateTabMove();
 
         if (effects == "link") {
-          let tab = this._getDragTargetTab(event);
+          let tab = this._getDragTargetTab(event, true);
           if (tab) {
             if (!this._dragTime)
               this._dragTime = Date.now();
             if (Date.now() >= this._dragTime + this._dragOverDelay)
               this.selectedItem = tab;
             ind.collapsed = true;
             return;
           }
@@ -5618,17 +5616,17 @@
           let maxMargin = Math.min(minMargin + scrollRect.width,
                                    scrollRect.right);
           if (!ltr)
             [minMargin, maxMargin] = [this.clientWidth - maxMargin,
                                       this.clientWidth - minMargin];
           newMargin = (pixelsToScroll > 0) ? maxMargin : minMargin;
         }
         else {
-          let newIndex = this._getDropIndex(event);
+          let newIndex = this._getDropIndex(event, effects == "link");
           if (newIndex == this.childNodes.length) {
             let tabRect = this.childNodes[newIndex-1].getBoundingClientRect();
             if (ltr)
               newMargin = tabRect.right - rect.left;
             else
               newMargin = rect.right - tabRect.left;
           }
           else {
@@ -5649,28 +5647,28 @@
         ind.style.transform = "translate(" + Math.round(newMargin) + "px)";
         ind.style.MozMarginStart = (-ind.clientWidth) + "px";
       ]]></handler>
 
       <handler event="drop"><![CDATA[
         var dt = event.dataTransfer;
         var dropEffect = dt.dropEffect;
         var draggedTab;
-        if (dropEffect != "link") { // copy or move
+        if (dt.mozTypesAt(0)[0] == TAB_DROP_TYPE) { // tab copy or move
           draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
           // not our drop then
           if (!draggedTab)
             return;
         }
 
         this._tabDropIndicator.collapsed = true;
         event.stopPropagation();
         if (draggedTab && dropEffect == "copy") {
           // copy the dropped tab (wherever it's from)
-          let newIndex = this._getDropIndex(event);
+          let newIndex = this._getDropIndex(event, false);
           let newTab = this.tabbrowser.duplicateTab(draggedTab);
           this.tabbrowser.moveTabTo(newTab, newIndex);
           if (draggedTab.parentNode != this || event.shiftKey)
             this.selectedItem = newTab;
         } else if (draggedTab && draggedTab.parentNode == this) {
           this._finishAnimateTabMove();
 
           // actually move the dragged tab
@@ -5679,17 +5677,17 @@
             if (newIndex > draggedTab._tPos)
               newIndex--;
             this.tabbrowser.moveTabTo(draggedTab, newIndex);
           }
         } else if (draggedTab) {
           // swap the dropped tab with a new one we create and then close
           // it in the other window (making it seem to have moved between
           // windows)
-          let newIndex = this._getDropIndex(event);
+          let newIndex = this._getDropIndex(event, false);
           let newTab = this.tabbrowser.addTab("about:blank");
           let newBrowser = this.tabbrowser.getBrowserForTab(newTab);
           let draggedBrowserURL = draggedTab.linkedBrowser.currentURI.spec;
 
           // If we're an e10s browser window, an exception will be thrown
           // if we attempt to drag a non-remote browser in, so we need to
           // ensure that the remoteness of the newly created browser is
           // appropriate for the URL of the tab being dragged in.
@@ -5727,20 +5725,20 @@
           if (!url)
             return;
 
           let bgLoad = Services.prefs.getBoolPref("browser.tabs.loadInBackground");
 
           if (event.shiftKey)
             bgLoad = !bgLoad;
 
-          let tab = this._getDragTargetTab(event);
+          let tab = this._getDragTargetTab(event, true);
           if (!tab || dropEffect == "copy") {
             // We're adding a new tab.
-            let newIndex = this._getDropIndex(event);
+            let newIndex = this._getDropIndex(event, true);
             let newTab = this.tabbrowser.loadOneTab(url, {inBackground: bgLoad, allowThirdPartyFixup: true});
             this.tabbrowser.moveTabTo(newTab, newIndex);
           } else {
             // Load in an existing tab.
             try {
               let webNav = Ci.nsIWebNavigation;
               let flags = webNav.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
                           webNav.LOAD_FLAGS_FIXUP_SCHEME_TYPOS;