webext-active-tab 0.0.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,4 @@
1
+ import { StorageItemMap } from 'webext-storage';
1
2
  type TabId = number;
2
3
  type Origin = string;
3
4
  export type ActiveTab = {
@@ -7,7 +8,7 @@ export type ActiveTab = {
7
8
  /**
8
9
  * The list is not guaranteed to be up to date. The activeTab permission might be lost before it's detected.
9
10
  */
10
- export declare const possiblyActiveTabs: Map<number, string>;
11
+ export declare const possiblyActiveTabs: StorageItemMap<string, string | undefined> | Map<string, string>;
11
12
  declare function startActiveTabTracking(): void;
12
13
  declare function stopActiveTabTracking(): void;
13
14
  export declare const PRIVATE: {
@@ -1,6 +1,7 @@
1
1
  import { isScriptableUrl } from 'webext-content-scripts';
2
2
  import { isBackground } from 'webext-detect';
3
3
  import SimpleEventTarget from 'simple-event-target';
4
+ import { StorageItemMap } from 'webext-storage';
4
5
  if (!isBackground()) {
5
6
  throw new Error('This module is only allowed in a background script');
6
7
  }
@@ -10,35 +11,40 @@ if (!chrome.runtime.getManifest().permissions?.includes('activeTab')) {
10
11
  const activation = new SimpleEventTarget();
11
12
  const deactivation = new SimpleEventTarget();
12
13
  const browserAction = chrome.action ?? chrome.browserAction;
13
- // TODO: use https://github.com/fregante/webext-storage/issues/5
14
14
  /**
15
15
  * The list is not guaranteed to be up to date. The activeTab permission might be lost before it's detected.
16
16
  */
17
- export const possiblyActiveTabs = new Map();
17
+ export const possiblyActiveTabs = chrome.storage.session
18
+ ? new StorageItemMap('webext-active-tab', {
19
+ area: 'session',
20
+ })
21
+ : new Map();
18
22
  async function addIfScriptable({ url, id }) {
19
23
  if (id && url
20
24
  // Skip if it already exists. A previous change of origin already cleared this
21
- && !possiblyActiveTabs.has(id)
25
+ && !await possiblyActiveTabs.has(String(id))
22
26
  // ActiveTab doesn't make sense on non-scriptable URLs as they generally don't have scriptable frames
23
27
  && isScriptableUrl(url)
24
28
  // Note: Do not filter by `isContentScriptRegistered`; `active-tab` also applies to random `executeScript` calls
25
29
  ) {
26
30
  const { origin } = new URL(url);
27
31
  console.debug('activeTab:', id, 'added', { origin });
28
- possiblyActiveTabs.set(id, origin);
32
+ await possiblyActiveTabs.set(String(id), origin);
29
33
  activation.emit({ id, origin });
30
34
  }
31
35
  else {
32
36
  console.debug('activeTab:', id, 'not added', { origin });
33
37
  }
34
38
  }
35
- function dropIfOriginChanged(tabId, { url }) {
36
- if (url && possiblyActiveTabs.has(tabId)) {
37
- const { origin } = new URL(url);
38
- if (possiblyActiveTabs.get(tabId) !== origin) {
39
- console.debug('activeTab:', tabId, 'removed because origin changed from', possiblyActiveTabs.get(tabId), 'to', origin);
40
- possiblyActiveTabs.delete(tabId);
41
- }
39
+ async function dropIfOriginChanged(tabId, { url }) {
40
+ if (!url) {
41
+ return;
42
+ }
43
+ const activeOrigin = await possiblyActiveTabs.get(String(tabId));
44
+ const { origin } = new URL(url);
45
+ if (activeOrigin !== origin) {
46
+ console.debug('activeTab:', tabId, 'removed because origin changed from', activeOrigin, 'to', origin);
47
+ void possiblyActiveTabs.delete(String(tabId));
42
48
  }
43
49
  }
44
50
  function altListener(_, tab) {
@@ -48,7 +54,7 @@ function altListener(_, tab) {
48
54
  }
49
55
  function drop(tabId) {
50
56
  console.debug('activeTab:', tabId, 'removed');
51
- possiblyActiveTabs.delete(tabId);
57
+ void possiblyActiveTabs.delete(String(tabId));
52
58
  deactivation.emit(tabId);
53
59
  }
54
60
  // https://developer.chrome.com/docs/extensions/mv3/manifest/activeTab/#invoking-activeTab
@@ -65,7 +71,8 @@ function stopActiveTabTracking() {
65
71
  chrome.commands?.onCommand.removeListener(altListener);
66
72
  chrome.tabs.onUpdated.removeListener(dropIfOriginChanged);
67
73
  chrome.tabs.onRemoved.removeListener(drop);
68
- possiblyActiveTabs.clear();
74
+ // TODO: Restore after https://github.com/fregante/webext-storage/issues/9
75
+ // void possiblyActiveTabs.clear();
69
76
  }
70
77
  export const PRIVATE = {
71
78
  startActiveTabTracking,
@@ -16,13 +16,14 @@ async function injectAllFrames({ id: tabId, origin: url }) {
16
16
  }
17
17
  async function injectOneFrame({ tabId, frameId, url }) {
18
18
  const { origin } = new URL(url);
19
+ const activeOrigin = await possiblyActiveTabs.get(String(tabId));
19
20
  // Check origin because the request might be for a frame; cross-origin frames do not receive activeTab
20
- if (possiblyActiveTabs.get(tabId) === origin) {
21
+ if (activeOrigin === origin) {
21
22
  console.debug('activeTab: will inject', { tabId, frameId, url });
22
23
  await injectContentScript({ tabId, frameId }, scripts);
23
24
  }
24
25
  else {
25
- console.debug('activeTab: won’t inject', { tabId, frameId, url }, { activeTab: possiblyActiveTabs.get(tabId) ?? 'no' });
26
+ console.debug('activeTab: won’t inject', { tabId, frameId, url }, { activeTab: activeOrigin ?? 'no' });
26
27
  }
27
28
  }
28
29
  async function tabListener(tabId, { status }, { url }) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "webext-active-tab",
3
- "version": "0.0.0",
4
- "description": "WebExtension module: Automatically registers your `content_scripts` on domains added via `permission.request` or on `activeTab`",
3
+ "version": "0.10.0",
4
+ "description": "WebExtension module: Track `activeTab` permission; automatically inject content scripts",
5
5
  "keywords": [
6
6
  "contentscript",
7
7
  "register",
@@ -24,9 +24,9 @@
24
24
  "author": "Federico Brigante <me@fregante.com> (https://fregante.com)",
25
25
  "type": "module",
26
26
  "exports": {
27
- "./on-active-tabs": {
28
- "types": "./distribution/on-active-tabs.d.ts",
29
- "default": "./distribution/on-active-tabs.js"
27
+ "./on-active-tab": {
28
+ "types": "./distribution/on-active-tab.d.ts",
29
+ "default": "./distribution/on-active-tab.js"
30
30
  },
31
31
  "./register-active-tab-scripts": {
32
32
  "types": "./distribution/register-active-tab-scripts.d.ts",
@@ -63,7 +63,8 @@
63
63
  "dependencies": {
64
64
  "simple-event-target": "^2.0.0",
65
65
  "webext-content-scripts": "^2.7.2",
66
- "webext-detect": "^5.3.2"
66
+ "webext-detect": "^5.3.2",
67
+ "webext-storage": "^1.3.1"
67
68
  },
68
69
  "devDependencies": {
69
70
  "@parcel/config-webextension": "^2.13.3",