@fuzdev/fuz_ui 0.169.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.
- package/LICENSE +21 -0
- package/README.md +93 -0
- package/dist/Alert.svelte +108 -0
- package/dist/Alert.svelte.d.ts +16 -0
- package/dist/Alert.svelte.d.ts.map +1 -0
- package/dist/ApiDeclarationList.svelte +35 -0
- package/dist/ApiDeclarationList.svelte.d.ts +9 -0
- package/dist/ApiDeclarationList.svelte.d.ts.map +1 -0
- package/dist/ApiIndex.svelte +65 -0
- package/dist/ApiIndex.svelte.d.ts +23 -0
- package/dist/ApiIndex.svelte.d.ts.map +1 -0
- package/dist/ApiModule.svelte +124 -0
- package/dist/ApiModule.svelte.d.ts +22 -0
- package/dist/ApiModule.svelte.d.ts.map +1 -0
- package/dist/Breadcrumb.svelte +83 -0
- package/dist/Breadcrumb.svelte.d.ts +23 -0
- package/dist/Breadcrumb.svelte.d.ts.map +1 -0
- package/dist/Card.svelte +157 -0
- package/dist/Card.svelte.d.ts +13 -0
- package/dist/Card.svelte.d.ts.map +1 -0
- package/dist/ColorSchemeInput.svelte +65 -0
- package/dist/ColorSchemeInput.svelte.d.ts +11 -0
- package/dist/ColorSchemeInput.svelte.d.ts.map +1 -0
- package/dist/Contextmenu.svelte +30 -0
- package/dist/Contextmenu.svelte.d.ts +32 -0
- package/dist/Contextmenu.svelte.d.ts.map +1 -0
- package/dist/ContextmenuEntry.svelte +74 -0
- package/dist/ContextmenuEntry.svelte.d.ts +12 -0
- package/dist/ContextmenuEntry.svelte.d.ts.map +1 -0
- package/dist/ContextmenuLinkEntry.svelte +112 -0
- package/dist/ContextmenuLinkEntry.svelte.d.ts +12 -0
- package/dist/ContextmenuLinkEntry.svelte.d.ts.map +1 -0
- package/dist/ContextmenuRoot.svelte +372 -0
- package/dist/ContextmenuRoot.svelte.d.ts +71 -0
- package/dist/ContextmenuRoot.svelte.d.ts.map +1 -0
- package/dist/ContextmenuRootForSafariCompatibility.svelte +541 -0
- package/dist/ContextmenuRootForSafariCompatibility.svelte.d.ts +79 -0
- package/dist/ContextmenuRootForSafariCompatibility.svelte.d.ts.map +1 -0
- package/dist/ContextmenuSeparator.svelte +16 -0
- package/dist/ContextmenuSeparator.svelte.d.ts +4 -0
- package/dist/ContextmenuSeparator.svelte.d.ts.map +1 -0
- package/dist/ContextmenuSubmenu.svelte +116 -0
- package/dist/ContextmenuSubmenu.svelte.d.ts +10 -0
- package/dist/ContextmenuSubmenu.svelte.d.ts.map +1 -0
- package/dist/ContextmenuTextEntry.svelte +21 -0
- package/dist/ContextmenuTextEntry.svelte.d.ts +10 -0
- package/dist/ContextmenuTextEntry.svelte.d.ts.map +1 -0
- package/dist/CopyToClipboard.svelte +81 -0
- package/dist/CopyToClipboard.svelte.d.ts +18 -0
- package/dist/CopyToClipboard.svelte.d.ts.map +1 -0
- package/dist/DeclarationDetail.svelte +340 -0
- package/dist/DeclarationDetail.svelte.d.ts +8 -0
- package/dist/DeclarationDetail.svelte.d.ts.map +1 -0
- package/dist/DeclarationLink.svelte +50 -0
- package/dist/DeclarationLink.svelte.d.ts +8 -0
- package/dist/DeclarationLink.svelte.d.ts.map +1 -0
- package/dist/Details.svelte +51 -0
- package/dist/Details.svelte.d.ts +20 -0
- package/dist/Details.svelte.d.ts.map +1 -0
- package/dist/Dialog.svelte +217 -0
- package/dist/Dialog.svelte.d.ts +30 -0
- package/dist/Dialog.svelte.d.ts.map +1 -0
- package/dist/Dialogs.svelte +28 -0
- package/dist/Dialogs.svelte.d.ts +11 -0
- package/dist/Dialogs.svelte.d.ts.map +1 -0
- package/dist/Docs.svelte +179 -0
- package/dist/Docs.svelte.d.ts +13 -0
- package/dist/Docs.svelte.d.ts.map +1 -0
- package/dist/DocsContent.svelte +40 -0
- package/dist/DocsContent.svelte.d.ts +14 -0
- package/dist/DocsContent.svelte.d.ts.map +1 -0
- package/dist/DocsFooter.svelte +64 -0
- package/dist/DocsFooter.svelte.d.ts +15 -0
- package/dist/DocsFooter.svelte.d.ts.map +1 -0
- package/dist/DocsLink.svelte +41 -0
- package/dist/DocsLink.svelte.d.ts +12 -0
- package/dist/DocsLink.svelte.d.ts.map +1 -0
- package/dist/DocsList.svelte +44 -0
- package/dist/DocsList.svelte.d.ts +11 -0
- package/dist/DocsList.svelte.d.ts.map +1 -0
- package/dist/DocsMenu.svelte +55 -0
- package/dist/DocsMenu.svelte.d.ts +11 -0
- package/dist/DocsMenu.svelte.d.ts.map +1 -0
- package/dist/DocsMenuHeader.svelte +15 -0
- package/dist/DocsMenuHeader.svelte.d.ts +9 -0
- package/dist/DocsMenuHeader.svelte.d.ts.map +1 -0
- package/dist/DocsModulesList.svelte +32 -0
- package/dist/DocsModulesList.svelte.d.ts +7 -0
- package/dist/DocsModulesList.svelte.d.ts.map +1 -0
- package/dist/DocsPageLinks.svelte +61 -0
- package/dist/DocsPageLinks.svelte.d.ts +8 -0
- package/dist/DocsPageLinks.svelte.d.ts.map +1 -0
- package/dist/DocsPrimaryNav.svelte +93 -0
- package/dist/DocsPrimaryNav.svelte.d.ts +11 -0
- package/dist/DocsPrimaryNav.svelte.d.ts.map +1 -0
- package/dist/DocsSearch.svelte +48 -0
- package/dist/DocsSearch.svelte.d.ts +11 -0
- package/dist/DocsSearch.svelte.d.ts.map +1 -0
- package/dist/DocsSecondaryNav.svelte +63 -0
- package/dist/DocsSecondaryNav.svelte.d.ts +9 -0
- package/dist/DocsSecondaryNav.svelte.d.ts.map +1 -0
- package/dist/DocsTertiaryNav.svelte +118 -0
- package/dist/DocsTertiaryNav.svelte.d.ts +10 -0
- package/dist/DocsTertiaryNav.svelte.d.ts.map +1 -0
- package/dist/EcosystemLinks.svelte +53 -0
- package/dist/EcosystemLinks.svelte.d.ts +7 -0
- package/dist/EcosystemLinks.svelte.d.ts.map +1 -0
- package/dist/EcosystemLinksPanel.svelte +22 -0
- package/dist/EcosystemLinksPanel.svelte.d.ts +8 -0
- package/dist/EcosystemLinksPanel.svelte.d.ts.map +1 -0
- package/dist/GithubLink.svelte +75 -0
- package/dist/GithubLink.svelte.d.ts +14 -0
- package/dist/GithubLink.svelte.d.ts.map +1 -0
- package/dist/Glyph.svelte +28 -0
- package/dist/Glyph.svelte.d.ts +9 -0
- package/dist/Glyph.svelte.d.ts.map +1 -0
- package/dist/Hashlink.svelte +41 -0
- package/dist/Hashlink.svelte.d.ts +8 -0
- package/dist/Hashlink.svelte.d.ts.map +1 -0
- package/dist/HiddenPersonalLinks.svelte +6 -0
- package/dist/HiddenPersonalLinks.svelte.d.ts +27 -0
- package/dist/HiddenPersonalLinks.svelte.d.ts.map +1 -0
- package/dist/HueInput.svelte +127 -0
- package/dist/HueInput.svelte.d.ts +11 -0
- package/dist/HueInput.svelte.d.ts.map +1 -0
- package/dist/ImgOrSvg.svelte +58 -0
- package/dist/ImgOrSvg.svelte.d.ts +25 -0
- package/dist/ImgOrSvg.svelte.d.ts.map +1 -0
- package/dist/LibraryDetail.svelte +297 -0
- package/dist/LibraryDetail.svelte.d.ts +15 -0
- package/dist/LibraryDetail.svelte.d.ts.map +1 -0
- package/dist/LibrarySummary.svelte +151 -0
- package/dist/LibrarySummary.svelte.d.ts +16 -0
- package/dist/LibrarySummary.svelte.d.ts.map +1 -0
- package/dist/MdnLink.svelte +40 -0
- package/dist/MdnLink.svelte.d.ts +8 -0
- package/dist/MdnLink.svelte.d.ts.map +1 -0
- package/dist/Mdz.svelte +30 -0
- package/dist/Mdz.svelte.d.ts +10 -0
- package/dist/Mdz.svelte.d.ts.map +1 -0
- package/dist/MdzNodeView.svelte +93 -0
- package/dist/MdzNodeView.svelte.d.ts +9 -0
- package/dist/MdzNodeView.svelte.d.ts.map +1 -0
- package/dist/ModuleLink.svelte +48 -0
- package/dist/ModuleLink.svelte.d.ts +8 -0
- package/dist/ModuleLink.svelte.d.ts.map +1 -0
- package/dist/PasteFromClipboard.svelte +35 -0
- package/dist/PasteFromClipboard.svelte.d.ts +9 -0
- package/dist/PasteFromClipboard.svelte.d.ts.map +1 -0
- package/dist/PendingAnimation.svelte +62 -0
- package/dist/PendingAnimation.svelte.d.ts +13 -0
- package/dist/PendingAnimation.svelte.d.ts.map +1 -0
- package/dist/PendingButton.svelte +75 -0
- package/dist/PendingButton.svelte.d.ts +17 -0
- package/dist/PendingButton.svelte.d.ts.map +1 -0
- package/dist/ProjectLinks.svelte +54 -0
- package/dist/ProjectLinks.svelte.d.ts +19 -0
- package/dist/ProjectLinks.svelte.d.ts.map +1 -0
- package/dist/Redirect.svelte +44 -0
- package/dist/Redirect.svelte.d.ts +23 -0
- package/dist/Redirect.svelte.d.ts.map +1 -0
- package/dist/Spiders.svelte +57 -0
- package/dist/Spiders.svelte.d.ts +9 -0
- package/dist/Spiders.svelte.d.ts.map +1 -0
- package/dist/Svg.svelte +99 -0
- package/dist/Svg.svelte.d.ts +54 -0
- package/dist/Svg.svelte.d.ts.map +1 -0
- package/dist/Teleport.svelte +48 -0
- package/dist/Teleport.svelte.d.ts +15 -0
- package/dist/Teleport.svelte.d.ts.map +1 -0
- package/dist/ThemeInput.svelte +75 -0
- package/dist/ThemeInput.svelte.d.ts +15 -0
- package/dist/ThemeInput.svelte.d.ts.map +1 -0
- package/dist/Themed.svelte +101 -0
- package/dist/Themed.svelte.d.ts +24 -0
- package/dist/Themed.svelte.d.ts.map +1 -0
- package/dist/TomeContent.svelte +67 -0
- package/dist/TomeContent.svelte.d.ts +12 -0
- package/dist/TomeContent.svelte.d.ts.map +1 -0
- package/dist/TomeHeader.svelte +56 -0
- package/dist/TomeHeader.svelte.d.ts +4 -0
- package/dist/TomeHeader.svelte.d.ts.map +1 -0
- package/dist/TomeLink.svelte +29 -0
- package/dist/TomeLink.svelte.d.ts +10 -0
- package/dist/TomeLink.svelte.d.ts.map +1 -0
- package/dist/TomeSection.svelte +65 -0
- package/dist/TomeSection.svelte.d.ts +24 -0
- package/dist/TomeSection.svelte.d.ts.map +1 -0
- package/dist/TomeSectionHeader.svelte +90 -0
- package/dist/TomeSectionHeader.svelte.d.ts +13 -0
- package/dist/TomeSectionHeader.svelte.d.ts.map +1 -0
- package/dist/TypeLink.svelte +19 -0
- package/dist/TypeLink.svelte.d.ts +7 -0
- package/dist/TypeLink.svelte.d.ts.map +1 -0
- package/dist/alert.d.ts +7 -0
- package/dist/alert.d.ts.map +1 -0
- package/dist/alert.js +6 -0
- package/dist/api_search.svelte.d.ts +16 -0
- package/dist/api_search.svelte.d.ts.map +1 -0
- package/dist/api_search.svelte.js +61 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +3 -0
- package/dist/context_helpers.d.ts +17 -0
- package/dist/context_helpers.d.ts.map +1 -0
- package/dist/context_helpers.js +19 -0
- package/dist/contextmenu_helpers.d.ts +16 -0
- package/dist/contextmenu_helpers.d.ts.map +1 -0
- package/dist/contextmenu_helpers.js +39 -0
- package/dist/contextmenu_state.svelte.d.ts +152 -0
- package/dist/contextmenu_state.svelte.d.ts.map +1 -0
- package/dist/contextmenu_state.svelte.js +424 -0
- package/dist/csp.d.ts +160 -0
- package/dist/csp.d.ts.map +1 -0
- package/dist/csp.js +354 -0
- package/dist/csp_of_ryanatkn.d.ts +6 -0
- package/dist/csp_of_ryanatkn.d.ts.map +1 -0
- package/dist/csp_of_ryanatkn.js +14 -0
- package/dist/declaration.svelte.d.ts +84 -0
- package/dist/declaration.svelte.d.ts.map +1 -0
- package/dist/declaration.svelte.js +66 -0
- package/dist/declaration_contextmenu.d.ts +4 -0
- package/dist/declaration_contextmenu.d.ts.map +1 -0
- package/dist/declaration_contextmenu.js +14 -0
- package/dist/dialog.d.ts +24 -0
- package/dist/dialog.d.ts.map +1 -0
- package/dist/dialog.js +12 -0
- package/dist/dimensions.svelte.d.ts +5 -0
- package/dist/dimensions.svelte.d.ts.map +1 -0
- package/dist/dimensions.svelte.js +4 -0
- package/dist/docs_helpers.svelte.d.ts +48 -0
- package/dist/docs_helpers.svelte.d.ts.map +1 -0
- package/dist/docs_helpers.svelte.js +99 -0
- package/dist/helpers.d.ts +2 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +16 -0
- package/dist/intersect.svelte.d.ts +47 -0
- package/dist/intersect.svelte.d.ts.map +1 -0
- package/dist/intersect.svelte.js +92 -0
- package/dist/library.svelte.d.ts +197 -0
- package/dist/library.svelte.d.ts.map +1 -0
- package/dist/library.svelte.js +130 -0
- package/dist/library_gen.d.ts +34 -0
- package/dist/library_gen.d.ts.map +1 -0
- package/dist/library_gen.js +123 -0
- package/dist/library_gen_helpers.d.ts +85 -0
- package/dist/library_gen_helpers.d.ts.map +1 -0
- package/dist/library_gen_helpers.js +188 -0
- package/dist/library_helpers.d.ts +54 -0
- package/dist/library_helpers.d.ts.map +1 -0
- package/dist/library_helpers.js +102 -0
- package/dist/logos.d.ts +134 -0
- package/dist/logos.d.ts.map +1 -0
- package/dist/logos.js +281 -0
- package/dist/mdz.d.ts +106 -0
- package/dist/mdz.d.ts.map +1 -0
- package/dist/mdz.js +1481 -0
- package/dist/mdz_components.d.ts +37 -0
- package/dist/mdz_components.d.ts.map +1 -0
- package/dist/mdz_components.js +12 -0
- package/dist/module.svelte.d.ts +47 -0
- package/dist/module.svelte.d.ts.map +1 -0
- package/dist/module.svelte.js +56 -0
- package/dist/module_contextmenu.d.ts +4 -0
- package/dist/module_contextmenu.d.ts.map +1 -0
- package/dist/module_contextmenu.js +14 -0
- package/dist/module_helpers.d.ts +69 -0
- package/dist/module_helpers.d.ts.map +1 -0
- package/dist/module_helpers.js +87 -0
- package/dist/rune_helpers.svelte.d.ts +6 -0
- package/dist/rune_helpers.svelte.d.ts.map +1 -0
- package/dist/rune_helpers.svelte.js +10 -0
- package/dist/storage.d.ts +13 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +43 -0
- package/dist/svelte_helpers.d.ts +37 -0
- package/dist/svelte_helpers.d.ts.map +1 -0
- package/dist/svelte_helpers.js +245 -0
- package/dist/themer.svelte.d.ts +24 -0
- package/dist/themer.svelte.d.ts.map +1 -0
- package/dist/themer.svelte.js +43 -0
- package/dist/tome.d.ts +80 -0
- package/dist/tome.d.ts.map +1 -0
- package/dist/tome.js +27 -0
- package/dist/ts_helpers.d.ts +110 -0
- package/dist/ts_helpers.d.ts.map +1 -0
- package/dist/ts_helpers.js +533 -0
- package/dist/tsdoc_helpers.d.ts +98 -0
- package/dist/tsdoc_helpers.d.ts.map +1 -0
- package/dist/tsdoc_helpers.js +221 -0
- package/package.json +128 -0
- package/src/lib/alert.ts +14 -0
- package/src/lib/api_search.svelte.ts +85 -0
- package/src/lib/constants.ts +3 -0
- package/src/lib/context_helpers.ts +47 -0
- package/src/lib/contextmenu_helpers.ts +63 -0
- package/src/lib/contextmenu_state.svelte.ts +515 -0
- package/src/lib/csp.ts +576 -0
- package/src/lib/csp_of_ryanatkn.ts +16 -0
- package/src/lib/declaration.svelte.ts +102 -0
- package/src/lib/declaration_contextmenu.ts +22 -0
- package/src/lib/dialog.ts +35 -0
- package/src/lib/dimensions.svelte.ts +4 -0
- package/src/lib/docs_helpers.svelte.ts +149 -0
- package/src/lib/helpers.ts +10 -0
- package/src/lib/intersect.svelte.ts +152 -0
- package/src/lib/library.svelte.ts +162 -0
- package/src/lib/library_gen.ts +160 -0
- package/src/lib/library_gen_helpers.ts +262 -0
- package/src/lib/library_helpers.ts +123 -0
- package/src/lib/logos.ts +302 -0
- package/src/lib/mdz.ts +1819 -0
- package/src/lib/mdz_components.ts +34 -0
- package/src/lib/module.svelte.ts +78 -0
- package/src/lib/module_contextmenu.ts +20 -0
- package/src/lib/module_helpers.ts +113 -0
- package/src/lib/rune_helpers.svelte.ts +10 -0
- package/src/lib/storage.ts +48 -0
- package/src/lib/svelte_helpers.ts +303 -0
- package/src/lib/themer.svelte.ts +68 -0
- package/src/lib/tome.ts +38 -0
- package/src/lib/ts_helpers.ts +662 -0
- package/src/lib/tsdoc_helpers.ts +259 -0
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
import { onDestroy } from 'svelte';
|
|
2
|
+
import { is_promise } from '@fuzdev/fuz_util/async.js';
|
|
3
|
+
import { BROWSER } from 'esm-env';
|
|
4
|
+
import { EMPTY_OBJECT } from '@fuzdev/fuz_util/object.js';
|
|
5
|
+
import { Dimensions } from './dimensions.svelte.js';
|
|
6
|
+
import { create_context } from './context_helpers.js';
|
|
7
|
+
import { url_to_root_relative } from './library_helpers.js';
|
|
8
|
+
export class EntryState {
|
|
9
|
+
is_menu = false; // TODO rename to `type`?
|
|
10
|
+
menu;
|
|
11
|
+
run;
|
|
12
|
+
disabled;
|
|
13
|
+
selected = $state(false);
|
|
14
|
+
pending = $state(false);
|
|
15
|
+
error_message = $state(null);
|
|
16
|
+
promise = $state.raw(null);
|
|
17
|
+
constructor(menu, run, disabled = () => false) {
|
|
18
|
+
this.menu = menu;
|
|
19
|
+
this.run = run;
|
|
20
|
+
this.disabled = disabled;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export class SubmenuState {
|
|
24
|
+
is_menu = true;
|
|
25
|
+
menu;
|
|
26
|
+
depth;
|
|
27
|
+
selected = $state(false);
|
|
28
|
+
items = $state.raw([]);
|
|
29
|
+
constructor(menu, depth) {
|
|
30
|
+
this.menu = menu;
|
|
31
|
+
this.depth = depth;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export class RootMenuState {
|
|
35
|
+
is_menu = true;
|
|
36
|
+
menu = null;
|
|
37
|
+
depth = 1;
|
|
38
|
+
items = $state.raw([]);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Creates a `contextmenu` store.
|
|
42
|
+
* See usage with `ContextmenuRoot.svelte` and `Contextmenu.svelte`.
|
|
43
|
+
*
|
|
44
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Element/contextmenu_event
|
|
45
|
+
*/
|
|
46
|
+
export class ContextmenuState {
|
|
47
|
+
layout; // TODO $state?
|
|
48
|
+
/**
|
|
49
|
+
* If an initial layout is provided, control is deferred externally.
|
|
50
|
+
* Otherwise the layout syncs to the page dimensions.
|
|
51
|
+
*/
|
|
52
|
+
has_custom_layout;
|
|
53
|
+
// State for external consumers.
|
|
54
|
+
opened = $state(false);
|
|
55
|
+
x = $state(0);
|
|
56
|
+
y = $state(0);
|
|
57
|
+
params = $state.raw([]);
|
|
58
|
+
error = $state();
|
|
59
|
+
// These arrays use immutable updates (reassignment, not mutation).
|
|
60
|
+
// If you need reactivity, use `$contextmenu` in a reactive statement to react to all changes, and
|
|
61
|
+
// then access the immutable `contextmenu.root_menu` and `contextmenu.selections`.
|
|
62
|
+
// See `ContextmenuEntry.svelte` and `ContextmenuSubmenu.svelte` for reactive usage examples.
|
|
63
|
+
root_menu = new RootMenuState();
|
|
64
|
+
selections = $state.raw([]);
|
|
65
|
+
can_collapse = $derived(this.selections.length > 1);
|
|
66
|
+
can_expand = $derived.by(() => {
|
|
67
|
+
const selected = this.selections.at(-1);
|
|
68
|
+
return !!selected?.is_menu && selected.items.length > 0;
|
|
69
|
+
});
|
|
70
|
+
can_select_next = $derived.by(() => {
|
|
71
|
+
const menu = this.selections.at(-1)?.menu ?? this.root_menu;
|
|
72
|
+
return menu.items.length > 1;
|
|
73
|
+
});
|
|
74
|
+
can_select_previous = $derived.by(() => {
|
|
75
|
+
const menu = this.selections.at(-1)?.menu ?? this.root_menu;
|
|
76
|
+
return menu.items.length > 1;
|
|
77
|
+
});
|
|
78
|
+
can_activate = $derived.by(() => {
|
|
79
|
+
const selected = this.selections.at(-1);
|
|
80
|
+
if (!selected)
|
|
81
|
+
return false;
|
|
82
|
+
if (selected.is_menu)
|
|
83
|
+
return selected.items.length > 0;
|
|
84
|
+
return !selected.disabled();
|
|
85
|
+
});
|
|
86
|
+
constructor(options = EMPTY_OBJECT) {
|
|
87
|
+
const { layout } = options;
|
|
88
|
+
this.has_custom_layout = !!layout;
|
|
89
|
+
this.layout = layout ?? new Dimensions();
|
|
90
|
+
}
|
|
91
|
+
open(params, x, y) {
|
|
92
|
+
this.selections = [];
|
|
93
|
+
this.opened = true;
|
|
94
|
+
this.x = x;
|
|
95
|
+
this.y = y;
|
|
96
|
+
this.params = params;
|
|
97
|
+
}
|
|
98
|
+
close() {
|
|
99
|
+
if (!this.opened)
|
|
100
|
+
return;
|
|
101
|
+
this.reset_items(this.root_menu.items);
|
|
102
|
+
this.opened = false;
|
|
103
|
+
}
|
|
104
|
+
reset_items(items) {
|
|
105
|
+
for (const item of items) {
|
|
106
|
+
if (item.is_menu) {
|
|
107
|
+
this.reset_items(item.items);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
item.promise = null;
|
|
111
|
+
item.pending = false;
|
|
112
|
+
item.error_message = null;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
activate(item) {
|
|
117
|
+
if (item.is_menu) {
|
|
118
|
+
this.expand_selected();
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
if (item.disabled())
|
|
122
|
+
return false;
|
|
123
|
+
let returned;
|
|
124
|
+
try {
|
|
125
|
+
returned = item.run()();
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
const message = typeof error?.message === 'string' ? error.message : undefined;
|
|
129
|
+
item.error_message = message ?? 'unknown error';
|
|
130
|
+
this.error = message;
|
|
131
|
+
}
|
|
132
|
+
if (is_promise(returned)) {
|
|
133
|
+
item.pending = true;
|
|
134
|
+
item.error_message = null;
|
|
135
|
+
const promise = (item.promise = returned
|
|
136
|
+
.then((result) => {
|
|
137
|
+
if (promise !== item.promise)
|
|
138
|
+
return;
|
|
139
|
+
if (typeof result?.ok === 'boolean') {
|
|
140
|
+
if (result.ok) {
|
|
141
|
+
if (result.close !== false) {
|
|
142
|
+
this.close();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
const message = typeof result.message === 'string' ? result.message : undefined;
|
|
147
|
+
item.error_message = message ?? 'unknown error';
|
|
148
|
+
this.error = message;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
// void or undefined - default behavior is to close
|
|
153
|
+
this.close();
|
|
154
|
+
}
|
|
155
|
+
return result;
|
|
156
|
+
}, (err) => {
|
|
157
|
+
if (promise !== item.promise)
|
|
158
|
+
return;
|
|
159
|
+
const message = typeof err?.message === 'string' ? err.message : undefined;
|
|
160
|
+
item.error_message = message ?? 'unknown error';
|
|
161
|
+
this.error = message;
|
|
162
|
+
})
|
|
163
|
+
.finally(() => {
|
|
164
|
+
if (promise !== item.promise)
|
|
165
|
+
return;
|
|
166
|
+
item.pending = false;
|
|
167
|
+
item.promise = null;
|
|
168
|
+
}));
|
|
169
|
+
return item.promise; // async path
|
|
170
|
+
}
|
|
171
|
+
// synchronous path
|
|
172
|
+
if (typeof returned?.ok === 'boolean') {
|
|
173
|
+
if (returned.ok) {
|
|
174
|
+
if (returned.close !== false) {
|
|
175
|
+
this.close();
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
const message = typeof returned.message === 'string' ? returned.message : undefined;
|
|
180
|
+
item.error_message = message ?? 'unknown error';
|
|
181
|
+
this.error = message;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
// void or undefined - default behavior is to close
|
|
186
|
+
this.close();
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
activate_selected() {
|
|
192
|
+
const selected = this.selections.at(-1);
|
|
193
|
+
if (selected) {
|
|
194
|
+
return this.activate(selected);
|
|
195
|
+
}
|
|
196
|
+
this.select_first();
|
|
197
|
+
}
|
|
198
|
+
// Instead of diffing, this does the simple thing and
|
|
199
|
+
// deselects everything and then re-creates the list of selections.
|
|
200
|
+
// Could be improved but it's fine because we're using mutation and the N is very small,
|
|
201
|
+
// and it allows us to have a single code path for the various selection methods.
|
|
202
|
+
/**
|
|
203
|
+
* Activates the selected entry, or if none, selects the first.
|
|
204
|
+
*/
|
|
205
|
+
// TODO implement focus management per APG: call .focus() on the selected item's DOM element (requires storing element refs in EntryState/SubmenuState)
|
|
206
|
+
select(item) {
|
|
207
|
+
if (this.selections.at(-1) === item)
|
|
208
|
+
return;
|
|
209
|
+
for (const s of this.selections)
|
|
210
|
+
s.selected = false;
|
|
211
|
+
const new_selections = [];
|
|
212
|
+
let i = item;
|
|
213
|
+
do {
|
|
214
|
+
i.selected = true;
|
|
215
|
+
new_selections.unshift(i);
|
|
216
|
+
} while ((i = i.menu) && i.menu); // eslint-disable-line @typescript-eslint/no-unnecessary-condition
|
|
217
|
+
this.selections = new_selections;
|
|
218
|
+
}
|
|
219
|
+
collapse_selected() {
|
|
220
|
+
if (!this.can_collapse)
|
|
221
|
+
return;
|
|
222
|
+
const deselected = this.selections.at(-1);
|
|
223
|
+
deselected.selected = false;
|
|
224
|
+
this.selections = this.selections.slice(0, -1);
|
|
225
|
+
}
|
|
226
|
+
expand_selected() {
|
|
227
|
+
if (!this.can_expand)
|
|
228
|
+
return;
|
|
229
|
+
const parent = this.selections.at(-1);
|
|
230
|
+
if (!parent?.is_menu || !parent.items.length)
|
|
231
|
+
return;
|
|
232
|
+
const selected = parent.items[0];
|
|
233
|
+
selected.selected = true;
|
|
234
|
+
this.selections = [...this.selections, selected];
|
|
235
|
+
}
|
|
236
|
+
select_next() {
|
|
237
|
+
if (!this.selections.length) {
|
|
238
|
+
this.select_first();
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
const item = this.selections.at(-1);
|
|
242
|
+
const index = item.menu.items.indexOf(item);
|
|
243
|
+
this.select(item.menu.items[index === item.menu.items.length - 1 ? 0 : index + 1]);
|
|
244
|
+
}
|
|
245
|
+
select_previous() {
|
|
246
|
+
if (!this.selections.length) {
|
|
247
|
+
this.select_last();
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
const item = this.selections.at(-1);
|
|
251
|
+
const index = item.menu.items.indexOf(item);
|
|
252
|
+
this.select(item.menu.items[index === 0 ? item.menu.items.length - 1 : index - 1]);
|
|
253
|
+
}
|
|
254
|
+
select_first() {
|
|
255
|
+
const menu = this.selections.at(-1)?.menu ?? this.root_menu;
|
|
256
|
+
if (!menu.items.length)
|
|
257
|
+
return;
|
|
258
|
+
this.select(menu.items[0]);
|
|
259
|
+
}
|
|
260
|
+
select_last() {
|
|
261
|
+
const { items } = this.selections.at(-1)?.menu ?? this.root_menu;
|
|
262
|
+
this.select(items.at(-1));
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Used by `ContextmenuEntry` and custom entry components
|
|
266
|
+
* @initializes
|
|
267
|
+
*/
|
|
268
|
+
add_entry(run, disabled = () => false) {
|
|
269
|
+
const menu = contextmenu_submenu_context.get_maybe() ?? this.root_menu;
|
|
270
|
+
const entry = new EntryState(menu, run, disabled);
|
|
271
|
+
menu.items = [...menu.items, entry];
|
|
272
|
+
// TODO messy, runs more than needed
|
|
273
|
+
onDestroy(() => {
|
|
274
|
+
menu.items = [];
|
|
275
|
+
});
|
|
276
|
+
return entry;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* @initializes
|
|
280
|
+
*/
|
|
281
|
+
add_submenu() {
|
|
282
|
+
const menu = contextmenu_submenu_context.get_maybe() ?? this.root_menu;
|
|
283
|
+
const submenu = new SubmenuState(menu, menu.depth + 1);
|
|
284
|
+
menu.items = [...menu.items, submenu];
|
|
285
|
+
contextmenu_submenu_context.set(submenu);
|
|
286
|
+
// TODO messy, runs more than needed
|
|
287
|
+
onDestroy(() => {
|
|
288
|
+
menu.items = [];
|
|
289
|
+
});
|
|
290
|
+
return submenu;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
// The dataset key must not have capital letters or dashes or it'll differ between JS and DOM:
|
|
294
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset
|
|
295
|
+
const CONTEXTMENU_DATASET_KEY = 'contextmenu';
|
|
296
|
+
const CONTEXTMENU_DOM_QUERY = `a,[data-${CONTEXTMENU_DATASET_KEY}]`;
|
|
297
|
+
const contextmenu_cache = new Map();
|
|
298
|
+
let cache_key_counter = 0;
|
|
299
|
+
/**
|
|
300
|
+
* Creates an attachment that sets up contextmenu behavior on an element.
|
|
301
|
+
* @param params Contextmenu parameters or nullish to disable
|
|
302
|
+
*/
|
|
303
|
+
export const contextmenu_attachment = (params) => (el) => {
|
|
304
|
+
// TODO could clean up the dataset attr, maybe use a weakmap?
|
|
305
|
+
if (params == null)
|
|
306
|
+
return;
|
|
307
|
+
// Only create key once per element, reuse on updates
|
|
308
|
+
let key = el.dataset[CONTEXTMENU_DATASET_KEY];
|
|
309
|
+
if (!key) {
|
|
310
|
+
key = cache_key_counter++ + '';
|
|
311
|
+
el.dataset[CONTEXTMENU_DATASET_KEY] = key;
|
|
312
|
+
}
|
|
313
|
+
contextmenu_cache.set(key, params);
|
|
314
|
+
return () => {
|
|
315
|
+
contextmenu_cache.delete(key);
|
|
316
|
+
};
|
|
317
|
+
};
|
|
318
|
+
const CONTEXTMENU_OPEN_VIBRATE_DURATION = 17;
|
|
319
|
+
/**
|
|
320
|
+
* Opens the contextmenu, if appropriate,
|
|
321
|
+
* querying the menu items from the DOM starting at the event target.
|
|
322
|
+
* @param target the leaf element from which to open the contextmenu
|
|
323
|
+
* @param x the page X coordinate at which to open the contextmenu, typically the mouse `pageX`
|
|
324
|
+
* @param y the page Y coordinate at which to open the contextmenu, typically the mouse `pageY`
|
|
325
|
+
* @param contextmenu the contextmenu store
|
|
326
|
+
* @param options optional configuration for filtering entries and haptic feedback
|
|
327
|
+
* @returns a boolean indicating if the menu was opened or not
|
|
328
|
+
*/
|
|
329
|
+
export const contextmenu_open = (target, x, y, contextmenu, options) => {
|
|
330
|
+
const { link_enabled = true, text_enabled = true, separator_enabled = true, vibrate = true, } = options ?? EMPTY_OBJECT;
|
|
331
|
+
const params = contextmenu_query_params(target)?.filter((p) => typeof p === 'function' ||
|
|
332
|
+
((p.snippet !== 'link' || link_enabled) &&
|
|
333
|
+
(p.snippet !== 'text' || text_enabled) &&
|
|
334
|
+
(p.snippet !== 'separator' || separator_enabled)));
|
|
335
|
+
// No-op if empty
|
|
336
|
+
if (!params?.length)
|
|
337
|
+
return false;
|
|
338
|
+
contextmenu.open(params, x, y);
|
|
339
|
+
// `navigator.vibrate()` works with `ContextmenuRoot` but gets blocked by some browsers
|
|
340
|
+
// when used with `ContextmenuRootForSafariCompatibility` because its longpress
|
|
341
|
+
// workaround triggers from a timeout rather than a direct user interaction.
|
|
342
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
343
|
+
if (BROWSER && vibrate && navigator.vibrate) {
|
|
344
|
+
navigator.vibrate(CONTEXTMENU_OPEN_VIBRATE_DURATION);
|
|
345
|
+
}
|
|
346
|
+
return true;
|
|
347
|
+
};
|
|
348
|
+
const contextmenu_query_params = (target) => {
|
|
349
|
+
let params = null;
|
|
350
|
+
// crawl DOM for contextmenu entries
|
|
351
|
+
let el = target;
|
|
352
|
+
let cache_key, cached;
|
|
353
|
+
while ((el = el?.closest(CONTEXTMENU_DOM_QUERY))) {
|
|
354
|
+
if ((cache_key = el.dataset[CONTEXTMENU_DATASET_KEY])) {
|
|
355
|
+
params ??= [];
|
|
356
|
+
cached = contextmenu_cache.get(cache_key);
|
|
357
|
+
if (cached === undefined) {
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
// preserve bubbling order
|
|
361
|
+
if (Array.isArray(cached)) {
|
|
362
|
+
(params ??= []).push(...cached);
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
(params ??= []).push(cached);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
if (el.tagName === 'A') {
|
|
369
|
+
(params ??= []).push({
|
|
370
|
+
snippet: 'link',
|
|
371
|
+
// anchor elements have the full url, but we want the slash-prefixed/absolute/root-relative version
|
|
372
|
+
props: { href: url_to_root_relative(el.href) },
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
el = el.parentElement;
|
|
376
|
+
}
|
|
377
|
+
// add "copy text" entry if anything is selected and we have any other entries
|
|
378
|
+
if (params) {
|
|
379
|
+
const text = window.getSelection()?.toString();
|
|
380
|
+
if (text) {
|
|
381
|
+
params.unshift({
|
|
382
|
+
snippet: 'text',
|
|
383
|
+
props: {
|
|
384
|
+
content: 'copy text',
|
|
385
|
+
icon: '📋',
|
|
386
|
+
run: async () => {
|
|
387
|
+
await navigator.clipboard.writeText(text);
|
|
388
|
+
},
|
|
389
|
+
},
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
return params;
|
|
394
|
+
};
|
|
395
|
+
export const contextmenu_context = create_context();
|
|
396
|
+
export const contextmenu_submenu_context = create_context();
|
|
397
|
+
export const contextmenu_dimensions_context = create_context(() => new Dimensions());
|
|
398
|
+
// Global registry of non-scoped contextmenu roots (only used in DEV)
|
|
399
|
+
const non_scoped_roots = new Set();
|
|
400
|
+
/**
|
|
401
|
+
* Registers a contextmenu root and warns if multiple non-scoped roots are detected.
|
|
402
|
+
* Only active in development mode. Automatically handles cleanup on unmount.
|
|
403
|
+
*
|
|
404
|
+
* @param get_scoped Getter function that returns the current scoped value
|
|
405
|
+
*/
|
|
406
|
+
export const contextmenu_check_global_root = (get_scoped) => {
|
|
407
|
+
$effect(() => {
|
|
408
|
+
const id = Symbol('contextmenu_root');
|
|
409
|
+
if (!get_scoped()) {
|
|
410
|
+
// Register as global (non-scoped)
|
|
411
|
+
non_scoped_roots.add(id);
|
|
412
|
+
if (non_scoped_roots.size > 1) {
|
|
413
|
+
// eslint-disable-next-line no-console
|
|
414
|
+
console.error(`Detected multiple non-scoped contextmenu roots (${non_scoped_roots.size} mounted). ` +
|
|
415
|
+
'Only one global contextmenu root should be active at a time. ' +
|
|
416
|
+
'Are you missing a `scoped` attribute?');
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
// Cleanup: unregister when scoped changes or component unmounts
|
|
420
|
+
return () => {
|
|
421
|
+
non_scoped_roots.delete(id);
|
|
422
|
+
};
|
|
423
|
+
});
|
|
424
|
+
};
|
package/dist/csp.d.ts
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import type { ArrayElement, Defined } from '@fuzdev/fuz_util/types.js';
|
|
2
|
+
export interface CreateCspDirectivesOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Override or transform specific directives.
|
|
5
|
+
* Returning `null` or `undefined` from a transform function will remove the directive.
|
|
6
|
+
*/
|
|
7
|
+
directives?: {
|
|
8
|
+
[K in CspDirective]?: CspDirectiveValue<K> | null | ((value: CspDirectiveValue<K>) => CspDirectiveValue<K> | null);
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Sources to include based on their trust levels.
|
|
12
|
+
*/
|
|
13
|
+
trusted_sources?: Array<CspSourceSpec>;
|
|
14
|
+
/**
|
|
15
|
+
* Override default values for specific directives,
|
|
16
|
+
* merging with `value_defaults_base` (or replacing if that directive is null in the base).
|
|
17
|
+
*/
|
|
18
|
+
value_defaults?: Partial<typeof csp_directive_value_defaults>;
|
|
19
|
+
/**
|
|
20
|
+
* Base values for directive defaults.
|
|
21
|
+
* Set to `null` or `{}` to start with no defaults.
|
|
22
|
+
* Defaults to `csp_directive_value_defaults`.
|
|
23
|
+
*/
|
|
24
|
+
value_defaults_base?: Partial<typeof csp_directive_value_defaults> | null;
|
|
25
|
+
/**
|
|
26
|
+
* Override trust requirements for specific directives,
|
|
27
|
+
* merging with `required_trust_defaults_base` (or replacing if that directive is null in the base).
|
|
28
|
+
*/
|
|
29
|
+
required_trust_defaults?: Partial<typeof csp_directive_required_trust_defaults>;
|
|
30
|
+
/**
|
|
31
|
+
* Base values for directive trust requirements.
|
|
32
|
+
* Set to `null` or `{}` to start with no trust requirements.
|
|
33
|
+
* Defaults to `csp_directive_required_trust_defaults`.
|
|
34
|
+
*/
|
|
35
|
+
required_trust_defaults_base?: Partial<typeof csp_directive_required_trust_defaults> | null;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* This is designed for compatibility with SvelteKit
|
|
39
|
+
* and maps to the `KitConfig` `directives` option.
|
|
40
|
+
* The goal is to provide an ergonomic, modern, and safe API
|
|
41
|
+
* for Content Security Policy (CSP) creation
|
|
42
|
+
* that's simple to write and audit, and isn't error-prone.
|
|
43
|
+
*
|
|
44
|
+
* Things like validation and rendering to a string
|
|
45
|
+
* are out of scope and left to SvelteKit.
|
|
46
|
+
*/
|
|
47
|
+
export declare function create_csp_directives(options?: CreateCspDirectivesOptions): CspDirectives;
|
|
48
|
+
export type CspDirective = keyof CspDirectives;
|
|
49
|
+
export declare const parse_csp_directive: (directive: unknown) => CspDirective | null;
|
|
50
|
+
export type CspDirectiveValue<T extends CspDirective> = Defined<CspDirectives[T]>;
|
|
51
|
+
export declare const csp_trust_levels: readonly ["low", "medium", "high"];
|
|
52
|
+
/**
|
|
53
|
+
* Numeric values for CSP trust levels, `csp_trust_levels`.
|
|
54
|
+
* Lower is less trusted.
|
|
55
|
+
* Includes `undefined` in the type for safety.
|
|
56
|
+
*/
|
|
57
|
+
export declare const csp_trust_level_value: Record<CspTrustLevel, number | undefined>;
|
|
58
|
+
/**
|
|
59
|
+
* Trust levels for CSP sources.
|
|
60
|
+
*
|
|
61
|
+
* With the base defaults, trust levels roughly correspond to:
|
|
62
|
+
*
|
|
63
|
+
* - `low` – Passive resources only (no script execution, no styling or UI control).
|
|
64
|
+
* Examples: `img-src`, `font-src`.
|
|
65
|
+
* - `medium` – Content that may affect layout, styling, or embed external browsing contexts,
|
|
66
|
+
* but cannot directly run code in the page's JS execution environment or
|
|
67
|
+
* perform other high-risk actions. Examples: `style-src`, `frame-src`, `frame-ancestors`.
|
|
68
|
+
* - `high` – Sources that can execute code in the page's context or open powerful network
|
|
69
|
+
* channels. Examples: `script-src`, `connect-src`, `child-src`.
|
|
70
|
+
* - `null` – No trust. This is used for directives that don't support sources.
|
|
71
|
+
*
|
|
72
|
+
*/
|
|
73
|
+
export type CspTrustLevel = ArrayElement<typeof csp_trust_levels>;
|
|
74
|
+
/**
|
|
75
|
+
* Validates and extracts a CSP trust level from an unknown value.
|
|
76
|
+
*/
|
|
77
|
+
export declare const parse_csp_trust_level: (trust: unknown) => CspTrustLevel | null;
|
|
78
|
+
export interface CspSourceSpec {
|
|
79
|
+
source: CspSource;
|
|
80
|
+
trust?: CspTrustLevel;
|
|
81
|
+
directives?: Array<CspDirective>;
|
|
82
|
+
}
|
|
83
|
+
export interface CspDirectiveSpec {
|
|
84
|
+
name: CspDirective;
|
|
85
|
+
fallback: Array<CspDirective> | null;
|
|
86
|
+
fallback_of: Array<CspDirective> | null;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Determines if a granted trust level is sufficient to satisfy a required trust level.
|
|
90
|
+
*
|
|
91
|
+
* Trust levels have the following hierarchy:
|
|
92
|
+
* - 'high' sources can be used in high, medium, and low trust directives (highest privilege)
|
|
93
|
+
* - 'medium' sources can be used in medium and low trust directives
|
|
94
|
+
* - 'low' sources can only be used in low trust directives (lowest privilege)
|
|
95
|
+
*/
|
|
96
|
+
export declare const is_csp_trusted: (required_trust: CspTrustLevel | null | undefined, granted_trust: CspTrustLevel | null | undefined) => boolean;
|
|
97
|
+
export declare const COLOR_SCHEME_SCRIPT_HASH = "sha256-QOxqn7EUzb3ydF9SALJoJGWSvywW9R0AfTDSenB83Z8=";
|
|
98
|
+
/**
|
|
99
|
+
* The base CSP directive defaults.
|
|
100
|
+
* Prioritizes safety but loosens around media and styles, relying on defense-in-depth.
|
|
101
|
+
* Customizable via `CreateCspDirectivesOptions.defaults`.
|
|
102
|
+
*/
|
|
103
|
+
export declare const csp_directive_value_defaults: Record<CspDirective, CspDirectiveValue<CspDirective> | null>;
|
|
104
|
+
/**
|
|
105
|
+
* Sources that meet this trust requirement are included for it by default.
|
|
106
|
+
* If null, no trusted sources are added to the directive automatically.
|
|
107
|
+
* Directives that don't support sources or default to `['none']` are null.
|
|
108
|
+
*
|
|
109
|
+
* Feedback is welcome, please see the issues - https://github.com/ryanatkn/fuz/issues
|
|
110
|
+
*/
|
|
111
|
+
export declare const csp_directive_required_trust_defaults: Record<CspDirective, CspTrustLevel | null>;
|
|
112
|
+
/**
|
|
113
|
+
* Static data descriptors for the CSP directives.
|
|
114
|
+
* Fuz excludes deprecated directives, so those are intentionally omitted,
|
|
115
|
+
* but any newer missing directives are bugs.
|
|
116
|
+
*
|
|
117
|
+
* Could be moved to `csp.ts` but is currently here to keep that module smaller.
|
|
118
|
+
*
|
|
119
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy
|
|
120
|
+
*/
|
|
121
|
+
export declare const csp_directive_specs: Array<CspDirectiveSpec>;
|
|
122
|
+
export declare const csp_directive_spec_by_name: Map<CspDirective, CspDirectiveSpec>;
|
|
123
|
+
export type CspActionSource = 'strict-dynamic' | 'report-sample';
|
|
124
|
+
export type CspBaseSource = 'self' | 'unsafe-eval' | 'unsafe-hashes' | 'unsafe-inline' | 'wasm-unsafe-eval' | 'none';
|
|
125
|
+
export type CspCryptoSource = `${'nonce' | 'sha256' | 'sha384' | 'sha512'}-${string}`;
|
|
126
|
+
export type CspFrameSource = CspHostSource | CspSchemeSource | 'self' | 'none';
|
|
127
|
+
export type CspHostNameScheme = `${string}.${string}` | 'localhost';
|
|
128
|
+
export type CspHostSource = `${CspHostProtocolSchemes}${CspHostNameScheme}${CspPortScheme}`;
|
|
129
|
+
export type CspHostProtocolSchemes = `${string}://` | '';
|
|
130
|
+
export type CspPortScheme = `:${number}` | '' | ':*';
|
|
131
|
+
export type CspSchemeSource = 'http:' | 'https:' | 'data:' | 'mediastream:' | 'blob:' | 'filesystem:';
|
|
132
|
+
export type CspSource = CspHostSource | CspSchemeSource | CspCryptoSource | CspBaseSource;
|
|
133
|
+
export type CspSources = Array<CspSource>;
|
|
134
|
+
export interface CspDirectives {
|
|
135
|
+
'default-src'?: Array<CspSource | CspActionSource>;
|
|
136
|
+
'script-src'?: Array<CspSource | CspActionSource>;
|
|
137
|
+
'script-src-elem'?: CspSources;
|
|
138
|
+
'script-src-attr'?: CspSources;
|
|
139
|
+
'style-src'?: Array<CspSource | CspActionSource>;
|
|
140
|
+
'style-src-elem'?: CspSources;
|
|
141
|
+
'style-src-attr'?: CspSources;
|
|
142
|
+
'img-src'?: CspSources;
|
|
143
|
+
'media-src'?: CspSources;
|
|
144
|
+
'font-src'?: CspSources;
|
|
145
|
+
'manifest-src'?: CspSources;
|
|
146
|
+
'child-src'?: CspSources;
|
|
147
|
+
'connect-src'?: CspSources;
|
|
148
|
+
'frame-src'?: CspSources;
|
|
149
|
+
'frame-ancestors'?: Array<CspFrameSource>;
|
|
150
|
+
'form-action'?: Array<CspSource | CspActionSource>;
|
|
151
|
+
'worker-src'?: CspSources;
|
|
152
|
+
'object-src'?: CspSources;
|
|
153
|
+
'base-uri'?: Array<CspSource | CspActionSource>;
|
|
154
|
+
'upgrade-insecure-requests'?: boolean;
|
|
155
|
+
'report-to'?: Array<string>;
|
|
156
|
+
'require-trusted-types-for'?: Array<'script'>;
|
|
157
|
+
'trusted-types'?: Array<'none' | 'allow-duplicates' | '*' | string>;
|
|
158
|
+
sandbox?: Array<'allow-downloads-without-user-activation' | 'allow-forms' | 'allow-modals' | 'allow-orientation-lock' | 'allow-pointer-lock' | 'allow-popups' | 'allow-popups-to-escape-sandbox' | 'allow-presentation' | 'allow-same-origin' | 'allow-scripts' | 'allow-storage-access-by-user-activation' | 'allow-top-navigation' | 'allow-top-navigation-by-user-activation'>;
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=csp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csp.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/csp.ts"],"names":[],"mappings":"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"}
|