Bug 1269713 - Use DataTransfer to transfer addresses between address books. r=aceman a=jorgk for SM CLOSED TREE a=jorgk(Aurora)
authorJorg K
Wed, 04 May 2016 20:11:24 +0200
changeset 27171 d27e0d778376e4d117c869124df897a838b007e5
parent 27170 b9e78456cca7585fa9e610e695c827fc4a4e72cd
child 27172 22ffea29a85d33082ff1dee3e7ba35b9a66968ec
push id1850
push userclokep@gmail.com
push dateWed, 08 Mar 2017 19:29:12 +0000
treeherdercomm-esr52@028df196b2d9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaceman, jorgk, jorgk
bugs1269713
Bug 1269713 - Use DataTransfer to transfer addresses between address books. r=aceman a=jorgk for SM CLOSED TREE a=jorgk(Aurora)
mail/components/addrbook/content/abTrees.js
mailnews/addrbook/content/abDragDrop.js
suite/mailnews/addrbook/abTrees.js
--- a/mail/components/addrbook/content/abTrees.js
+++ b/mail/components/addrbook/content/abTrees.js
@@ -165,22 +165,22 @@ directoryTreeView.prototype = {
     if (aJSONFile) {
       // Write out our json file...
       let data = JSON.stringify(this._persistOpenMap);
       IOUtils.saveStringToFile(aJSONFile, data);
     }
   },
 
   // Override the dnd methods for those functions in abDragDrop.js
