wxt 0.8.6 → 0.8.7

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.
package/dist/client.d.ts CHANGED
@@ -1,9 +1,55 @@
1
1
  import { B as BackgroundDefinition, C as ContentScriptContext, a as ContentScriptDefinition } from './external-9107db91.js';
2
+ import * as wxt_browser from 'wxt/browser';
2
3
  import 'webextension-polyfill';
3
4
 
4
5
  declare function defineBackground(main: () => void): BackgroundDefinition;
5
6
  declare function defineBackground(definition: BackgroundDefinition): BackgroundDefinition;
6
7
 
8
+ type ContentScriptOverlayAlignment = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
9
+ type ContentScriptAppendMode = 'last' | 'first' | 'replace' | 'before' | 'after' | ((anchor: Element, ui: Element) => void);
10
+ type ContentScriptPositioningOptions = {
11
+ type: 'inline';
12
+ } | {
13
+ type: 'overlay';
14
+ /**
15
+ * The `z-index` used on the `shadowHost`. Set to a positive number to show your UI over website
16
+ * content.
17
+ */
18
+ zIndex?: number;
19
+ /**
20
+ * When using `type: "overlay"`, the mounted element is 0px by 0px in size. Alignment specifies
21
+ * which corner is aligned with that 0x0 pixel space.
22
+ *
23
+ * @default "top-left"
24
+ */
25
+ alignment?: ContentScriptOverlayAlignment;
26
+ } | {
27
+ type: 'modal';
28
+ /**
29
+ * The `z-index` used on the `shadowHost`. Set to a positive number to show your UI over website
30
+ * content.
31
+ */
32
+ zIndex?: number;
33
+ };
34
+ interface ContentScriptAnchoredOptions {
35
+ /**
36
+ * A CSS selector, element, or function that returns one of the two. Along with `append`, the
37
+ * `anchor` dictates where in the page the UI will be added.
38
+ */
39
+ anchor?: string | Element | null | undefined | (() => string | Element | null | undefined);
40
+ /**
41
+ * In combination with `anchor`, decide how to add the UI to the DOM.
42
+ *
43
+ * - `"last"` (default) - Add the UI as the last child of the `anchor` element
44
+ * - `"first"` - Add the UI as the last child of the `anchor` element
45
+ * - `"replace"` - Replace the `anchor` element with the UI.
46
+ * - `"before"` - Add the UI as the sibling before the `anchor` element
47
+ * - `"after"` - Add the UI as the sibling after the `anchor` element
48
+ * - `(anchor, ui) => void` - Customizable function that let's you add the UI to the DOM
49
+ */
50
+ append?: ContentScriptAppendMode | ((anchor: Element, ui: Element) => void);
51
+ }
52
+
7
53
  /**
8
54
  * Utility for mounting content script UI's with isolated styles. Automatically removed from the DOM
9
55
  * when the content script's context is invalidated.
@@ -61,27 +107,11 @@ interface ContentScriptUi<TApp> {
61
107
  */
62
108
  remove: () => void;
63
109
  }
