about summary refs log tree commit diff
path: root/background.js
blob: c1be6e4ff378de3d8289f238716ae049fca53160 (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
const PROTOCOL_VERSION = 0

const port = browser.runtime.connectNative("hidit")

port.onDisconnect.addListener(port => {
  if (port.error) {
    // TODO(V): Write a more precise error message
    console.error(`Disconnected due to an error: ${port.error.message}`)
    // TODO(V): Do we want to restart the application here? Do we want to kill the extension?
  }
})

function checkVersion(version) {
  if (version !== PROTOCOL_VERSION) {
    console.error(`Native application protocol has an incompatible version! Wanted ${PROTOCOL_VERSION}, got ${version}`)
    // TODO(V): Fatal error. Ideally we would repeat this process once a second or so, and display
    // an error icon in the toolbar to alert the user, along with some information on how to solve it.
  }

  port.onMessage.removeListener(checkVersion)
  port.onMessage.addListener(([command, args]) => {
    switch (command) {
      case "console:log": console.log(...args); break
      case "console:error": console.error(...args); break
      default: throw new Error(`Unknown command ${command}`)
    }
  })

  browser.windows.onCreated.addListener(window => {
    port.postMessage(["window:create", window])
  })

  browser.windows.onFocusChanged.addListener(windowId => {
    port.postMessage(["window:focus", windowId])
  })

  browser.windows.onRemoved.addListener(windowId => {
    port.postMessage(["window:destroy", windowId])
  })

  browser.windows.getAll().then(windows => {
    port.postMessage(["init:windows", windows])
  })

  browser.tabs.onActivated.addListener(({ windowId, tabId, previousTabId }) => {
    port.postMessage(["tab:activate", [windowId, tabId, previousTabId]])
  })

  browser.tabs.onAttached.addListener((tabId, { newWindowId, newPosition }) => {
    port.postMessage(["tab:attach", [tabId, newWindowId, newPosition]])
  })

  browser.tabs.onCreated.addListener(tab => {
    port.postMessage(["tab:create", tab])
  })

  browser.tabs.onDetached.addListener((tabId, { oldWindowId, oldPosition }) => {
    port.postMessage(["tab:detach", [tabId, oldWindowId, oldPosition]])
  })

  browser.tabs.onHighlighted.addListener(({ windowId, tabIds }) => {
    port.postMessage(["tab:select", [windowId, tabIds]])
  })

  browser.tabs.onMoved.addListener((tabId, info) => {
    port.postMessage(["tab:move", [tabId, info]])
  })

  browser.tabs.onRemoved.addListener((tabId, { windowId, isWindowClosing }) => {
    port.postMessage(["tab:destroy", [tabId, windowID, isWindowClosing]])
  })

  // Note: MDN has the following to say:
  // "This event may not be relevant for or supported by browsers other than Chrome."
  browser.tabs.onReplaced.addListener((newTabId, oldTabId) => {
    port.postMessage(["tab:replace", [oldTabId, newTabId]])
  })

  // TODO(V): Remove the tab parameter, it shouldn't be necessary if we're doing deltas properly
  browser.tabs.onUpdated.addListener((tabId, info, tab) => {
    port.postMessage(["tab:update", [tabId, info, tab]])
  })

  browser.tabs.onZoomChange.addListener(info => {
    port.postMessage(["tab:zoom", info])
  })

  browser.tabs.query({}).then(tabs => {
    port.postMessage(["init:tabs", tabs])
  })

  browser.contextualIdentities.onCreated.addListener(({ contextualIdentity }) => {
    port.postMessage(["context:create", contextualIdentity])
  })

  browser.contextualIdentities.onRemoved.addListener(({ contextualIdentity }) => {
    port.postMessage(["context:destroy", contextualIdentity])
  })

  browser.contextualIdentities.onUpdated.addListener(({ contextualIdentity }) => {
    port.postMessage(["context:update", contextualIdentity])
  })

  browser.contextualIdentities.query({}).then(contexts => {
    port.postMessage(["init:contexts", contexts])
    // TODO(V): either send over the files in resource://usercontext-content/ or vendor them
  })
}
port.onMessage.addListener(checkVersion)
port.postMessage(PROTOCOL_VERSION)