summaryrefslogtreecommitdiffstats
path: root/mobile/android/components/extensions/ext-browserAction.js
blob: 7cfffb24b0039764c61c1c7d919e65c35b6b5d02 (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
125
126
127
128
129
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";

// The ext-* files are imported into the same scopes.
/* import-globals-from ext-android.js */

XPCOMUtils.defineLazyModuleGetters(this, {
  GeckoViewWebExtension: "resource://gre/modules/GeckoViewWebExtension.jsm",
  ExtensionActionHelper: "resource://gre/modules/GeckoViewWebExtension.jsm",
});

const { BrowserActionBase } = ChromeUtils.import(
  "resource://gre/modules/ExtensionActions.jsm"
);

const BROWSER_ACTION_PROPERTIES = [
  "title",
  "icon",
  "popup",
  "badgeText",
  "badgeBackgroundColor",
  "badgeTextColor",
  "enabled",
  "patternMatching",
];

class BrowserAction extends BrowserActionBase {
  constructor(extension, clickDelegate) {
    const tabContext = new TabContext(tabId => this.getContextData(null));
    super(tabContext, extension);
    this.clickDelegate = clickDelegate;
    this.helper = new ExtensionActionHelper({
      extension,
      tabTracker,
      windowTracker,
      tabContext,
      properties: BROWSER_ACTION_PROPERTIES,
    });
  }

  updateOnChange(tab) {
    const tabId = tab ? tab.id : null;
    const action = tab
      ? this.getContextData(tab)
      : this.helper.extractProperties(this.globals);
    this.helper.sendRequest(tabId, {
      action,
      type: "GeckoView:BrowserAction:Update",
    });
  }

  openPopup() {
    const tab = tabTracker.activeTab;
    const actionObject = this.getContextData(tab);
    const action = this.helper.extractProperties(actionObject);
    this.helper.sendRequest(tab.id, {
      action,
      type: "GeckoView:BrowserAction:OpenPopup",
    });
  }

  getTab(tabId) {
    return this.helper.getTab(tabId);
  }

  getWindow(windowId) {
    return this.helper.getWindow(windowId);
  }

  click() {
    this.clickDelegate.onClick();
  }
}

this.browserAction = class extends ExtensionAPI {
  async onManifestEntry(entryName) {
    const { extension } = this;
    this.action = new BrowserAction(extension, this);
    await this.action.loadIconData();

    GeckoViewWebExtension.browserActions.set(extension, this.action);

    // Notify the embedder of this action
    this.action.updateOnChange(null);
  }

  onShutdown() {
    const { extension } = this;
    this.action.onShutdown();
    GeckoViewWebExtension.browserActions.delete(extension);
  }

  onClick() {
    this.emit("click", tabTracker.activeTab);
  }

  getAPI(context) {
    const { extension } = context;
    const { tabManager } = extension;
    const { action } = this;

    return {
      browserAction: {
        ...action.api(context),

        onClicked: new EventManager({
          context,
          name: "browserAction.onClicked",
          register: fire => {
            const listener = (event, tab) => {
              fire.async(tabManager.convert(tab));
            };
            this.on("click", listener);
            return () => {
              this.off("click", listener);
            };
          },
        }).api(),

        openPopup: function() {
          action.openPopup();
        },
      },
    };
  }
};

global.browserActionFor = this.browserAction.for;