summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/addrbook/content/abDragDrop.js
blob: 56cbee0e085c87f100fc576037b71fb841a533a9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/* import-globals-from abResultsPane.js */

// Returns the load context for the current window
function getLoadContext() {
  return window.docShell.QueryInterface(Ci.nsILoadContext);
}

var abFlavorDataProvider = {
  QueryInterface: ChromeUtils.generateQI(["nsIFlavorDataProvider"]),

  getFlavorData(aTransferable, aFlavor, aData) {
    if (aFlavor == "application/x-moz-file-promise") {
      var primitive = {};
      aTransferable.getTransferData("text/vcard", primitive);
      var vCard = primitive.value.QueryInterface(Ci.nsISupportsString).data;
      aTransferable.getTransferData(
        "application/x-moz-file-promise-dest-filename",
        primitive
      );
      var leafName = primitive.value.QueryInterface(Ci.nsISupportsString).data;
      aTransferable.getTransferData(
        "application/x-moz-file-promise-dir",
        primitive
      );
      var localFile = primitive.value.QueryInterface(Ci.nsIFile).clone();
      localFile.append(leafName);

      var ofStream = Cc[
        "@mozilla.org/network/file-output-stream;1"
      ].createInstance(Ci.nsIFileOutputStream);
      ofStream.init(localFile, -1, -1, 0);
      var converter = Cc[
        "@mozilla.org/intl/converter-output-stream;1"
      ].createInstance(Ci.nsIConverterOutputStream);
      converter.init(ofStream, null);
      converter.writeString(vCard);
      converter.close();

      aData.value = localFile;
    }
  },
};

let abResultsPaneObserver = {
  onDragStart(event) {
    let selectedRows = GetSelectedRows();

    if (!selectedRows) {
      return;
    }

    let selectedAddresses = GetSelectedAddresses();

    event.dataTransfer.setData("moz/abcard", selectedRows);
    event.dataTransfer.setData("moz/abcard", selectedRows);
    event.dataTransfer.setData("text/x-moz-address", selectedAddresses);
    event.dataTransfer.setData("text/plain", selectedAddresses);

    let card = GetSelectedCard();
    if (card && card.displayName && !card.isMailList) {
      try {
        // A card implementation may throw NS_ERROR_NOT_IMPLEMENTED.
        // Don't break drag-and-drop if that happens.
        let vCard = card.translateTo("vcard");
        event.dataTransfer.setData("text/vcard", decodeURIComponent(vCard));
        event.dataTransfer.setData(
          "application/x-moz-file-promise-dest-filename",
          `${card.displayName}.vcf`.replace(/(.{74}).*(.{10})$/u, "$1...$2")
        );
        event.dataTransfer.setData(
          "application/x-moz-file-promise-url",
          "data:text/vcard," + vCard
        );
        event.dataTransfer.setData(
          "application/x-moz-file-promise",
          abFlavorDataProvider
        );
      } catch (ex) {
        console.error(ex);
      }
    }

    event.dataTransfer.effectAllowed = "copyMove";
    // a drag targeted at a tree should instead use the treechildren so that
    // the current selection is used as the drag feedback
    event.dataTransfer.addElement(event.target);
    event.stopPropagation();
  },
};

function DragAddressOverTargetControl(event) {
  var dragSession = Cc["@mozilla.org/widget/dragservice;1"]
    .getService(Ci.nsIDragService)
    .getCurrentSession();

  if (!dragSession.isDataFlavorSupported("text/x-moz-address")) {
    return;
  }

  var trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(
    Ci.nsITransferable
  );
  trans.init(getLoadContext());
  trans.addDataFlavor("text/x-moz-address");

  var canDrop = true;

  for (var i = 0; i < dragSession.numDropItems; ++i) {
    dragSession.getData(trans, i);
    var dataObj = {};
    var bestFlavor = {};
    try {
      trans.getAnyTransferData(bestFlavor, dataObj);
    } catch (ex) {
      canDrop = false;
      break;
    }
  }
  dragSession.canDrop = canDrop;
}