summaryrefslogtreecommitdiffstats
path: root/mobile/android/modules/geckoview/GeckoViewClipboardPermission.sys.mjs
blob: 2c8e55c3805b61351091e8f290be3cc8051bf36d (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
/* 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/. */

const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
  PromptUtils: "resource://gre/modules/PromptUtils.sys.mjs",
});

import { GeckoViewUtils } from "resource://gre/modules/GeckoViewUtils.sys.mjs";

const { debug } = GeckoViewUtils.initLogging("GeckoViewClipboardPermission");

export var GeckoViewClipboardPermission = {
  confirmUserPaste(aWindowContext) {
    return new Promise((resolve, reject) => {
      if (!aWindowContext) {
        reject(
          Components.Exception("Null window context.", Cr.NS_ERROR_INVALID_ARG)
        );
        return;
      }

      const { document } = aWindowContext.browsingContext.topChromeWindow;
      if (!document) {
        reject(
          Components.Exception(
            "Unable to get chrome document.",
            Cr.NS_ERROR_FAILURE
          )
        );
        return;
      }

      if (this._pendingRequest) {
        reject(
          Components.Exception(
            "There is an ongoing request.",
            Cr.NS_ERROR_FAILURE
          )
        );
        return;
      }

      this._pendingRequest = { resolve, reject };

      const mouseXInCSSPixels = {};
      const mouseYInCSSPixels = {};
      const windowUtils = document.ownerGlobal.windowUtils;
      windowUtils.getLastOverWindowPointerLocationInCSSPixels(
        mouseXInCSSPixels,
        mouseYInCSSPixels
      );
      const screenRect = windowUtils.toScreenRect(
        mouseXInCSSPixels.value,
        mouseYInCSSPixels.value,
        0,
        0
      );

      debug`confirmUserPaste (${screenRect.x}, ${screenRect.y})`;

      document.addEventListener("pointerdown", this);
      document.ownerGlobal.WindowEventDispatcher.sendRequestForResult({
        type: "GeckoView:ClipboardPermissionRequest",
        screenPoint: {
          x: screenRect.x,
          y: screenRect.y,
        },
      }).then(
        allowOrDeny => {
          const propBag = lazy.PromptUtils.objectToPropBag({ ok: allowOrDeny });
          this._pendingRequest.resolve(propBag);
          this._pendingRequest = null;
          document.removeEventListener("pointerdown", this);
        },
        error => {
          debug`Permission error: ${error}`;
          this._pendingRequest.reject();
          this._pendingRequest = null;
          document.removeEventListener("pointerdown", this);
        }
      );
    });
  },

  // EventListener interface.
  handleEvent(aEvent) {
    debug`handleEvent: ${aEvent.type}`;
    switch (aEvent.type) {
      case "pointerdown": {
        aEvent.target.ownerGlobal.WindowEventDispatcher.sendRequestForResult({
          type: "GeckoView:DismissClipboardPermissionRequest",
        });
        break;
      }
    }
  },
};