Bug 545119, use link drop service for tabbrowser dataTransfer for search engine dialog and remove browser dependency on nsDragAndDrop.js, r=gavin
authorNeil Deakin <neil@mozilla.com>
Wed, 26 May 2010 11:28:25 -0400
changeset 42827 13b292f9ab79d57850d903d42353440585450c34
parent 42826 aec47f551360cf881f348be5d513f29693a2d684
child 42836 cb0e5f6d0a1777ef3281fb2838670f4ab5188b08
push id13462
push userneil@mozilla.com
push dateWed, 26 May 2010 15:29:19 +0000
treeherdermozilla-central@13b292f9ab79 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgavin
bugs545119
milestone1.9.3a5pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
Bug 545119, use link drop service for tabbrowser dataTransfer for search engine dialog and remove browser dependency on nsDragAndDrop.js, r=gavin
browser/base/content/browser.js
browser/base/content/browser.xul
browser/base/content/tabbrowser.xml
browser/base/content/test/browser_drag.js
browser/components/search/content/engineManager.js
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2723,19 +2723,21 @@ function FillInHTMLTooltip(tipElement)
       retVal = true;
     }
   });
 
   return retVal;
 }
 
 var browserDragAndDrop = {
+  canDropLink: function (aEvent) Services.droppedLinkHandler.canDropLink(aEvent, true),
+
   dragOver: function (aEvent, statusString)
   {
-    if (Services.droppedLinkHandler.canDropLink(aEvent, true)) {
+    if (this.canDropLink(aEvent)) {
       aEvent.preventDefault();
 
       if (statusString) {
         var statusTextFld = document.getElementById("statusbar-display");
         statusTextFld.label = gNavigatorBundle.getString(statusString);
       }
     }
   },
@@ -2867,18 +2869,16 @@ var newWindowButtonObserver = {
     if (url) {
       // allow third-party services to fixup this URL
       openNewWindowWith(url, null, postData.value, true);
     }
   }
 }
 
 var DownloadsButtonDNDObserver = {
-  /////////////////////////////////////////////////////////////////////////////
-  // nsDragAndDrop
   onDragOver: function (aEvent)
   {
     var statusTextFld = document.getElementById("statusbar-display");
     statusTextFld.label = gNavigatorBundle.getString("dropondownloadsbutton");
     var types = aEvent.dataTransfer.types;
     if (types.contains("text/x-moz-url") ||
         types.contains("text/uri-list") ||
         types.contains("text/plain"))
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -97,20 +97,16 @@
 
 #ifdef MOZ_SAFE_BROWSING
 <script type="application/javascript" src="chrome://browser/content/safebrowsing/sb-loader.js"/>
 #endif
 <script type="application/javascript" src="chrome://global/content/contentAreaUtils.js"/>
 
 <script type="application/javascript" src="chrome://browser/content/places/editBookmarkOverlay.js"/>
 
-<!-- This is still used for dragDropSecurityCheck and transferUtils.  Since we
-     rely on the new Drag and Drop API these dependencies should be removed. -->
-<script type="application/javascript" src="chrome://global/content/nsDragAndDrop.js"/>
-
 # All sets except for popupsets (commands, keys, stringbundles and broadcasters) *must* go into the 
 # browser-sets.inc file for sharing with hiddenWindow.xul.
 #include browser-sets.inc
 
   <popupset id="mainPopupSet">
     <menupopup id="tabContextMenu"
                onpopupshowing="if (event.target == this) TabContextMenu.updateContextMenu(this);"
                onpopuphidden="if (event.target == this) TabContextMenu.contextTab = null;">
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -2147,27 +2147,16 @@
       <property name="contentPrincipal"
                 onget="return this.mCurrentBrowser.contentPrincipal;"
                 readonly="true"/>
 
       <property name="securityUI"
                 onget="return this.mCurrentBrowser.securityUI;"
                 readonly="true"/>
 
-      <method name="dragDropSecurityCheck">
-        <parameter name="aEvent"/>
-        <parameter name="aDragSession"/>
-        <parameter name="aUri"/>
-        <body>
-          <![CDATA[
-            nsDragAndDrop.dragDropSecurityCheck(aEvent, aDragSession, aUri);
-          ]]>
-        </body>
-      </method>
-
       <method name="_handleKeyEvent">
         <parameter name="aEvent"/>
         <body><![CDATA[
           if (!aEvent.isTrusted) {
             // Don't let untrusted events mess with tabs.
             return;
           }
 
@@ -2507,20 +2496,16 @@
 
       <field name="_tabDropIndicator">
         document.getAnonymousElementByAttribute(this, "anonid", "tab-drop-indicator");
       </field>
 
       <field name="_dragOverDelay">350</field>
       <field name="_dragTime">0</field>
 
-      <field name="_supportedLinkDropTypes"><![CDATA[
-        ["text/x-moz-url", "text/uri-list", "text/plain", "application/x-moz-file"]
-      ]]></field>
-
       <field name="_container" readonly="true"><![CDATA[
         this.parentNode && this.parentNode.localName == "toolbar" ? this.parentNode : this;
       ]]></field>
 
       <property name="visible"
                 onget="return !this._container.collapsed;">
         <setter><![CDATA[
           this._container.collapsed = !val;
@@ -2704,21 +2689,19 @@
                                        sourceNode.boxObject.width))) {
                 return dt.effectAllowed = "none";
               }
 
               return dt.effectAllowed = "copyMove";
             }
           }
 
-          for (let i = 0; i < this._supportedLinkDropTypes.length; i++) {
-            if (types.contains(this._supportedLinkDropTypes[i])) {
-              // Here we need to to do this manually
-              return dt.effectAllowed = dt.dropEffect = "link";
-            }
+          if (browserDragAndDrop.canDropLink(event)) {
+            // Here we need to do this manually
+            return dt.effectAllowed = dt.dropEffect = "link";
           }
           return dt.effectAllowed = "none";
         ]]></body>
       </method>
 
       <method name="_continueScroll">
         <parameter name="event"/>
         <body><![CDATA[
@@ -2956,44 +2939,24 @@
 
           this.tabbrowser.swapBrowsersAndCloseOther(newTab, draggedTab);
 
           // We need to select the tab after we've done
           // swapBrowsersAndCloseOther, so that the updateCurrentBrowser
           // it triggers will correctly update our URL bar.
           this.tabbrowser.selectedTab = newTab;
         } else {
-          let url;
-          for (let i = 0; i < this._supportedLinkDropTypes.length; i++) {
-            let dataType = this._supportedLinkDropTypes[i];
-            // uri-list: for now, support dropping of the first URL
-            // only
-            let isURLList = dataType == "text/uri-list";
-            let urlData = isURLList ?
-                          dt.mozGetDataAt("URL", 0) : dt.mozGetDataAt(dataType, 0);
-            if (urlData) {
-              url = transferUtils.retrieveURLFromData(urlData, isURLList ? "text/plain" : dataType);
-              break;
-            }
-          }
-          NS_ASSERT(url, "In the drop event, at least one mime-type should match our supported types");
+          let url = browserDragAndDrop.drop(event, { });
 
           // valid urls don't contain spaces ' '; if we have a space it isn't a valid url.
           // Also disallow dropping javascript: or data: urls--bail out
           if (!url || !url.length || url.indexOf(" ", 0) != -1 ||
               /^\s*(javascript|data):/.test(url))
             return;
 
-          // XXXmano: temporary fix until dragDropSecurityCheck make the
-          // drag-session an optional paramter
-          let dragService = Cc["@mozilla.org/widget/dragservice;1"].
-                            getService(Ci.nsIDragService);
-          let dragSession = dragService.getCurrentSession();
-          nsDragAndDrop.dragDropSecurityCheck(event, dragSession, url);
-
           let bgLoad = Services.prefs.getBoolPref("browser.tabs.loadInBackground");
 
           if (event.shiftKey)
             bgLoad = !bgLoad;
 
           let tab = this._getDragTargetTab(event);
           if (!tab || dropEffect == "copy") {
             // We're adding a new tab.
--- a/browser/base/content/test/browser_drag.js
+++ b/browser/base/content/test/browser_drag.js
@@ -1,10 +1,12 @@
 function test()
 {
+  waitForExplicitFinish();
+
   // ---- Test dragging the proxy icon ---
   var value = content.location.href;
   var urlString = value + "\n" + content.document.title;
   var htmlString = "<a href=\"" + value + "\">" + value + "</a>";
   var expected = [ [
     { type  : "text/x-moz-url",
       data  : urlString },
     { type  : "text/uri-list",
@@ -19,9 +21,27 @@ function test()
   var oldstate = proxyicon.getAttribute("pageproxystate");
   proxyicon.setAttribute("pageproxystate", "valid");
   var dt = EventUtils.synthesizeDragStart(proxyicon, expected);
   is(dt, null, "drag on proxy icon");
   proxyicon.setAttribute("pageproxystate", oldstate);
   // Now, the identity information panel is opened by the proxy icon click.
   // We need to close it for next tests.
   EventUtils.synthesizeKey("VK_ESCAPE", {}, window);
+
+  // now test dragging onto a tab
+  var tab1 = gBrowser.addTab();
+  var browser1 = gBrowser.getBrowserForTab(tab1);
+
+  var tab2 = gBrowser.addTab();
+  var browser2 = gBrowser.getBrowserForTab(tab2);
+
+  gBrowser.selectedTab = tab1;
+
+  browser2.addEventListener("load", function () {
+    is(browser2.contentWindow.location, "http://mochi.test:8888/", "drop on tab");
+    gBrowser.removeCurrentTab();
+    gBrowser.removeCurrentTab();
+    finish();
+  }, true);
+
+  EventUtils.synthesizeDrop(tab2, [[{type: "text/uri-list", data: "http://mochi.test:8888/"}]], "copy", window);
 }
--- a/browser/components/search/content/engineManager.js
+++ b/browser/components/search/content/engineManager.js
@@ -460,39 +460,18 @@ EngineView.prototype = {
   invalidate: function () {
     this.tree.invalidate();
   },
 
   ensureRowIsVisible: function (index) {
     this.tree.ensureRowIsVisible(index);
   },
 
-  getSourceIndexFromDrag: function () {
-    var dragService = Cc["@mozilla.org/widget/dragservice;1"].
-                      getService().QueryInterface(Ci.nsIDragService);
-    var dragSession = dragService.getCurrentSession();
-    var transfer = Cc["@mozilla.org/widget/transferable;1"].
-                   createInstance(Ci.nsITransferable);
-
-    transfer.addDataFlavor(ENGINE_FLAVOR);
-    dragSession.getData(transfer, 0);
-
-    var dataObj = {};
-    var len = {};
-    var sourceIndex = -1;
-    try {
-      transfer.getAnyTransferData({}, dataObj, len);
-    } catch (ex) {}
-
-    if (dataObj.value) {
-      sourceIndex = dataObj.value.QueryInterface(Ci.nsISupportsString).data;
-      sourceIndex = parseInt(sourceIndex.substring(0, len.value));
-    }
-
-    return sourceIndex;
+  getSourceIndexFromDrag: function (dataTransfer) {
+    return parseInt(dataTransfer.getData(ENGINE_FLAVOR));
   },
 
   // nsITreeView
   get rowCount() {
     return this._engineStore.engines.length;
   },
 
   getImageSrc: function(index, column) {
@@ -508,25 +487,25 @@ EngineView.prototype = {
       return this._engineStore.engines[index].alias;
     return "";
   },
 
   setTree: function(tree) {
     this.tree = tree;
   },
 
-  canDrop: function(targetIndex, orientation) {
-    var sourceIndex = this.getSourceIndexFromDrag();
+  canDrop: function(targetIndex, orientation, dataTransfer) {
+    var sourceIndex = this.getSourceIndexFromDrag(dataTransfer);
     return (sourceIndex != -1 &&
             sourceIndex != targetIndex &&
             sourceIndex != (targetIndex + orientation));
   },
 
-  drop: function(dropIndex, orientation) {
-    var sourceIndex = this.getSourceIndexFromDrag();
+  drop: function(dropIndex, orientation, dataTransfer) {
+    var sourceIndex = this.getSourceIndexFromDrag(dataTransfer);
     var sourceEngine = this._engineStore.engines[sourceIndex];
 
     if (dropIndex > sourceIndex) {
       if (orientation == Ci.nsITreeView.DROP_BEFORE)
         dropIndex--;
     } else {
       if (orientation == Ci.nsITreeView.DROP_AFTER)
         dropIndex++;