64
- interface BaseContentScriptUiOptions<TApp> {
110
+ type ContentScriptUiOptions<TApp> = ContentScriptPositioningOptions & ContentScriptAnchoredOptions & {
65
111
  /**
66
112
  * The name of the custom component used to host the ShadowRoot. Must be kebab-case.
67
113
  */
68
114
  name: string;
69
- /**
70
- * In combination with `anchor`, decide how to add the UI to the DOM.
71
- *
72
- * - `"last"` (default) - Add the UI as the last child of the `anchor` element
73
- * - `"first"` - Add the UI as the last child of the `anchor` element
74
- * - `"replace"` - Replace the `anchor` element with the UI.
75
- * - `"before"` - Add the UI as the sibling before the `anchor` element
76
- * - `"after"` - Add the UI as the sibling after the `anchor` element
77
- * - `(anchor, ui) => void` - Customizable function that let's you add the UI to the DOM
78
- */
79
- append?: ContentScriptAppendMode | ((anchor: Element, ui: Element) => void);
80
- /**
81
- * A CSS selector, element, or function that returns one of the two. Along with `append`, the
82
- * `anchor` dictates where in the page the UI will be added.
83
- */
84
- anchor?: string | Element | null | undefined | (() => string | Element | null | undefined);
85
115
  /**
86
116
  * Callback executed when mounting the UI. This function should create and append the UI to the
87
117
  * `container` element. It is called every time `ui.mount()` is called
@@ -102,37 +132,53 @@ interface BaseContentScriptUiOptions<TApp> {
102
132
  * See https://wxt.dev/entrypoints/content-scripts.html#ui for more info.
103
133
  */
104
134
  css?: string;
105
- }
106
- type OverlayContentScriptUiOptions<TApp> = BaseContentScriptUiOptions<TApp> & {
107
- type: 'overlay';
135
+ };
136
+
137
+ /**
138
+ * Utility for mounting a content script UI inside an iframe. Automatically removed from the DOM
139
+ * when the content script's context is invalidated.
140
+ *
141
+ * See https://wxt.dev/entrypoints/content-scripts.html#iframe for full documentation.
142
+ *
143
+ * @example
144
+ * export default defineContentScript({
145
+ * matches: ["*://*.google.com/*"],
146
+ *
147
+ * main(ctx) {
148
+ * const ui = await createContentScriptIframe(ctx, {
149
+ * page: "/content-script-overlay.html",
150
+ * type: "modal",
151
+ * })
152
+ * ui.mount();
153
+ * }
154
+ * })
155
+ */
156
+ declare function createContentScriptIframe(ctx: ContentScriptContext, options: ContentScriptIframeOptions): ContentScriptIframe;
157
+ interface ContentScriptIframe {
108
158
  /**
109
- * When using `type: "overlay"`, the mounted element is 0px by 0px in size. Alignment specifies
110
- * which corner is aligned with that 0x0 pixel space.
111
- *
112
- * @default "top-left"
159
+ * The iframe added to the DOM.
113
160
  */
114
- alignment?: ContentScriptUiOverlayAlignment;
161
+ iframe: HTMLIFrameElement;
115
162
  /**
116
- * The `z-index` used on the `shadowHost`. Set to a positive number to show your UI over website
117
- * content.
163
+ * A wrapper div that assists in positioning.
118
164
  */
119
- zIndex?: number;
120
- };
121
- type ModalContentScriptUiOptions<TApp> = BaseContentScriptUiOptions<TApp> & {
122
- type: 'modal';
165
+ wrapper: HTMLDivElement;
123
166
  /**
124
- * The `z-index` used on the `shadowHost`. Set to a positive number to show your UI over website
125
- * content.
167
+ * Function that mounts or remounts the UI on the page.
126
168
  */
127
- zIndex?: number;
128
- };
129
- type InlineContentScriptUiOptions<TApp> = BaseContentScriptUiOptions<TApp> & {
130
- type: 'inline';
169
+ mount: () => void;
170
+ /**
171
+ * Function that removes the UI from the webpage.
172
+ */
173
+ remove: () => void;
174
+ }
175
+ type ContentScriptIframeOptions = ContentScriptPositioningOptions & ContentScriptAnchoredOptions & {
176
+ /**
177
+ * The path to the unlisted HTML file to display in the iframe.
178
+ */
179
+ page: wxt_browser.PublicPath;
131
180
  };
132
- type ContentScriptUiOverlayAlignment = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
133
- type ContentScriptAppendMode = 'last' | 'first' | 'replace' | 'before' | 'after';
134
- type ContentScriptUiOptions<TApp> = OverlayContentScriptUiOptions<TApp> | ModalContentScriptUiOptions<TApp> | InlineContentScriptUiOptions<TApp>;
135
181
 
136
182
  declare function defineContentScript(definition: ContentScriptDefinition): ContentScriptDefinition;
137
183
 
138
- export { BaseContentScriptUiOptions, ContentScriptAppendMode, ContentScriptContext, ContentScriptUi, ContentScriptUiOptions, ContentScriptUiOverlayAlignment, InlineContentScriptUiOptions, ModalContentScriptUiOptions, OverlayContentScriptUiOptions, createContentScriptUi, defineBackground, defineContentScript };
184
+ export { ContentScriptContext, ContentScriptIframe, ContentScriptIframeOptions, ContentScriptUi, ContentScriptUiOptions, createContentScriptIframe, createContentScriptUi, defineBackground, defineContentScript };
package/dist/client.js CHANGED
@@ -185,6 +185,80 @@ var ContentScriptContext = class _ContentScriptContext {
185
185
 
186
186
  // src/client/content-scripts/content-script-ui.ts
187
187
  import { createIsolatedElement } from "@webext-core/isolated-element";
188
+
189
+ // src/client/utils/content-script-ui.ts
190
+ function mountContentScriptUiRoot(root, options) {
191
+ const anchor = getAnchor(options);
192
+ if (anchor == null)
193
+ throw Error(
194
+ "Failed to mount content script UI: could not find anchor element"
195
+ );
196
+ switch (options.append) {
197
+ case void 0:
198
+ case "last":
199
+ anchor.append(root);
200
+ break;
201
+ case "first":
202
+ if (anchor.firstChild) {
203
+ anchor.insertBefore(root, anchor.firstChild);
204
+ } else {
205
+ anchor.append(root);
206
+ }
207
+ break;
208
+ case "replace":
209
+ anchor.replaceWith(root);
210
+ break;
211
+ case "after":
212
+ anchor.replaceWith(anchor, root);
213
+ break;
214
+ case "before":
215
+ anchor.replaceWith(root, anchor);
216
+ break;
217
+ default:
218
+ options.append(anchor, root);
219
+ break;
220
+ }
221
+ }
222
+ function applyContentScriptUiPosition(root, positionedElement, options) {
223
+ if (options.type !== "inline") {
224
+ if (options.zIndex != null)
225
+ root.style.zIndex = String(options.zIndex);
226
+ root.style.overflow = "visible";
227
+ root.style.position = "relative";
228
+ root.style.width = "0";
229
+ root.style.height = "0";
230
+ root.style.display = "block";
231
+ if (positionedElement) {
232
+ if (options.type === "overlay") {
233
+ positionedElement.style.position = "absolute";
234
+ if (options.alignment?.startsWith("bottom-"))
235
+ positionedElement.style.bottom = "0";
236
+ else
237
+ positionedElement.style.top = "0";
238
+ if (options.alignment?.endsWith("-right"))
239
+ positionedElement.style.right = "0";
240
+ else
241
+ positionedElement.style.left = "0";
242
+ } else {
243
+ positionedElement.style.position = "fixed";
244
+ positionedElement.style.top = "0";
245
+ positionedElement.style.bottom = "0";
246
+ positionedElement.style.left = "0";
247
+ positionedElement.style.right = "0";
248
+ }
249
+ }
250
+ }
251
+ }
252
+ function getAnchor(options) {
253
+ if (options.anchor == null)
254
+ return document.body;
255
+ let resolved = typeof options.anchor === "function" ? options.anchor() : options.anchor;
256
+ if (typeof resolved === "string")
257
+ return document.querySelector(resolved) ?? void 0;
258
+ return resolved ?? void 0;
259
+ }
260
+
261
+ // src/client/content-scripts/content-script-ui.ts
188
262
  async function createContentScriptUi(ctx, options) {
189
263
  const css = [options.css ?? ""];
190
264
  if (ctx.options?.cssInjectionMode === "ui") {
@@ -201,74 +275,15 @@ async function createContentScriptUi(ctx, options) {
201
275
  },
202
276
  mode: "open"
203
277
  });
204
- const getAnchor = () => {
205
- if (options.anchor == null)
206
- return document.body;
207
- let resolved = typeof options.anchor === "function" ? options.anchor() : options.anchor;
208
- if (typeof resolved === "string")
209
- return document.querySelector(resolved) ?? void 0;
210
- return resolved ?? void 0;
211
- };
212
278
  let mounted;
213
279
  const mount = () => {
214
- const anchor = getAnchor();
215
- if (anchor == null)
216
- throw Error(
217
- "Failed to mount content script ui: could not find anchor element"
218
- );
219
280
  mounted = options.mount(uiContainer);
220
- switch (options.append) {
221
- case void 0:
222
- case "last":
223
- anchor.append(shadowHost);
224
- break;
225
- case "first":
226
- if (anchor.firstChild) {
227
- anchor.insertBefore(shadowHost, anchor.firstChild);
228
- } else {
229
- anchor.append(shadowHost);
230
- }
231
- break;
232
- case "replace":
233
- anchor.replaceWith(shadowHost);
234
- break;
235
- case "after":
236
- anchor.replaceWith(anchor, shadowHost);
237
- break;
238
- case "before":
239
- anchor.replaceWith(shadowHost, anchor);
240
- break;
241
- default:
242
- options.append(anchor, shadowHost);
243
- break;
244
- }
245
- if (options.type !== "inline") {
246
- if (options.zIndex != null)
247
- shadowHost.style.zIndex = String(options.zIndex);
248
- shadowHost.style.overflow = "visible";
249
- shadowHost.style.position = "relative";
250
- shadowHost.style.width = "0";
251
- shadowHost.style.height = "0";
252
- shadowHost.style.display = "block";
253
- const html = shadow.querySelector("html");
254
- if (options.type === "overlay") {
255
- html.style.position = "absolute";
256
- if (options.alignment?.startsWith("bottom-"))
257
- html.style.bottom = "0";
258
- else
259
- html.style.top = "0";
260
- if (options.alignment?.endsWith("-right"))
261
- html.style.right = "0";
262
- else
263
- html.style.left = "0";
264
- } else {
265
- html.style.position = "fixed";
266
- html.style.top = "0";
267
- html.style.bottom = "0";
268
- html.style.left = "0";
269
- html.style.right = "0";
270
- }
271
- }
281
+ mountContentScriptUiRoot(shadowHost, options);
282
+ applyContentScriptUiPosition(
283
+ shadowHost,
284
+ shadow.querySelector("html"),
285
+ options
286
+ );
272
287
  };
273
288
  const remove = () => {
274
289
  shadowHost.remove();
@@ -301,12 +316,37 @@ async function loadCss() {
301
316
  }
302
317
  }
303
318
 
319
+ // src/client/content-scripts/content-script-iframe.ts
320
+ import browser2 from "webextension-polyfill";
321
+ function createContentScriptIframe(ctx, options) {
322
+ const wrapper = document.createElement("div");
323
+ wrapper.classList.add("wxt-iframe-wrapper");
324
+ const iframe = document.createElement("iframe");
325
+ iframe.src = browser2.runtime.getURL(options.page);
326
+ wrapper.appendChild(iframe);
327
+ const mount = () => {
328
+ applyContentScriptUiPosition(wrapper, iframe, options);
329
+ mountContentScriptUiRoot(wrapper, options);
330
+ };
331
+ const remove = () => {
332
+ wrapper.remove();
333
+ };
334
+ ctx.onInvalidated(remove);
335
+ return {
336
+ iframe,
337
+ wrapper,
338
+ mount,
339
+ remove
340
+ };
341
+ }
342
+
304
343
  // src/client/content-scripts/define-content-script.ts
305
344
  function defineContentScript(definition) {
306
345
  return definition;
307
346
  }
308
347
  export {
309
348
  ContentScriptContext,
349
+ createContentScriptIframe,
310
350
  createContentScriptUi,
311
351
  defineBackground,
312
352
  defineContentScript