wxt 0.16.8-alpha2 → 0.16.9

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,5 +1,5 @@
1
1
  // package.json
2
- var version = "0.16.8-alpha2";
2
+ var version = "0.16.9";
3
3
 
4
4
  // src/core/utils/paths.ts
5
5
  import systemPath from "node:path";
@@ -204,6 +204,14 @@ function resolvePerBrowserOption(option, browser) {
204
204
  return option[browser];
205
205
  return option;
206
206
  }
207
+ function resolvePerBrowserOptions(options, browser) {
208
+ return Object.fromEntries(
209
+ Object.entries(options).map(([key, value]) => [
210
+ key,
211
+ key === "defaultIcon" ? value : resolvePerBrowserOption(value, browser)
212
+ ])
213
+ );
214
+ }
207
215
 
208
216
  // src/core/utils/constants.ts
209
217
  var VIRTUAL_NOOP_BACKGROUND_MODULE_ID = "virtual:user-background";
@@ -242,6 +250,8 @@ async function findEntrypoints() {
242
250
  switch (type) {
243
251
  case "popup":
244
252
  return await getPopupEntrypoint(info);
253
+ case "sidepanel":
254
+ return await getSidepanelEntrypoint(info);
245
255
  case "options":
246
256
  return await getOptionsEntrypoint(info);
247
257
  case "background":
@@ -352,100 +362,66 @@ function preventNoEntrypoints(files) {
352
362
  throw Error(`No entrypoints found in ${wxt.config.entrypointsDir}`);
353
363
  }
354
364
  }
355
- function getHtmlBaseOptions(document) {
356
- const options = {};
357
- const includeContent = document.querySelector("meta[name='manifest.include']")?.getAttribute("content");
358
- if (includeContent) {
359
- options.include = JSON5.parse(includeContent);
360
- }
361
- const excludeContent = document.querySelector("meta[name='manifest.exclude']")?.getAttribute("content");
362
- if (excludeContent) {
363
- options.exclude = JSON5.parse(excludeContent);
364
- }
365
- return options;
366
- }
367
- async function getPopupEntrypoint({
368
- inputPath,
369
- name,
370
- skipped
371
- }) {
372
- const content = await fs3.readFile(inputPath, "utf-8");
373
- const { document } = parseHTML(content);
374
- const options = getHtmlBaseOptions(document);
375
- const title = document.querySelector("title");
376
- if (title != null)
377
- options.defaultTitle = title.textContent ?? void 0;
378
- const defaultIconContent = document.querySelector("meta[name='manifest.default_icon']")?.getAttribute("content");
379
- if (defaultIconContent) {
380
- try {
381
- options.defaultIcon = JSON5.parse(defaultIconContent);
382
- } catch (err) {
383
- wxt.logger.fatal(
384
- `Failed to parse default_icon meta tag content as JSON5. content=${defaultIconContent}`,
385
- err
386
- );
365
+ async function getPopupEntrypoint(info) {
366
+ const options = await getHtmlEntrypointOptions(
367
+ info,
368
+ {
369
+ browserStyle: "browse_style",
370
+ exclude: "exclude",
371
+ include: "include",
372
+ defaultIcon: "default_icon",
373
+ defaultTitle: "default_title",
374
+ mv2Key: "type"
375
+ },
376
+ {
377
+ defaultTitle: (document) => document.querySelector("title")?.textContent || void 0
378
+ },
379
+ {
380
+ defaultTitle: (content) => content,
381
+ mv2Key: (content) => content === "page_action" ? "page_action" : "browser_action"
387
382
  }
388
- }
389
- const mv2TypeContent = document.querySelector("meta[name='manifest.type']")?.getAttribute("content");
390
- if (mv2TypeContent) {
391
- options.mv2Key = mv2TypeContent === "page_action" ? "page_action" : "browser_action";
392
- }
393
- const browserStyleContent = document.querySelector("meta[name='manifest.browser_style']")?.getAttribute("content");
394
- if (browserStyleContent) {
395
- options.browserStyle = browserStyleContent === "true";
396
- }
383
+ );
397
384
  return {
398
385
  type: "popup",
399
386
  name: "popup",
400
- options,
401
- inputPath,
387
+ options: resolvePerBrowserOptions(options, wxt.config.browser),
388
+ inputPath: info.inputPath,
402
389
  outputDir: wxt.config.outDir,
403
- skipped
390
+ skipped: info.skipped
404
391
  };
405
392
  }
406
- async function getOptionsEntrypoint({
407
- inputPath,
408
- name,
409
- skipped
410
- }) {
411
- const content = await fs3.readFile(inputPath, "utf-8");
412
- const { document } = parseHTML(content);
413
- const options = getHtmlBaseOptions(document);
414
- const openInTabContent = document.querySelector("meta[name='manifest.open_in_tab']")?.getAttribute("content");
415
- if (openInTabContent) {
416
- options.openInTab = openInTabContent === "true";
417
- }
418
- const chromeStyleContent = document.querySelector("meta[name='manifest.chrome_style']")?.getAttribute("content");
419
- if (chromeStyleContent) {
420
- options.chromeStyle = chromeStyleContent === "true";
421
- }
422
- const browserStyleContent = document.querySelector("meta[name='manifest.browser_style']")?.getAttribute("content");
423
- if (browserStyleContent) {
424
- options.browserStyle = browserStyleContent === "true";
425
- }
393
+ async function getOptionsEntrypoint(info) {
394
+ const options = await getHtmlEntrypointOptions(
395
+ info,
396
+ {
397
+ browserStyle: "browse_style",
398
+ chromeStyle: "chrome_style",
399
+ exclude: "exclude",
400
+ include: "include",
401
+ openInTab: "open_in_tab"
402
+ }
403
+ );
426
404
  return {
427
405
  type: "options",
428
406
  name: "options",
429
- options,
430
- inputPath,
407
+ options: resolvePerBrowserOptions(options, wxt.config.browser),
408
+ inputPath: info.inputPath,
431
409
  outputDir: wxt.config.outDir,
432
- skipped
410
+ skipped: info.skipped
433
411
  };
434
412
  }
435
- async function getUnlistedPageEntrypoint({
436
- inputPath,
437
- name,
438
- skipped
439
- }) {
440
- const content = await fs3.readFile(inputPath, "utf-8");
441
- const { document } = parseHTML(content);
413
+ async function getUnlistedPageEntrypoint(info) {
414
+ const options = await getHtmlEntrypointOptions(info, {
415
+ exclude: "exclude",
416
+ include: "include"
417
+ });
442
418
  return {
443
419
  type: "unlisted-page",
444
- name: getEntrypointName(wxt.config.entrypointsDir, inputPath),
445
- inputPath,
420
+ name: info.name,
421
+ inputPath: info.inputPath,
446
422
  outputDir: wxt.config.outDir,
447
- options: getHtmlBaseOptions(document),
448
- skipped
423
+ options,
424
+ skipped: info.skipped
449
425
  };
450
426
  }
451
427
  async function getUnlistedScriptEntrypoint({
@@ -459,14 +435,13 @@ async function getUnlistedScriptEntrypoint({
459
435
  `${name}: Default export not found, did you forget to call "export default defineUnlistedScript(...)"?`
460
436
  );
461
437
  }
462
- const { main: _, ...moduleOptions } = defaultExport;
463
- const options = moduleOptions;
438
+ const { main: _, ...options } = defaultExport;
464
439
  return {
465
440
  type: "unlisted-script",
466
441
  name,
467
442
  inputPath,
468
443
  outputDir: wxt.config.outDir,
469
- options,
444
+ options: resolvePerBrowserOptions(options, wxt.config.browser),
470
445
  skipped
471
446
  };
472
447
  }
@@ -494,14 +469,7 @@ async function getBackgroundEntrypoint({
494
469
  name,
495
470
  inputPath,
496
471
  outputDir: wxt.config.outDir,
497
- options: {
498
- ...options,
499
- type: resolvePerBrowserOption(options.type, wxt.config.browser),
500
- persistent: resolvePerBrowserOption(
501
- options.persistent,
502
- wxt.config.browser
503
- )
504
- },
472
+ options: resolvePerBrowserOptions(options, wxt.config.browser),
505
473
  skipped
506
474
  };
507
475
  }
@@ -521,10 +489,58 @@ async function getContentScriptEntrypoint({
521
489
  name,
522
490
  inputPath,
523
491
  outputDir: resolve3(wxt.config.outDir, CONTENT_SCRIPT_OUT_DIR),
524
- options,
492
+ options: resolvePerBrowserOptions(options, wxt.config.browser),
525
493
  skipped
526
494
  };
527
495
  }
496
+ async function getSidepanelEntrypoint(info) {
497
+ const options = await getHtmlEntrypointOptions(
498
+ info,
499
+ {
500
+ browserStyle: "browse_style",
501
+ exclude: "exclude",
502
+ include: "include",
503
+ defaultIcon: "default_icon",
504
+ defaultTitle: "default_title",
505
+ openAtInstall: "open_at_install"
506
+ },
507
+ {
508
+ defaultTitle: (document) => document.querySelector("title")?.textContent || void 0
509
+ },
510
+ {
511
+ defaultTitle: (content) => content
512
+ }
513
+ );
514
+ return {
515
+ type: "sidepanel",
516
+ name: info.name,
517
+ options: resolvePerBrowserOptions(options, wxt.config.browser),
518
+ inputPath: info.inputPath,
519
+ outputDir: wxt.config.outDir,
520
+ skipped: info.skipped
521
+ };
522
+ }
523
+ async function getHtmlEntrypointOptions(info, keyMap, queries, parsers) {
524
+ const content = await fs3.readFile(info.inputPath, "utf-8");
525
+ const { document } = parseHTML(content);
526
+ const options = {};
527
+ const defaultQuery = (manifestKey) => document.querySelector(`meta[name='manifest.${manifestKey}']`)?.getAttribute("content");
528
+ Object.entries(keyMap).forEach(([_key, manifestKey]) => {
529
+ const key = _key;
530
+ const content2 = queries?.[key] ? queries[key](document, manifestKey) : defaultQuery(manifestKey);
531
+ if (content2) {
532
+ try {
533
+ options[key] = (parsers?.[key] ?? JSON5.parse)(content2);
534
+ } catch (err) {
535
+ wxt.logger.fatal(
536
+ `Failed to parse meta tag content. Usually this means you have invalid JSON5 content (content=${content2})`,
537
+ err
538
+ );
539
+ }
540
+ }
541
+ });
542
+ return options;
543
+ }
528
544
  var PATH_GLOB_TO_TYPE_MAP = {
529
545
  "sandbox.html": "sandbox",
530
546
  "sandbox/index.html": "sandbox",
@@ -2204,7 +2220,11 @@ var ContentSecurityPolicy = class _ContentSecurityPolicy {
2204
2220
 
2205
2221
  // src/core/utils/content-scripts.ts
2206
2222
  function hashContentScriptOptions(options) {
2207
- const simplifiedOptions = mapWxtOptionsToContentScript(options);
2223
+ const simplifiedOptions = mapWxtOptionsToContentScript(
2224
+ options,
2225
+ void 0,
2226
+ void 0
2227
+ );
2208
2228
  Object.keys(simplifiedOptions).forEach((key) => {
2209
2229
  if (simplifiedOptions[key] == null)
2210
2230
  delete simplifiedOptions[key];
@@ -2230,32 +2250,31 @@ function hashContentScriptOptions(options) {
2230
2250
  }).sort((l, r) => l[0].localeCompare(r[0]))
2231
2251
  );
2232
2252
  }
2233
- function mapWxtOptionsToContentScript(options) {
2253
+ function mapWxtOptionsToContentScript(options, js, css) {
2234
2254
  return {
2235
- matches: resolvePerBrowserOption(options.matches, wxt.config.browser),
2236
- all_frames: resolvePerBrowserOption(options.allFrames, wxt.config.browser),
2237
- match_about_blank: resolvePerBrowserOption(
2238
- options.matchAboutBlank,
2239
- wxt.config.browser
2240
- ),
2241
- exclude_globs: resolvePerBrowserOption(
2242
- options.excludeGlobs,
2243
- wxt.config.browser
2244
- ),
2245
- exclude_matches: resolvePerBrowserOption(
2246
- options.excludeMatches,
2247
- wxt.config.browser
2248
- ),
2249
- include_globs: resolvePerBrowserOption(
2250
- options.includeGlobs,
2251
- wxt.config.browser
2252
- ),
2253
- run_at: resolvePerBrowserOption(options.runAt, wxt.config.browser),
2255
+ matches: options.matches,
2256
+ all_frames: options.allFrames,
2257
+ match_about_blank: options.matchAboutBlank,
2258
+ exclude_globs: options.excludeGlobs,
2259
+ exclude_matches: options.excludeMatches,
2260
+ include_globs: options.includeGlobs,
2261
+ run_at: options.runAt,
2262
+ css,
2263
+ js,
2254
2264
  // @ts-expect-error: untyped chrome options
2255
- match_origin_as_fallback: resolvePerBrowserOption(
2256
- options.matchOriginAsFallback,
2257
- wxt.config.browser
2258
- ),
2265
+ match_origin_as_fallback: options.matchOriginAsFallback,
2266
+ world: options.world
2267
+ };
2268
+ }
2269
+ function mapWxtOptionsToRegisteredContentScript(options, js, css) {
2270
+ return {
2271
+ allFrames: options.allFrames,
2272
+ excludeMatches: options.excludeMatches,
2273
+ matches: options.matches,
2274
+ runAt: options.runAt,
2275
+ js,
2276
+ css,
2277
+ // @ts-expect-error: Chrome accepts this, not typed in webextension-polyfill (https://developer.chrome.com/docs/extensions/reference/scripting/#type-RegisteredContentScript)
2259
2278
  world: options.world
2260
2279
  };
2261
2280
  }
@@ -2490,9 +2509,11 @@ function addEntrypoints(manifest, entrypoints, buildOutput) {
2490
2509
  );
2491
2510
  if (wxt.config.browser === "firefox") {
2492
2511
  manifest.sidebar_action = {
2493
- // TODO: Add options to side panel
2494
- // ...defaultSidepanel.options,
2495
- default_panel: page
2512
+ default_panel: page,
2513
+ browser_style: defaultSidepanel.options.browserStyle,
2514
+ default_icon: defaultSidepanel.options.defaultIcon,
2515
+ default_title: defaultSidepanel.options.defaultTitle,
2516
+ open_at_install: defaultSidepanel.options.openAtInstall
2496
2517
  };
2497
2518
  } else if (wxt.config.manifestVersion === 3) {
2498
2519
  manifest.side_panel = {
@@ -2509,11 +2530,7 @@ function addEntrypoints(manifest, entrypoints, buildOutput) {
2509
2530
  if (wxt.config.command === "serve" && wxt.config.manifestVersion === 3) {
2510
2531
  const hostPermissions = new Set(manifest.host_permissions ?? []);
2511
2532
  contentScripts.forEach((script) => {
2512
- const matches = resolvePerBrowserOption(
2513
- script.options.matches,
2514
- wxt.config.browser
2515
- );
2516
- matches.forEach((matchPattern) => {
2533
+ script.options.matches.forEach((matchPattern) => {
2517
2534
  hostPermissions.add(matchPattern);
2518
2535
  });
2519
2536
  });
@@ -2530,13 +2547,13 @@ function addEntrypoints(manifest, entrypoints, buildOutput) {
2530
2547
  return map;
2531
2548
  }, /* @__PURE__ */ new Map());
2532
2549
  const newContentScripts = Array.from(hashToEntrypointsMap.entries()).map(
2533
- ([, scripts]) => ({
2534
- ...mapWxtOptionsToContentScript(scripts[0].options),
2535
- css: getContentScriptCssFiles(scripts, cssMap),
2536
- js: scripts.map(
2550
+ ([, scripts]) => mapWxtOptionsToContentScript(
2551
+ scripts[0].options,
2552
+ scripts.map(
2537
2553
  (entry) => getEntrypointBundlePath(entry, wxt.config.outDir, ".js")
2538
- )
2539
- })
2554
+ ),
2555
+ getContentScriptCssFiles(scripts, cssMap)
2556
+ )
2540
2557
  );
2541
2558
  if (newContentScripts.length >= 0) {
2542
2559
  manifest.content_scripts ??= [];
@@ -2640,10 +2657,9 @@ function getContentScriptCssWebAccessibleResources(contentScripts, contentScript
2640
2657
  return;
2641
2658
  resources.push({
2642
2659
  resources: [cssFile],
2643
- matches: resolvePerBrowserOption(
2644
- script.options.matches,
2645
- wxt.config.browser
2646
- ).map((matchPattern) => stripPathFromMatchPattern(matchPattern))
2660
+ matches: script.options.matches.map(
2661
+ (matchPattern) => stripPathFromMatchPattern(matchPattern)
2662
+ )
2647
2663
  });
2648
2664
  });
2649
2665
  return resources;
@@ -2943,7 +2959,6 @@ export {
2943
2959
  registerWxt,
2944
2960
  detectDevChanges,
2945
2961
  getEntrypointBundlePath,
2946
- resolvePerBrowserOption,
2947
2962
  findEntrypoints,
2948
2963
  generateTypesDir,
2949
2964
  formatDuration,
@@ -2957,6 +2972,7 @@ export {
2957
2972
  kebabCaseAlphanumeric,
2958
2973
  printFileList,
2959
2974
  version,
2975
+ mapWxtOptionsToRegisteredContentScript,
2960
2976
  getContentScriptCssFiles,
2961
2977
  getContentScriptsCssMap,
2962
2978
  rebuild,