-  canDrop: function dtv_canDrop(aIndex, aOrientation) {
-    return abDirTreeObserver.canDrop(aIndex, aOrientation);
+  canDrop: function dtv_canDrop(aIndex, aOrientation, dataTransfer) {
+    return abDirTreeObserver.canDrop(aIndex, aOrientation, dataTransfer);
   },
 
-  drop: function dtv_drop(aRow, aOrientation) {
-    abDirTreeObserver.onDrop(aRow, aOrientation);
+  drop: function dtv_drop(aRow, aOrientation, dataTransfer) {
+    abDirTreeObserver.onDrop(aRow, aOrientation, dataTransfer);
   },
 
   getDirectoryAtIndex: function dtv_getDirForIndex(aIndex) {
     return this._rowMap[aIndex]._directory;
   },
 
   // Override jsTreeView's isContainer, since we want to be able
   // to react to drag-drop events for all items in the directory
--- a/mailnews/addrbook/content/abDragDrop.js
+++ b/mailnews/addrbook/content/abDragDrop.js
@@ -123,20 +123,23 @@ var abDirTreeObserver = {
    *   (cards currently have to exist outside list for list to work correctly)
    *   mailing list      -> different address book = MOVE only
    *   (lists currently need to have unique names)
    *   card in mailing list -> parent mailing list = Not allowed
    *   card in mailing list -> other mailing list  = MOVE or COPY
    *   card in mailing list -> other address book  = MOVE or COPY
    *   read only directory item -> anywhere        = COPY only
    */
-  canDrop: function(index, orientation)
+  canDrop: function(index, orientation, dataTransfer)
   {
     if (orientation != Components.interfaces.nsITreeView.DROP_ON)
       return false;
+    if (!dataTransfer.types.contains("moz/abcard")) {
+      return false;
+    }
 
     var targetURI = gDirectoryTreeView.getDirectoryAtIndex(index).URI;
 
     var srcURI = GetSelectedDirectory();
 
     // We cannot allow copy/move to "All Address Books".
     if (targetURI == kAllDirectoryRoot + "?")
       return false;
@@ -179,48 +182,26 @@ var abDirTreeObserver = {
                                   nsIDragService.DRAGDROP_ACTION_COPY)
       return false;
 
     // Go through the cards checking to see if one of them is a mailing list
     // (if we are attempting a copy) - we can't copy mailing lists as
     // that would give us duplicate names which isn't allowed at the
     // moment.
     var draggingMailList = false;
-    var trans = Components.classes["@mozilla.org/widget/transferable;1"].
-                createInstance(Components.interfaces.nsITransferable);
-    trans.init(getLoadContext());
-    trans.addDataFlavor("moz/abcard");
 
-    for (var i = 0; i < dragSession.numDropItems && !draggingMailList; i++)
-    {
-      dragSession.getData(trans, i);
+    // The data contains the a string of "selected rows", eg.: "1,2".
+    var rows = dataTransfer.getData("moz/abcard").split(",").map(j => parseInt(j, 10));
 
-      var dataObj = new Object();
-      var flavor = new Object();
-      var len = new Object();
-      try {
-        trans.getAnyTransferData(flavor, dataObj, len);
-      }
-      catch (ex) {
-        dragSession.canDrop = false;
-        return false;
-      }
-
-      dataObj = dataObj.value.QueryInterface(Components.interfaces.nsISupportsString);
-
-      var transData = dataObj.data.split("\n");
-      var rows = transData[0].split(",");
-
-      for (var j = 0; j < rows.length; j++)
+    for (var j = 0; j < rows.length; j++)
+    {
+      if (gAbView.getCardFromRow(rows[j]).isMailList)
       {
-        if (gAbView.getCardFromRow(rows[j]).isMailList)
-        {
-          draggingMailList = true;
-          break;
-        }
+        draggingMailList = true;
+        break;
       }
     }
 
     // The rest of the cases - allow cards for copy or move, but only allow
     // move of mailing lists if we're not going into another mailing list.
     if (draggingMailList &&
         (targetDirectory.isMailList ||
          dragSession.dragAction == Components.interfaces.
@@ -233,134 +214,118 @@ var abDirTreeObserver = {
     return true;
   },
 
   /**
    * onDrop - we don't need to check again for correctness as the
    * tree view calls canDrop just before calling onDrop.
    *
    */
-  onDrop: function(index, orientation)
+  onDrop: function(index, orientation, dataTransfer)
   {
     var dragSession = dragService.getCurrentSession();
     if (!dragSession)
       return;
-
-    var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
-    trans.init(getLoadContext());
-    trans.addDataFlavor("moz/abcard");
+    if (!dataTransfer.types.contains("moz/abcard")) {
+      return;
+    }
 
     var targetURI = gDirectoryTreeView.getDirectoryAtIndex(index).URI;
     var srcURI = GetSelectedDirectory();
 
-    for (var i = 0; i < dragSession.numDropItems; i++) {
-      dragSession.getData(trans, i);
-      var dataObj = new Object();
-      var flavor = new Object();
-      var len = new Object();
-      try {
-        trans.getAnyTransferData(flavor, dataObj, len);
-        dataObj =
-          dataObj.value.QueryInterface(Components.interfaces.nsISupportsString);
+    // The data contains the a string of "selected rows", eg.: "1,2".
+    var rows = dataTransfer.getData("moz/abcard").split(",").map(j => parseInt(j, 10));
+    var numrows = rows.length;
+
+    var result;
+    // needToCopyCard is used for whether or not we should be creating
+    // copies of the cards in a mailing list in a different address book
+    // - it's not for if we are moving or not.
+    var needToCopyCard = true;
+    if (srcURI.length > targetURI.length) {
+      result = srcURI.split(targetURI);
+      if (result[0] != srcURI) {
+        // src directory is a mailing list on target directory, no need to copy card
+        needToCopyCard = false;
       }
-      catch (ex) {
-        continue;
+    }
+    else {
+      result = targetURI.split(srcURI);
+      if (result[0] != targetURI) {
+        // target directory is a mailing list on src directory, no need to copy card
+        needToCopyCard = false;
       }
-
-      var transData = dataObj.data.split("\n");
-      var rows = transData[0].split(",").map(j => parseInt(j, 10));
-      var numrows = rows.length;
+    }
 
-      var result;
-      // needToCopyCard is used for whether or not we should be creating
-      // copies of the cards in a mailing list in a different address book
-      // - it's not for if we are moving or not.
-      var needToCopyCard = true;
-      if (srcURI.length > targetURI.length) {
-        result = srcURI.split(targetURI);
-        if (result[0] != srcURI) {
-          // src directory is a mailing list on target directory, no need to copy card
-          needToCopyCard = false;
+    // if we still think we have to copy the card,
+    // check if srcURI and targetURI are mailing lists on same directory
+    // if so, we don't have to copy the card
+    if (needToCopyCard) {
+      var targetParentURI = GetParentDirectoryFromMailingListURI(targetURI);
+      if (targetParentURI && (targetParentURI == GetParentDirectoryFromMailingListURI(srcURI)))
+        needToCopyCard = false;
+    }
+
+    var directory = GetDirectoryFromURI(targetURI);
+
+    // Only move if we are not transferring to a mail list
+    var actionIsMoving = (dragSession.dragAction & dragSession.DRAGDROP_ACTION_MOVE) && !directory.isMailList;
+
+    let cardsToCopy = [];
+    for (let j = 0; j < numrows; j++) {
+      cardsToCopy.push(gAbView.getCardFromRow(rows[j]));
+    }
+    for (let card of cardsToCopy) {
+      if (card.isMailList) {
+        // This check ensures we haven't slipped through by mistake
+        if (needToCopyCard && actionIsMoving) {
+          directory.addMailList(GetDirectoryFromURI(card.mailListURI));
         }
-      }
-      else {
-        result = targetURI.split(srcURI);
-        if (result[0] != targetURI) {
-          // target directory is a mailing list on src directory, no need to copy card
-          needToCopyCard = false;
+      } else {
+        let srcDirectory = null;
+        if (srcURI == (kAllDirectoryRoot + "?") && actionIsMoving) {
+          let dirId = card.directoryId.substring(0, card.directoryId.indexOf("&"));
+          srcDirectory = MailServices.ab.getDirectoryFromId(dirId);
+        }
+
+        directory.dropCard(card, needToCopyCard);
+
+        // This is true only if srcURI is "All ABs" and action is moving.
+        if (srcDirectory) {
+          let cardArray =
+            Components.classes["@mozilla.org/array;1"]
+                      .createInstance(Components.interfaces.nsIMutableArray);
+          cardArray.appendElement(card, false);
+          srcDirectory.deleteCards(cardArray);
         }
       }
+    }
 
-      // if we still think we have to copy the card,
-      // check if srcURI and targetURI are mailing lists on same directory
-      // if so, we don't have to copy the card
-      if (needToCopyCard) {
-        var targetParentURI = GetParentDirectoryFromMailingListURI(targetURI);
-        if (targetParentURI && (targetParentURI == GetParentDirectoryFromMailingListURI(srcURI)))
-          needToCopyCard = false;
-      }
-
-      var directory = GetDirectoryFromURI(targetURI);
-
-      // Only move if we are not transferring to a mail list
-      var actionIsMoving = (dragSession.dragAction & dragSession.DRAGDROP_ACTION_MOVE) && !directory.isMailList;
+    var cardsTransferredText;
 
-      let cardsToCopy = [];
-      for (let j = 0; j < numrows; j++) {
-        cardsToCopy.push(gAbView.getCardFromRow(rows[j]));
-      }
-      for (let card of cardsToCopy) {
-        if (card.isMailList) {
-          // This check ensures we haven't slipped through by mistake
-          if (needToCopyCard && actionIsMoving) {
-            directory.addMailList(GetDirectoryFromURI(card.mailListURI));
-          }
-        } else {
-          let srcDirectory = null;
-          if (srcURI == (kAllDirectoryRoot + "?") && actionIsMoving) {
-            let dirId = card.directoryId.substring(0, card.directoryId.indexOf("&"));
-            srcDirectory = MailServices.ab.getDirectoryFromId(dirId);
-          }
-
-          directory.dropCard(card, needToCopyCard);
+    // If we are moving, but not moving to a directory, then delete the
+    // selected cards and display the appropriate text
+    if (actionIsMoving && srcURI != (kAllDirectoryRoot + "?")) {
+      // If we have moved the cards, then delete them as well.
+      gAbView.deleteSelectedCards();
+    }
 
-          // This is true only if srcURI is "All ABs" and action is moving.
-          if (srcDirectory) {
-            let cardArray =
-              Components.classes["@mozilla.org/array;1"]
-                        .createInstance(Components.interfaces.nsIMutableArray);
-            cardArray.appendElement(card, false);
-            srcDirectory.deleteCards(cardArray);
-          }
-        }
-      }
-
-      var cardsTransferredText;
+    if (actionIsMoving) {
+      cardsTransferredText = PluralForm.get(numrows,
+        gAddressBookBundle.getFormattedString("contactsMoved", [numrows]));
+    } else {
+      cardsTransferredText = PluralForm.get(numrows,
+        gAddressBookBundle.getFormattedString("contactsCopied", [numrows]));
+    }
 
-      // If we are moving, but not moving to a directory, then delete the
-      // selected cards and display the appropriate text
-      if (actionIsMoving && srcURI != (kAllDirectoryRoot + "?")) {
-        // If we have moved the cards, then delete them as well.
-        gAbView.deleteSelectedCards();
-      }
+    if (srcURI == kAllDirectoryRoot + "?") {
+      SetAbView(srcURI);
+    }
 
-      if (actionIsMoving) {
-        cardsTransferredText = PluralForm.get(numrows,
-          gAddressBookBundle.getFormattedString("contactsMoved", [numrows]));
-      } else {
-        cardsTransferredText = PluralForm.get(numrows,
-          gAddressBookBundle.getFormattedString("contactsCopied", [numrows]));
-      }
-
-      if (srcURI == kAllDirectoryRoot + "?") {
-        SetAbView(srcURI);
-      }
-
-      document.getElementById("statusText").label = cardsTransferredText;
-    }
+    document.getElementById("statusText").label = cardsTransferredText;
   },
 
   onToggleOpenState: function()
   {
   },
 
   onCycleHeader: function(colID, elt)
   {
--- a/suite/mailnews/addrbook/abTrees.js
+++ b/suite/mailnews/addrbook/abTrees.js
@@ -109,24 +109,24 @@ directoryTreeView.prototype =
     {
       // Write out our json file...
       let data = JSON.stringify(this._persistOpenMap);
       IOUtils.saveStringToFile(aJSONFile, data);
     }
   },
 
   // Override the dnd methods for those functions in abDragDrop.js
-  canDrop: function dtv_canDrop(aIndex, aOrientation)
+  canDrop: function dtv_canDrop(aIndex, aOrientation, dataTransfer)
   {
-    return abDirTreeObserver.canDrop(aIndex, aOrientation);
+    return abDirTreeObserver.canDrop(aIndex, aOrientation, dataTransfer);
   },
 
-  drop: function dtv_drop(aRow, aOrientation)
+  drop: function dtv_drop(aRow, aOrientation, dataTransfer)
   {
-    abDirTreeObserver.onDrop(aRow, aOrientation);
+    abDirTreeObserver.onDrop(aRow, aOrientation, dataTransfer);
   },
 
   getDirectoryAtIndex: function dtv_getDirForIndex(aIndex)
   {
     return this._rowMap[aIndex]._directory;
   },
 
   getIndexOfDirectory: function dtv_getIndexOfDir(aItem)