@addonova/browser 0.1.0 → 0.2.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.
Files changed (99) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +259 -0
  3. package/dist/api/scripting/index.d.ts.map +1 -1
  4. package/dist/api/scripting/index.js.map +1 -1
  5. package/dist/api/storage/area.d.ts +4 -0
  6. package/dist/api/storage/area.d.ts.map +1 -0
  7. package/dist/api/storage/area.js +29 -0
  8. package/dist/api/storage/area.js.map +1 -0
  9. package/dist/api/storage/index.d.ts +4 -3
  10. package/dist/api/storage/index.d.ts.map +1 -1
  11. package/dist/api/storage/index.js +7 -27
  12. package/dist/api/storage/index.js.map +1 -1
  13. package/dist/api/storage/item.d.ts +4 -0
  14. package/dist/api/storage/item.d.ts.map +1 -0
  15. package/dist/api/storage/item.js +109 -0
  16. package/dist/api/storage/item.js.map +1 -0
  17. package/dist/content/context.d.ts +24 -0
  18. package/dist/content/context.d.ts.map +1 -0
  19. package/dist/content/context.js +157 -0
  20. package/dist/content/context.js.map +1 -0
  21. package/dist/content/index.d.ts +7 -0
  22. package/dist/content/index.d.ts.map +1 -0
  23. package/dist/content/index.js +4 -0
  24. package/dist/content/index.js.map +1 -0
  25. package/dist/content/inject-root.d.ts +2 -0
  26. package/dist/content/inject-root.d.ts.map +1 -0
  27. package/dist/content/inject-root.js +4 -0
  28. package/dist/content/inject-root.js.map +1 -0
  29. package/dist/content/inject-script.d.ts +16 -0
  30. package/dist/content/inject-script.d.ts.map +1 -0
  31. package/dist/content/inject-script.js +39 -0
  32. package/dist/content/inject-script.js.map +1 -0
  33. package/dist/content/ui.d.ts +50 -0
  34. package/dist/content/ui.d.ts.map +1 -0
  35. package/dist/content/ui.js +331 -0
  36. package/dist/content/ui.js.map +1 -0
  37. package/dist/entries/chrome.d.ts +3 -0
  38. package/dist/entries/chrome.d.ts.map +1 -1
  39. package/dist/entries/chrome.js +7 -0
  40. package/dist/entries/chrome.js.map +1 -1
  41. package/dist/entries/chromium.d.ts +3 -0
  42. package/dist/entries/chromium.d.ts.map +1 -1
  43. package/dist/entries/chromium.js +7 -0
  44. package/dist/entries/chromium.js.map +1 -1
  45. package/dist/entries/edge.d.ts +3 -0
  46. package/dist/entries/edge.d.ts.map +1 -1
  47. package/dist/entries/edge.js +7 -0
  48. package/dist/entries/edge.js.map +1 -1
  49. package/dist/entries/firefox.d.ts +3 -0
  50. package/dist/entries/firefox.d.ts.map +1 -1
  51. package/dist/entries/firefox.js +7 -0
  52. package/dist/entries/firefox.js.map +1 -1
  53. package/dist/entries/shared-exports.d.ts +10 -0
  54. package/dist/entries/shared-exports.d.ts.map +1 -1
  55. package/dist/entries/shared-exports.js +5 -0
  56. package/dist/entries/shared-exports.js.map +1 -1
  57. package/dist/entries/utilities.d.ts +6 -0
  58. package/dist/entries/utilities.d.ts.map +1 -0
  59. package/dist/entries/utilities.js +7 -0
  60. package/dist/entries/utilities.js.map +1 -0
  61. package/dist/i18n/index.d.ts +16 -0
  62. package/dist/i18n/index.d.ts.map +1 -0
  63. package/dist/i18n/index.js +52 -0
  64. package/dist/i18n/index.js.map +1 -0
  65. package/dist/index.d.ts +13 -0
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.js +8 -0
  68. package/dist/index.js.map +1 -1
  69. package/dist/messaging/index.d.ts +22 -0
  70. package/dist/messaging/index.d.ts.map +1 -0
  71. package/dist/messaging/index.js +100 -0
  72. package/dist/messaging/index.js.map +1 -0
  73. package/dist/messaging/proxy.d.ts +17 -0
  74. package/dist/messaging/proxy.d.ts.map +1 -0
  75. package/dist/messaging/proxy.js +61 -0
  76. package/dist/messaging/proxy.js.map +1 -0
  77. package/dist/messaging/root.d.ts +4 -0
  78. package/dist/messaging/root.d.ts.map +1 -0
  79. package/dist/messaging/root.js +9 -0
  80. package/dist/messaging/root.js.map +1 -0
  81. package/dist/testing/fake-browser.d.ts +184 -0
  82. package/dist/testing/fake-browser.d.ts.map +1 -0
  83. package/dist/testing/fake-browser.js +994 -0
  84. package/dist/testing/fake-browser.js.map +1 -0
  85. package/dist/testing/index.d.ts +3 -0
  86. package/dist/testing/index.d.ts.map +1 -0
  87. package/dist/testing/index.js +2 -0
  88. package/dist/testing/index.js.map +1 -0
  89. package/dist/testing/setup.d.ts +2 -0
  90. package/dist/testing/setup.d.ts.map +1 -0
  91. package/dist/testing/setup.js +6 -0
  92. package/dist/testing/setup.js.map +1 -0
  93. package/dist/types/index.d.ts +1 -1
  94. package/dist/types/index.d.ts.map +1 -1
  95. package/dist/types/scripting.d.ts +5 -5
  96. package/dist/types/scripting.d.ts.map +1 -1
  97. package/dist/types/storage.d.ts +23 -0
  98. package/dist/types/storage.d.ts.map +1 -1
  99. package/package.json +30 -2
