summaryrefslogtreecommitdiffstats
path: root/toolkit/mozapps/extensions/content/drag-drop-addon-installer.js
blob: 0a4f3f749c4b31ba56f07fae6501efb79d68d39c (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
/* 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 aboutaddonsCommon.js */

"use strict";

class DragDropAddonInstaller extends HTMLElement {
  connectedCallback() {
    window.addEventListener("drop", this);
  }

  disconnectedCallback() {
    window.removeEventListener("drop", this);
  }

  canInstallFromEvent(e) {
    let types = e.dataTransfer.types;
    return (
      types.includes("text/uri-list") ||
      types.includes("text/x-moz-url") ||
      types.includes("application/x-moz-file")
    );
  }

  handleEvent(e) {
    if (!XPINSTALL_ENABLED) {
      // Nothing to do if we can't install add-ons.
      return;
    }

    if (e.type == "drop" && this.canInstallFromEvent(e)) {
      this.onDrop(e);
    }
  }

  async onDrop(e) {
    e.preventDefault();

    let dataTransfer = e.dataTransfer;
    let browser = getBrowserElement();
    let urls = [];

    // Convert every dropped item into a url, without this should be sync.
    for (let i = 0; i < dataTransfer.mozItemCount; i++) {
      let url = dataTransfer.mozGetDataAt("text/uri-list", i);
      if (!url) {
        url = dataTransfer.mozGetDataAt("text/x-moz-url", i);
      }
      if (url) {
        url = url.split("\n")[0];
      } else {
        let file = dataTransfer.mozGetDataAt("application/x-moz-file", i);
        if (file) {
          url = Services.io.newFileURI(file).spec;
        }
      }

      if (url) {
        urls.push(url);
      }
    }

    // Install the add-ons, the await clears the event data so we do this last.
    for (let url of urls) {
      let install = await AddonManager.getInstallForURL(url, {
        telemetryInfo: {
          source: "about:addons",
          method: "drag-and-drop",
        },
      });

      AddonManager.installAddonFromAOM(
        browser,
        document.documentURIObject,
        install
      );
    }
  }
}
customElements.define("drag-drop-addon-installer", DragDropAddonInstaller);