@@ -0,0 +1,157 @@
1
+ import { BrowserApiError } from '../shared/errors.js';
2
+ export function createContentScriptContext(options = {}) {
3
+ const validateRuntime = options.validateRuntime ?? true;
4
+ const runtime = options.runtime ?? getGlobalRuntime();
5
+ const controller = new AbortController();
6
+ const timers = new Set();
7
+ const intervals = new Set();
8
+ const animationFrames = new Set();
9
+ const listeners = new Map();
10
+ const invalidationCallbacks = new Set();
11
+ const isValid = () => {
12
+ if (controller.signal.aborted) {
13
+ return false;
14
+ }
15
+ if (!validateRuntime) {
16
+ return true;
17
+ }
18
+ try {
19
+ return runtime?.id !== undefined && runtime.id !== '';
20
+ }
21
+ catch {
22
+ return false;
23
+ }
24
+ };
25
+ const context = {
26
+ get isValid() {
27
+ return isValid();
28
+ },
29
+ signal: controller.signal,
30
+ setTimeout(callback, timeout = 0, ...args) {
31
+ const timer = globalThis.setTimeout(() => {
32
+ timers.delete(timer);
33
+ if (!controller.signal.aborted) {
34
+ callback(...args);
35
+ }
36
+ }, timeout);
37
+ timers.add(timer);
38
+ return timer;
39
+ },
40
+ clearTimeout(timer) {
41
+ timers.delete(timer);
42
+ globalThis.clearTimeout(timer);
43
+ },
44
+ setInterval(callback, timeout = 0, ...args) {
45
+ const timer = globalThis.setInterval(() => {
46
+ if (!controller.signal.aborted) {
47
+ callback(...args);
48
+ }
49
+ }, timeout);
50
+ intervals.add(timer);
51
+ return timer;
52
+ },
53
+ clearInterval(timer) {
54
+ intervals.delete(timer);
55
+ globalThis.clearInterval(timer);
56
+ },
57
+ requestAnimationFrame(callback) {
58
+ if (typeof globalThis.requestAnimationFrame !== 'function') {
59
+ throw new BrowserApiError('BROWSER_UNSUPPORTED_API', 'requestAnimationFrame is not available in this environment.');
60
+ }
61
+ const id = globalThis.requestAnimationFrame((time) => {
62
+ animationFrames.delete(id);
63
+ if (!controller.signal.aborted) {
64
+ callback(time);
65
+ }
66
+ });
67
+ animationFrames.add(id);
68
+ return id;
69
+ },
70
+ cancelAnimationFrame(id) {
71
+ animationFrames.delete(id);
72
+ globalThis.cancelAnimationFrame?.(id);
73
+ },
74
+ addEventListener(targetOrType, typeOrListener, listenerOrOptions, maybeOptions) {
75
+ const hasTarget = typeof targetOrType !== 'string';
76
+ const target = hasTarget
77
+ ? targetOrType
78
+ : getDefaultEventTarget();
79
+ const type = hasTarget ? typeOrListener : targetOrType;
80
+ const listener = hasTarget
81
+ ? listenerOrOptions
82
+ : typeOrListener;
83
+ const options = hasTarget
84
+ ? maybeOptions
85
+ : listenerOrOptions;
86
+ if (target === undefined) {
87
+ throw new BrowserApiError('BROWSER_UNSUPPORTED_ENVIRONMENT', 'No event target is available for the content script context.');
88
+ }
89
+ target.addEventListener(type, listener, options);
90
+ const remove = () => {
91
+ target.removeEventListener(type, listener, options);
92
+ listeners.delete(remove);
93
+ };
94
+ listeners.set(remove, {
95
+ target,
96
+ type,
97
+ listener,
98
+ ...(options === undefined ? {} : { options }),
99
+ });
100
+ return remove;
101
+ },
102
+ onInvalidated(callback) {
103
+ if (controller.signal.aborted) {
104
+ callback();
105
+ return () => { };
106
+ }
107
+ invalidationCallbacks.add(callback);
108
+ return () => invalidationCallbacks.delete(callback);
109
+ },
110
+ invalidate() {
111
+ if (controller.signal.aborted) {
112
+ return;
113
+ }
114
+ controller.abort();
115
+ for (const timer of timers) {
116
+ globalThis.clearTimeout(timer);
117
+ }
118
+ timers.clear();
119
+ for (const timer of intervals) {
120
+ globalThis.clearInterval(timer);
121
+ }
122
+ intervals.clear();
123
+ for (const id of animationFrames) {
124
+ globalThis.cancelAnimationFrame?.(id);
125
+ }
126
+ animationFrames.clear();
127
+ for (const remove of [...listeners.keys()]) {
128
+ remove();
129
+ }
130
+ listeners.clear();
131
+ for (const callback of [...invalidationCallbacks]) {
132
+ callback();
133
+ }
134
+ invalidationCallbacks.clear();
135
+ },
136
+ };
137
+ if (typeof window !== 'undefined') {
138
+ context.addEventListener(window, 'pagehide', () => context.invalidate(), {
139
+ once: true,
140
+ });
141
+ }
142
+ return context;
143
+ }
144
+ function getGlobalRuntime() {
145
+ const global = globalThis;
146
+ return global.browser?.runtime ?? global.chrome?.runtime;
147
+ }
148
+ function getDefaultEventTarget() {
149
+ if (typeof window !== 'undefined') {
150
+ return window;
151
+ }
152
+ if (typeof document !== 'undefined') {
153
+ return document;
154
+ }
155
+ return undefined;
156
+ }
157
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/content/context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export { createContentScriptContext, } from './context.ts';
2
+ export type { ContentScriptContext, ContentScriptContextOptions, ContentScriptRuntime, ContentScriptTimer, } from './context.ts';
3
+ export { createInjectScript } from './inject-script.ts';
4
+ export type { InjectScript, InjectScriptApis, InjectScriptOptions, } from './inject-script.ts';
5
+ export { createIframeUi, createIntegratedUi, createShadowRootUi, } from './ui.ts';
6
+ export type { AutoMountOptions, BaseUiOptions, ContentScriptUi, IframeUiOptions, IntegratedUiOptions, ShadowRootContentScriptUi, ShadowRootUiOptions, UiAlignment, UiAnchor, UiAppendMode, UiPosition, } from './ui.ts';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/content/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,GAC3B,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,oBAAoB,EACpB,2BAA2B,EAC3B,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,YAAY,EACV,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,SAAS,CAAC;AACjB,YAAY,EACV,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,yBAAyB,EACzB,mBAAmB,EACnB,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,UAAU,GACX,MAAM,SAAS,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { createContentScriptContext, } from './context.js';
2
+ export { createInjectScript } from './inject-script.js';
3
+ export { createIframeUi, createIntegratedUi, createShadowRootUi, } from './ui.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/content/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,GAC3B,MAAM,cAAc,CAAC;AAOtB,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAMxD,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,SAAS,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const injectScript: import("./inject-script.ts").InjectScript;
2
+ //# sourceMappingURL=inject-root.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inject-root.d.ts","sourceRoot":"","sources":["../../src/content/inject-root.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,2CAA0C,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { scripting, tabs } from '../api/singletons.js';
2
+ import { createInjectScript } from './inject-script.js';
3
+ export const injectScript = createInjectScript({ scripting, tabs });
4
+ //# sourceMappingURL=inject-root.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inject-root.js","sourceRoot":"","sources":["../../src/content/inject-root.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,CAAC,MAAM,YAAY,GAAG,kBAAkB,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { InjectionResult, ScriptingApi } from '../types/scripting.ts';
2
+ import type { TabsApi } from '../types/tabs.ts';
3
+ export interface InjectScriptOptions {
4
+ readonly tabId?: number;
5
+ readonly frameIds?: readonly number[];
6
+ readonly allFrames?: boolean;
7
+ readonly world?: 'ISOLATED' | 'MAIN' | string;
8
+ readonly injectImmediately?: boolean;
9
+ }
10
+ export interface InjectScriptApis {
11
+ readonly scripting: Pick<ScriptingApi, 'executeScript'>;
12
+ readonly tabs: Pick<TabsApi, 'query'>;
13
+ }
14
+ export type InjectScript = (path: string | readonly string[], options?: InjectScriptOptions) => Promise<InjectionResult[]>;
15
+ export declare function createInjectScript(apis: InjectScriptApis): InjectScript;
16
+ //# sourceMappingURL=inject-script.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inject-script.d.ts","sourceRoot":"","sources":["../../src/content/inject-script.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,eAAe,EAGf,YAAY,EACb,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEhD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;IAC9C,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;CACtC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;IACxD,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;CACvC;AAED,MAAM,MAAM,YAAY,GAAG,CACzB,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,EAChC,OAAO,CAAC,EAAE,mBAAmB,KAC1B,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;AAEhC,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,YAAY,CAmDvE"}
@@ -0,0 +1,39 @@
1
+ import { BrowserApiError } from '../shared/errors.js';
2
+ export function createInjectScript(apis) {
3
+ const findActiveTabId = async () => {
4
+ const [tab] = await apis.tabs.query({
5
+ active: true,
6
+ currentWindow: true,
7
+ });
8
+ if (tab?.id === undefined) {
9
+ throw new BrowserApiError('BROWSER_API_FAILED', 'Could not resolve an active tab for script injection.', { api: 'tabs.query' });
10
+ }
11
+ return tab.id;
12
+ };
13
+ const resolveTarget = async (options) => {
14
+ const tabId = options.tabId ?? (await findActiveTabId());
15
+ return {
16
+ tabId,
17
+ ...(options.frameIds === undefined
18
+ ? {}
19
+ : { frameIds: options.frameIds }),
20
+ ...(options.allFrames === undefined
21
+ ? {}
22
+ : { allFrames: options.allFrames }),
23
+ };
24
+ };
25
+ return async function injectScript(path, options = {}) {
26
+ const target = await resolveTarget(options);
27
+ const files = typeof path === 'string' ? [path] : [...path];
28
+ const injection = {
29
+ target,
30
+ files,
31
+ ...(options.world === undefined ? {} : { world: options.world }),
32
+ ...(options.injectImmediately === undefined
33
+ ? {}
34
+ : { injectImmediately: options.injectImmediately }),
35
+ };
36
+ return apis.scripting.executeScript(injection);
37
+ };
38
+ }
39
+ //# sourceMappingURL=inject-script.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inject-script.js","sourceRoot":"","sources":["../../src/content/inject-script.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AA2BtD,MAAM,UAAU,kBAAkB,CAAC,IAAsB;IACvD,MAAM,eAAe,GAAG,KAAK,IAAqB,EAAE;QAClD,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;YAClC,MAAM,EAAE,IAAI;YACZ,aAAa,EAAE,IAAI;SACpB,CAAC,CAAC;QAEH,IAAI,GAAG,EAAE,EAAE,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,IAAI,eAAe,CACvB,oBAAoB,EACpB,uDAAuD,EACvD,EAAE,GAAG,EAAE,YAAY,EAAE,CACtB,CAAC;QACJ,CAAC;QAED,OAAO,GAAG,CAAC,EAAE,CAAC;IAChB,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,KAAK,EACzB,OAA4B,EACF,EAAE;QAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,MAAM,eAAe,EAAE,CAAC,CAAC;QAEzD,OAAO;YACL,KAAK;YACL,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS;gBAChC,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;YACnC,GAAG,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS;gBACjC,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC;SACtC,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO,KAAK,UAAU,YAAY,CAChC,IAAgC,EAChC,OAAO,GAAwB,EAAE;QAEjC,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAC5D,MAAM,SAAS,GAAoB;YACjC,MAAM;YACN,KAAK;YACL,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;YAChE,GAAG,CAAC,OAAO,CAAC,iBAAiB,KAAK,SAAS;gBACzC,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,EAAE,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,EAAE,CAAC;SACtD,CAAC;QAEF,OAAO,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IACjD,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,50 @@
1
+ import type { ContentScriptContext } from './context.ts';
2
+ export type UiAnchor = string | Element | (() => string | Element | null | undefined) | null;
3
+ export type UiAppendMode = 'first' | 'last' | 'before' | 'after' | 'replace' | ((anchor: Element, ui: HTMLElement) => void);
4
+ export type UiPosition = 'inline' | 'overlay' | 'modal';
5
+ export type UiAlignment = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
6
+ export interface AutoMountOptions {
7
+ readonly once?: boolean;
8
+ }
9
+ export interface ContentScriptUi<T> {
10
+ readonly mounted: T | undefined;
11
+ readonly element: HTMLElement | undefined;
12
+ readonly isValid: boolean;
13
+ mount(): Promise<T>;
14
+ remove(): void;
15
+ unmount(): void;
16
+ autoMount(options?: AutoMountOptions): () => void;
17
+ }
18
+ export interface BaseUiOptions<T> {
19
+ readonly anchor?: UiAnchor;
20
+ readonly append?: UiAppendMode;
21
+ readonly position?: UiPosition;
22
+ readonly alignment?: UiAlignment;
23
+ readonly zIndex?: number;
24
+ readonly onRemove?: (mounted: T | undefined) => void;
25
+ }
26
+ export interface IntegratedUiOptions<T> extends BaseUiOptions<T> {
27
+ readonly tag?: string;
28
+ readonly onMount?: (container: HTMLElement) => T | Promise<T>;
29
+ }
30
+ export interface ShadowRootUiOptions<T> extends BaseUiOptions<T> {
31
+ readonly tag?: string;
32
+ readonly name?: string;
33
+ readonly css?: string;
34
+ readonly mode?: ShadowRootMode;
35
+ readonly isolateEvents?: boolean;
36
+ readonly onMount?: (container: HTMLElement) => T | Promise<T>;
37
+ }
38
+ export interface IframeUiOptions<T> extends BaseUiOptions<T> {
39
+ readonly page: string;
40
+ readonly tag?: string;
41
+ readonly onMount?: (iframe: HTMLIFrameElement, wrapper: HTMLElement) => T | Promise<T>;
42
+ }
43
+ export interface ShadowRootContentScriptUi<T> extends ContentScriptUi<T> {
44
+ readonly shadow: ShadowRoot | undefined;
45
+ readonly shadowHost: HTMLElement | undefined;
46
+ }
47
+ export declare function createIntegratedUi<T = HTMLElement>(ctx: ContentScriptContext, options?: IntegratedUiOptions<T>): ContentScriptUi<T>;
48
+ export declare function createShadowRootUi<T = HTMLElement>(ctx: ContentScriptContext, options?: ShadowRootUiOptions<T>): ShadowRootContentScriptUi<T>;
49
+ export declare function createIframeUi<T = HTMLIFrameElement>(ctx: ContentScriptContext, options: IframeUiOptions<T>): ContentScriptUi<T>;
50
+ //# sourceMappingURL=ui.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../src/content/ui.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,331 @@
1
+ import { BrowserApiError } from '../shared/errors.js';
2
+ export function createIntegratedUi(ctx, options = {}) {
3
+ return createUi(ctx, options, {
4
+ createHost(document) {
5
+ return createHost(document, options.tag ?? 'div');
6
+ },
7
+ createContainer(host) {
8
+ return host;
9
+ },
10
+ async mount(container) {
11
+ return options.onMount === undefined
12
+ ? container
13
+ : options.onMount(container);
14
+ },
15
+ ...(options.onRemove === undefined
16
+ ? {}
17
+ : { onRemove: options.onRemove }),
18
+ });
19
+ }
20
+ export function createShadowRootUi(ctx, options = {}) {
21
+ let shadow;
22
+ let shadowHost;
23
+ const ui = createUi(ctx, options, {
24
+ createHost(document) {
25
+ shadowHost = createHost(document, options.tag ?? 'div');
26
+ if (options.name !== undefined) {
27
+ shadowHost.setAttribute('data-addonova-ui-name', options.name);
28
+ }
29
+ if (options.isolateEvents === true) {
30
+ isolateEvents(shadowHost);
31
+ }
32
+ return shadowHost;
33
+ },
34
+ createContainer(host, document) {
35
+ shadow = host.attachShadow({ mode: options.mode ?? 'open' });
36
+ if (options.css !== undefined && options.css !== '') {
37
+ const style = document.createElement('style');
38
+ style.textContent = options.css;
39
+ shadow.append(style);
40
+ }
41
+ const container = document.createElement('div');
42
+ shadow.append(container);
43
+ return container;
44
+ },
45
+ async mount(container) {
46
+ return options.onMount === undefined
47
+ ? container
48
+ : options.onMount(container);
49
+ },
50
+ ...(options.onRemove === undefined
51
+ ? {}
52
+ : { onRemove: options.onRemove }),
53
+ });
54
+ return Object.defineProperties(ui, {
55
+ shadow: {
56
+ configurable: true,
57
+ enumerable: true,
58
+ get() {
59
+ return shadow;
60
+ },
61
+ },
62
+ shadowHost: {
63
+ configurable: true,
64
+ enumerable: true,
65
+ get() {
66
+ return shadowHost;
67
+ },
68
+ },
69
+ });
70
+ }
71
+ export function createIframeUi(ctx, options) {
72
+ return createUi(ctx, options, {
73
+ createHost(document) {
74
+ return createHost(document, options.tag ?? 'div');
75
+ },
76
+ createContainer(host, document) {
77
+ const iframe = document.createElement('iframe');
78
+ iframe.src = resolveIframeUrl(options.page);
79
+ host.append(iframe);
80
+ return iframe;
81
+ },
82
+ async mount(container, host) {
83
+ const iframe = container;
84
+ return options.onMount === undefined
85
+ ? iframe
86
+ : options.onMount(iframe, host);
87
+ },
88
+ ...(options.onRemove === undefined
89
+ ? {}
90
+ : { onRemove: options.onRemove }),
91
+ });
92
+ }
93
+ function createUi(ctx, options, internals) {
94
+ let host;
95
+ let mounted;
96
+ let hasMounted = false;
97
+ let mounting;
98
+ let stopAutoMount;
99
+ const requireDocument = () => {
100
+ if (typeof document === 'undefined') {
101
+ throw new BrowserApiError('BROWSER_UNSUPPORTED_ENVIRONMENT', 'A DOM document is required to mount a content script UI.');
102
+ }
103
+ return document;
104
+ };
105
+ const attach = (hostElement) => {
106
+ const document = requireDocument();
107
+ const anchor = resolveAnchor(options.anchor, document);
108
+ if (anchor === null) {
109
+ throw new BrowserApiError('BROWSER_API_FAILED', 'Could not find an anchor element for the content script UI.');
110
+ }
111
+ applyPosition(hostElement, options);
112
+ insertUi(anchor, hostElement, options.append ?? 'last');
113
+ };
114
+ const mount = async () => {
115
+ if (hasMounted) {
116
+ return mounted;
117
+ }
118
+ if (mounting !== undefined) {
119
+ return mounting;
120
+ }
121
+ if (!ctx.isValid) {
122
+ throw new BrowserApiError('BROWSER_UNSUPPORTED_ENVIRONMENT', 'The content script context is no longer valid.');
123
+ }
124
+ mounting = (async () => {
125
+ const document = requireDocument();
126
+ host = internals.createHost(document);
127
+ try {
128
+ attach(host);
129
+ const container = internals.createContainer(host, document);
130
+ mounted = await internals.mount(container, host);
131
+ hasMounted = true;
132
+ return mounted;
133
+ }
134
+ catch (error) {
135
+ host.remove();
136
+ host = undefined;
137
+ throw error;
138
+ }
139
+ finally {
140
+ mounting = undefined;
141
+ }
142
+ })();
143
+ return mounting;
144
+ };
145
+ const remove = () => {
146
+ if (!hasMounted && host === undefined) {
147
+ return;
148
+ }
149
+ const currentHost = host;
150
+ const currentMounted = mounted;
151
+ hasMounted = false;
152
+ mounted = undefined;
153
+ host = undefined;
154
+ try {
155
+ internals.onRemove?.(currentMounted);
156
+ }
157
+ finally {
158
+ currentHost?.remove();
159
+ }
160
+ };
161
+ const autoMount = (autoOptions = {}) => {
162
+ if (stopAutoMount !== undefined) {
163
+ return stopAutoMount;
164
+ }
165
+ if (typeof document === 'undefined' || document.documentElement === null) {
166
+ return () => { };
167
+ }
168
+ let stopped = false;
169
+ let invalidatedCleanup;
170
+ const check = () => {
171
+ if (stopped) {
172
+ return;
173
+ }
174
+ const anchor = resolveAnchor(options.anchor, document);
175
+ if (anchor === null) {
176
+ if (hasMounted || host !== undefined) {
177
+ remove();
178
+ }
179
+ return;
180
+ }
181
+ if (!hasMounted) {
182
+ void mount().catch(() => { });
183
+ }
184
+ else if (host !== undefined && !host.isConnected) {
185
+ remove();
186
+ void mount().catch(() => { });
187
+ }
188
+ if (autoOptions.once === true && hasMounted) {
189
+ stop();
190
+ }
191
+ };
192
+ const observer = new MutationObserver(check);
193
+ observer.observe(document.documentElement, {
194
+ childList: true,
195
+ subtree: true,
196
+ });
197
+ const stop = () => {
198
+ if (stopped) {
199
+ return;
200
+ }
201
+ stopped = true;
202
+ observer.disconnect();
203
+ invalidatedCleanup?.();
204
+ stopAutoMount = undefined;
205
+ };
206
+ invalidatedCleanup = ctx.onInvalidated(() => {
207
+ stop();
208
+ remove();
209
+ });
210
+ stopAutoMount = stop;
211
+ check();
212
+ return stop;
213
+ };
214
+ return {
215
+ get mounted() {
216
+ return mounted;
217
+ },
218
+ get element() {
219
+ return host;
220
+ },
221
+ get isValid() {
222
+ return ctx.isValid;
223
+ },
224
+ mount,
225
+ remove,
226
+ unmount: remove,
227
+ autoMount,
228
+ };
229
+ }
230
+ function createHost(document, tag) {
231
+ const host = document.createElement(tag);
232
+ host.setAttribute('data-addonova-ui', '');
233
+ return host;
234
+ }
235
+ function resolveAnchor(anchor, document) {
236
+ if (anchor === undefined) {
237
+ return document.body ?? document.documentElement;
238
+ }
239
+ if (anchor === null) {
240
+ return null;
241
+ }
242
+ const resolved = typeof anchor === 'function' ? anchor() : anchor;
243
+ if (resolved === null || resolved === undefined) {
244
+ return null;
245
+ }
246
+ return typeof resolved === 'string'
247
+ ? document.querySelector(resolved)
248
+ : resolved;
249
+ }
250
+ function insertUi(anchor, ui, mode) {
251
+ if (typeof mode === 'function') {
252
+ mode(anchor, ui);
253
+ return;
254
+ }
255
+ switch (mode) {
256
+ case 'first':
257
+ anchor.prepend(ui);
258
+ break;
259
+ case 'last':
260
+ anchor.append(ui);
261
+ break;
262
+ case 'before':
263
+ anchor.before(ui);
264
+ break;
265
+ case 'after':
266
+ anchor.after(ui);
267
+ break;
268
+ case 'replace':
269
+ anchor.replaceWith(ui);
270
+ break;
271
+ }
272
+ }
273
+ function applyPosition(host, options) {
274
+ const position = options.position ?? 'inline';
275
+ if (position === 'inline') {
276
+ return;
277
+ }
278
+ host.style.position = 'fixed';
279
+ host.style.zIndex = String(options.zIndex ?? 2147483647);
280
+ if (position === 'modal') {
281
+ host.style.top = '0';
282
+ host.style.left = '0';
283
+ host.style.width = '100%';
284
+ host.style.height = '100%';
285
+ host.style.display = 'flex';
286
+ host.style.alignItems = 'center';
287
+ host.style.justifyContent = 'center';
288
+ return;
289
+ }
290
+ const alignment = options.alignment ?? 'top-left';
291
+ const [vertical, horizontal] = alignment.split('-');
292
+ host.style[vertical] = '0';
293
+ host.style[horizontal] = '0';
294
+ }
295
+ function isolateEvents(host) {
296
+ const events = [
297
+ 'click',
298
+ 'dblclick',
299
+ 'mousedown',
300
+ 'mouseup',
301
+ 'pointerdown',
302
+ 'pointerup',
303
+ 'keydown',
304
+ 'keyup',
305
+ 'keypress',
306
+ 'input',
307
+ 'change',
308
+ 'submit',
309
+ 'wheel',
310
+ 'touchstart',
311
+ 'touchend',
312
+ ];
313
+ for (const event of events) {
314
+ host.addEventListener(event, (value) => value.stopPropagation());
315
+ }
316
+ }
317
+ function resolveIframeUrl(page) {
318
+ if (/^(?:[a-z][a-z\d+.-]*:|\/\/)/i.test(page)) {
319
+ return page;
320
+ }
321
+ const runtime = getGlobalRuntime();
322
+ if (runtime === undefined || typeof runtime.getURL !== 'function') {
323
+ throw new BrowserApiError('BROWSER_UNSUPPORTED_ENVIRONMENT', 'The extension runtime is not available to resolve the iframe URL.');
324
+ }
325
+ return runtime.getURL(page);
326
+ }
327
+ function getGlobalRuntime() {
328
+ const global = globalThis;
329
+ return global.browser?.runtime ?? global.chrome?.runtime;
330
+ }
331
+ //# sourceMappingURL=ui.js.map