@gjermundgaraba/pixel-paper 0.1.1 → 0.2.1
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/README.md +11 -1
- package/THIRD_PARTY_NOTICES.md +25 -0
- package/dist/board/board.d.ts +12 -12
- package/dist/copy-button/copy-button.d.ts +4 -4
- package/dist/index.d.ts +44 -43
- package/dist/index.js +2 -1
- package/dist/inline-input/inline-input.d.ts +6 -6
- package/dist/markdown-editor/element.d.ts +4 -0
- package/dist/markdown-editor/element.js +128 -0
- package/dist/markdown-editor/engine.js +94 -0
- package/dist/markdown-editor/index.d.ts +5 -0
- package/dist/markdown-editor/index.js +6 -0
- package/dist/markdown-editor/link-policy.js +18 -0
- package/dist/markdown-editor/live/live.js +438 -0
- package/dist/markdown-editor/live/theme.js +117 -0
- package/dist/markdown-editor/markdown-editor.d.ts +11 -0
- package/dist/markdown-editor/markdown-editor.js +22 -0
- package/dist/markdown-editor/reconcile.js +24 -0
- package/dist/menu/menu.d.ts +4 -4
- package/dist/sortable/sortable.d.ts +12 -12
- package/dist/toast/toast.d.ts +8 -8
- package/package.json +16 -2
- package/src/pixel-paper.css +46 -0
package/README.md
CHANGED
|
@@ -46,6 +46,16 @@ export default defineConfig({
|
|
|
46
46
|
|
|
47
47
|
Provide `Clipboard.layer` as the application's resources where a component copies.
|
|
48
48
|
|
|
49
|
+
`MarkdownEditor.view` edits Markdown in place, and needs its element registered once, from the client entry, before the first render:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import { defineMarkdownEditorElement } from "@gjermundgaraba/pixel-paper/markdown-editor/element";
|
|
53
|
+
|
|
54
|
+
defineMarkdownEditorElement();
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Only that subpath loads CodeMirror, so an application that never imports it pays nothing and shows a plain textarea. Links open with Ctrl or Cmd and a click, or Ctrl or Cmd and Enter at the caret. A disabled fieldset makes the editor read-only.
|
|
58
|
+
|
|
49
59
|
## Licence
|
|
50
60
|
|
|
51
|
-
MIT. Departure Mono, in `fonts/`, carries its own licence beside it.
|
|
61
|
+
MIT. Departure Mono, in `fonts/`, carries its own licence beside it. `THIRD_PARTY_NOTICES.md` carries the licence of the Markdown editor's live layer.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Third-party notices
|
|
2
|
+
|
|
3
|
+
The files in `src/markdown-editor/live/` derive from [cm-live-markdown](https://github.com/Jason1258t/cm-live-markdown), tag `v0.1.7`, commit `89166b7`, under the MIT licence below.
|
|
4
|
+
|
|
5
|
+
MIT License
|
|
6
|
+
|
|
7
|
+
Copyright (c) 2026 Jason
|
|
8
|
+
|
|
9
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
10
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
11
|
+
in the Software without restriction, including without limitation the rights
|
|
12
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
13
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
14
|
+
furnished to do so, subject to the following conditions:
|
|
15
|
+
|
|
16
|
+
The above copyright notice and this permission notice shall be included in all
|
|
17
|
+
copies or substantial portions of the Software.
|
|
18
|
+
|
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
20
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
21
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
22
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
23
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
24
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
25
|
+
SOFTWARE.
|
package/dist/board/board.d.ts
CHANGED
|
@@ -271,6 +271,8 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
271
271
|
}>;
|
|
272
272
|
};
|
|
273
273
|
commands?: Update.Commands<{
|
|
274
|
+
readonly _tag: "PressedEscape";
|
|
275
|
+
} | {
|
|
274
276
|
readonly _tag: "CompletedAnnounceMove";
|
|
275
277
|
} | {
|
|
276
278
|
readonly _tag: "CompletedSizeLiftedCard";
|
|
@@ -333,8 +335,6 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
333
335
|
readonly label: string;
|
|
334
336
|
}[];
|
|
335
337
|
}[];
|
|
336
|
-
} | {
|
|
337
|
-
readonly _tag: "PressedEscape";
|
|
338
338
|
} | {
|
|
339
339
|
readonly _tag: "PressedGripKey";
|
|
340
340
|
readonly cardId: string;
|
|
@@ -430,6 +430,8 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
430
430
|
}>;
|
|
431
431
|
}>;
|
|
432
432
|
}, {
|
|
433
|
+
readonly _tag: "PressedEscape";
|
|
434
|
+
} | {
|
|
433
435
|
readonly _tag: "CompletedAnnounceMove";
|
|
434
436
|
} | {
|
|
435
437
|
readonly _tag: "CompletedSizeLiftedCard";
|
|
@@ -492,8 +494,6 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
492
494
|
readonly label: string;
|
|
493
495
|
}[];
|
|
494
496
|
}[];
|
|
495
|
-
} | {
|
|
496
|
-
readonly _tag: "PressedEscape";
|
|
497
497
|
} | {
|
|
498
498
|
readonly _tag: "PressedGripKey";
|
|
499
499
|
readonly cardId: string;
|
|
@@ -572,6 +572,8 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
572
572
|
}>;
|
|
573
573
|
}>;
|
|
574
574
|
}, {
|
|
575
|
+
readonly _tag: "PressedEscape";
|
|
576
|
+
} | {
|
|
575
577
|
readonly _tag: "CompletedAnnounceMove";
|
|
576
578
|
} | {
|
|
577
579
|
readonly _tag: "CompletedSizeLiftedCard";
|
|
@@ -634,8 +636,6 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
634
636
|
readonly label: string;
|
|
635
637
|
}[];
|
|
636
638
|
}[];
|
|
637
|
-
} | {
|
|
638
|
-
readonly _tag: "PressedEscape";
|
|
639
639
|
} | {
|
|
640
640
|
readonly _tag: "PressedGripKey";
|
|
641
641
|
readonly cardId: string;
|
|
@@ -714,6 +714,8 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
714
714
|
}>;
|
|
715
715
|
}>;
|
|
716
716
|
}, {
|
|
717
|
+
readonly _tag: "PressedEscape";
|
|
718
|
+
} | {
|
|
717
719
|
readonly _tag: "CompletedAnnounceMove";
|
|
718
720
|
} | {
|
|
719
721
|
readonly _tag: "CompletedSizeLiftedCard";
|
|
@@ -776,8 +778,6 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
776
778
|
readonly label: string;
|
|
777
779
|
}[];
|
|
778
780
|
}[];
|
|
779
|
-
} | {
|
|
780
|
-
readonly _tag: "PressedEscape";
|
|
781
781
|
} | {
|
|
782
782
|
readonly _tag: "PressedGripKey";
|
|
783
783
|
readonly cardId: string;
|
|
@@ -855,6 +855,8 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
855
855
|
}>;
|
|
856
856
|
}>;
|
|
857
857
|
}, {
|
|
858
|
+
readonly _tag: "PressedEscape";
|
|
859
|
+
} | {
|
|
858
860
|
readonly _tag: "CompletedAnnounceMove";
|
|
859
861
|
} | {
|
|
860
862
|
readonly _tag: "CompletedSizeLiftedCard";
|
|
@@ -917,8 +919,6 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
917
919
|
readonly label: string;
|
|
918
920
|
}[];
|
|
919
921
|
}[];
|
|
920
|
-
} | {
|
|
921
|
-
readonly _tag: "PressedEscape";
|
|
922
922
|
} | {
|
|
923
923
|
readonly _tag: "PressedGripKey";
|
|
924
924
|
readonly cardId: string;
|
|
@@ -1065,6 +1065,8 @@ export declare const view: import("foldkit/submodel").View<{
|
|
|
1065
1065
|
}>;
|
|
1066
1066
|
}>;
|
|
1067
1067
|
}, {
|
|
1068
|
+
readonly _tag: "PressedEscape";
|
|
1069
|
+
} | {
|
|
1068
1070
|
readonly _tag: "CompletedAnnounceMove";
|
|
1069
1071
|
} | {
|
|
1070
1072
|
readonly _tag: "CompletedSizeLiftedCard";
|
|
@@ -1127,8 +1129,6 @@ export declare const view: import("foldkit/submodel").View<{
|
|
|
1127
1129
|
readonly label: string;
|
|
1128
1130
|
}[];
|
|
1129
1131
|
}[];
|
|
1130
|
-
} | {
|
|
1131
|
-
readonly _tag: "PressedEscape";
|
|
1132
1132
|
} | {
|
|
1133
1133
|
readonly _tag: "PressedGripKey";
|
|
1134
1134
|
readonly cardId: string;
|
|
@@ -38,11 +38,11 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
38
38
|
model: {
|
|
39
39
|
readonly id: string;
|
|
40
40
|
readonly state: {
|
|
41
|
+
readonly _tag: "Idle";
|
|
42
|
+
} | {
|
|
41
43
|
readonly _tag: "Copied";
|
|
42
44
|
} | {
|
|
43
45
|
readonly _tag: "Copying";
|
|
44
|
-
} | {
|
|
45
|
-
readonly _tag: "Idle";
|
|
46
46
|
};
|
|
47
47
|
};
|
|
48
48
|
commands?: Update.Commands<{
|
|
@@ -74,11 +74,11 @@ export type ViewInputs = Readonly<{
|
|
|
74
74
|
export declare const view: import("foldkit/submodel").View<{
|
|
75
75
|
readonly id: string;
|
|
76
76
|
readonly state: {
|
|
77
|
+
readonly _tag: "Idle";
|
|
78
|
+
} | {
|
|
77
79
|
readonly _tag: "Copied";
|
|
78
80
|
} | {
|
|
79
81
|
readonly _tag: "Copying";
|
|
80
|
-
} | {
|
|
81
|
-
readonly _tag: "Idle";
|
|
82
82
|
};
|
|
83
83
|
}, {
|
|
84
84
|
readonly _tag: "FailedCopyText";
|
package/dist/index.d.ts
CHANGED
|
@@ -40,46 +40,47 @@ import { index_d_exports as index_d_exports$38 } from "./link-state/index.js";
|
|
|
40
40
|
import { index_d_exports as index_d_exports$39 } from "./live-region/index.js";
|
|
41
41
|
import { index_d_exports as index_d_exports$40 } from "./loading/index.js";
|
|
42
42
|
import { index_d_exports as index_d_exports$41 } from "./mark/index.js";
|
|
43
|
-
import { index_d_exports as index_d_exports$42 } from "./
|
|
44
|
-
import { index_d_exports as index_d_exports$43 } from "./
|
|
45
|
-
import { index_d_exports as index_d_exports$44 } from "./
|
|
46
|
-
import { index_d_exports as index_d_exports$45 } from "./
|
|
47
|
-
import { index_d_exports as index_d_exports$46 } from "./
|
|
48
|
-
import { index_d_exports as index_d_exports$47 } from "./
|
|
49
|
-
import { index_d_exports as index_d_exports$48 } from "./
|
|
50
|
-
import { index_d_exports as index_d_exports$49 } from "./
|
|
51
|
-
import { index_d_exports as index_d_exports$50 } from "./
|
|
52
|
-
import { index_d_exports as index_d_exports$51 } from "./
|
|
53
|
-
import { index_d_exports as index_d_exports$52 } from "./
|
|
54
|
-
import { index_d_exports as index_d_exports$53 } from "./
|
|
55
|
-
import { index_d_exports as index_d_exports$54 } from "./
|
|
56
|
-
import { index_d_exports as index_d_exports$55 } from "./
|
|
57
|
-
import { index_d_exports as index_d_exports$56 } from "./
|
|
58
|
-
import { index_d_exports as index_d_exports$57 } from "./
|
|
59
|
-
import { index_d_exports as index_d_exports$58 } from "./
|
|
60
|
-
import { index_d_exports as index_d_exports$59 } from "./
|
|
61
|
-
import { index_d_exports as index_d_exports$60 } from "./
|
|
62
|
-
import { index_d_exports as index_d_exports$61 } from "./
|
|
63
|
-
import { index_d_exports as index_d_exports$62 } from "./
|
|
64
|
-
import { index_d_exports as index_d_exports$63 } from "./
|
|
65
|
-
import { index_d_exports as index_d_exports$64 } from "./
|
|
66
|
-
import { index_d_exports as index_d_exports$65 } from "./
|
|
67
|
-
import { index_d_exports as index_d_exports$66 } from "./
|
|
68
|
-
import { index_d_exports as index_d_exports$67 } from "./
|
|
69
|
-
import { index_d_exports as index_d_exports$68 } from "./
|
|
70
|
-
import { index_d_exports as index_d_exports$69 } from "./
|
|
71
|
-
import { index_d_exports as index_d_exports$70 } from "./
|
|
72
|
-
import { index_d_exports as index_d_exports$71 } from "./
|
|
73
|
-
import { index_d_exports as index_d_exports$72 } from "./
|
|
74
|
-
import { index_d_exports as index_d_exports$
|
|
75
|
-
import { index_d_exports as index_d_exports$
|
|
76
|
-
import { index_d_exports as index_d_exports$
|
|
77
|
-
import { index_d_exports as index_d_exports$76 } from "./
|
|
78
|
-
import { index_d_exports as index_d_exports$77 } from "./
|
|
79
|
-
import { index_d_exports as index_d_exports$78 } from "./
|
|
80
|
-
import { index_d_exports as index_d_exports$79 } from "./
|
|
81
|
-
import { index_d_exports as index_d_exports$80 } from "./
|
|
82
|
-
import { index_d_exports as index_d_exports$81 } from "./
|
|
83
|
-
import { index_d_exports as index_d_exports$82 } from "./
|
|
84
|
-
import { index_d_exports as index_d_exports$83 } from "./
|
|
85
|
-
|
|
43
|
+
import { index_d_exports as index_d_exports$42 } from "./markdown-editor/index.js";
|
|
44
|
+
import { index_d_exports as index_d_exports$43 } from "./menu/index.js";
|
|
45
|
+
import { index_d_exports as index_d_exports$44 } from "./meter/index.js";
|
|
46
|
+
import { index_d_exports as index_d_exports$45 } from "./nav-strip/index.js";
|
|
47
|
+
import { index_d_exports as index_d_exports$46 } from "./notice/index.js";
|
|
48
|
+
import { index_d_exports as index_d_exports$47 } from "./outcome/index.js";
|
|
49
|
+
import { index_d_exports as index_d_exports$48 } from "./page-head/index.js";
|
|
50
|
+
import { index_d_exports as index_d_exports$49 } from "./panel/index.js";
|
|
51
|
+
import { index_d_exports as index_d_exports$50 } from "./password-field/index.js";
|
|
52
|
+
import { index_d_exports as index_d_exports$51 } from "./places/index.js";
|
|
53
|
+
import { index_d_exports as index_d_exports$52 } from "./props-list/index.js";
|
|
54
|
+
import { index_d_exports as index_d_exports$53 } from "./prose/index.js";
|
|
55
|
+
import { index_d_exports as index_d_exports$54 } from "./query-chip/index.js";
|
|
56
|
+
import { index_d_exports as index_d_exports$55 } from "./radio-choices/index.js";
|
|
57
|
+
import { index_d_exports as index_d_exports$56 } from "./rail/index.js";
|
|
58
|
+
import { index_d_exports as index_d_exports$57 } from "./reel/index.js";
|
|
59
|
+
import { index_d_exports as index_d_exports$58 } from "./remote/index.js";
|
|
60
|
+
import { index_d_exports as index_d_exports$59 } from "./rows/index.js";
|
|
61
|
+
import { index_d_exports as index_d_exports$60 } from "./scheme/index.js";
|
|
62
|
+
import { index_d_exports as index_d_exports$61 } from "./secret/index.js";
|
|
63
|
+
import { index_d_exports as index_d_exports$62 } from "./segmented/index.js";
|
|
64
|
+
import { index_d_exports as index_d_exports$63 } from "./select-field/index.js";
|
|
65
|
+
import { index_d_exports as index_d_exports$64 } from "./sheet/index.js";
|
|
66
|
+
import { index_d_exports as index_d_exports$65 } from "./skip-link/index.js";
|
|
67
|
+
import { index_d_exports as index_d_exports$66 } from "./sortable/index.js";
|
|
68
|
+
import { index_d_exports as index_d_exports$67 } from "./stack/index.js";
|
|
69
|
+
import { index_d_exports as index_d_exports$68 } from "./stage/index.js";
|
|
70
|
+
import { index_d_exports as index_d_exports$69 } from "./stat/index.js";
|
|
71
|
+
import { index_d_exports as index_d_exports$70 } from "./status-bar/index.js";
|
|
72
|
+
import { index_d_exports as index_d_exports$71 } from "./table/index.js";
|
|
73
|
+
import { index_d_exports as index_d_exports$72 } from "./tabs/index.js";
|
|
74
|
+
import { index_d_exports as index_d_exports$73 } from "./tag/index.js";
|
|
75
|
+
import { index_d_exports as index_d_exports$75 } from "./textarea-field/index.js";
|
|
76
|
+
import { index_d_exports as index_d_exports$74 } from "./text-button/index.js";
|
|
77
|
+
import { index_d_exports as index_d_exports$76 } from "./time/index.js";
|
|
78
|
+
import { index_d_exports as index_d_exports$77 } from "./tips/index.js";
|
|
79
|
+
import { index_d_exports as index_d_exports$78 } from "./toast/index.js";
|
|
80
|
+
import { index_d_exports as index_d_exports$79 } from "./toc/index.js";
|
|
81
|
+
import { index_d_exports as index_d_exports$80 } from "./top-bar/index.js";
|
|
82
|
+
import { index_d_exports as index_d_exports$81 } from "./wall/index.js";
|
|
83
|
+
import { index_d_exports as index_d_exports$82 } from "./window/index.js";
|
|
84
|
+
import { index_d_exports as index_d_exports$83 } from "./wordmark/index.js";
|
|
85
|
+
import { index_d_exports as index_d_exports$84 } from "./wrap/index.js";
|
|
86
|
+
export { index_d_exports as Announcer, index_d_exports$1 as Banner, index_d_exports$2 as Bench, index_d_exports$3 as Board, index_d_exports$4 as Button, index_d_exports$5 as Card, index_d_exports$6 as Chip, index_d_exports$7 as Choice, index_d_exports$8 as CodeEditor, index_d_exports$9 as CodeSurface, index_d_exports$10 as CommandPalette, index_d_exports$11 as ConfirmDialog, index_d_exports$12 as CopyButton, index_d_exports$13 as Crumbs, index_d_exports$14 as Deck, index_d_exports$15 as Dialog, index_d_exports$16 as Disclosure, index_d_exports$17 as DropZone, index_d_exports$18 as EmptyState, index_d_exports$19 as ErrorSummary, index_d_exports$20 as Field, index_d_exports$21 as FieldGrid, index_d_exports$22 as Fieldset, index_d_exports$23 as FilterChip, index_d_exports$24 as FilterStrip, index_d_exports$25 as FlashWord, index_d_exports$26 as Focus, index_d_exports$27 as Format, index_d_exports$28 as Glyph, index_d_exports$29 as Group, index_d_exports$30 as History, index_d_exports$31 as IconButton, index_d_exports$32 as Identity, index_d_exports$33 as InlineInput, index_d_exports$34 as KeyHelp, index_d_exports$35 as KeyHint, index_d_exports$36 as LineDiff, index_d_exports$37 as LinkButton, index_d_exports$38 as LinkState, index_d_exports$39 as LiveRegion, index_d_exports$40 as Loading, index_d_exports$41 as Mark, index_d_exports$42 as MarkdownEditor, index_d_exports$43 as Menu, index_d_exports$44 as Meter, index_d_exports$45 as NavStrip, index_d_exports$46 as Notice, index_d_exports$47 as Outcome, index_d_exports$48 as PageHead, index_d_exports$49 as Panel, index_d_exports$50 as PasswordField, index_d_exports$51 as Places, index_d_exports$52 as PropsList, index_d_exports$53 as Prose, index_d_exports$54 as QueryChip, index_d_exports$55 as RadioChoices, index_d_exports$56 as Rail, index_d_exports$57 as Reel, index_d_exports$58 as Remote, index_d_exports$59 as Rows, index_d_exports$60 as Scheme, index_d_exports$61 as Secret, index_d_exports$62 as Segmented, index_d_exports$63 as SelectField, index_d_exports$64 as Sheet, index_d_exports$65 as SkipLink, index_d_exports$66 as Sortable, index_d_exports$67 as Stack, index_d_exports$68 as Stage, index_d_exports$69 as Stat, index_d_exports$70 as StatusBar, index_d_exports$71 as Table, index_d_exports$72 as Tabs, index_d_exports$73 as Tag, index_d_exports$74 as TextButton, index_d_exports$75 as TextareaField, index_d_exports$76 as Time, index_d_exports$77 as Tips, index_d_exports$78 as Toast, index_d_exports$79 as Toc, index_d_exports$80 as TopBar, index_d_exports$81 as Wall, index_d_exports$82 as Window, index_d_exports$83 as Wordmark, index_d_exports$84 as Wrap };
|
package/dist/index.js
CHANGED
|
@@ -40,6 +40,7 @@ import { link_state_exports } from "./link-state/index.js";
|
|
|
40
40
|
import { live_region_exports } from "./live-region/index.js";
|
|
41
41
|
import { loading_exports } from "./loading/index.js";
|
|
42
42
|
import { mark_exports } from "./mark/index.js";
|
|
43
|
+
import { markdown_editor_exports } from "./markdown-editor/index.js";
|
|
43
44
|
import { menu_exports } from "./menu/index.js";
|
|
44
45
|
import { meter_exports } from "./meter/index.js";
|
|
45
46
|
import { nav_strip_exports } from "./nav-strip/index.js";
|
|
@@ -82,4 +83,4 @@ import { wall_exports } from "./wall/index.js";
|
|
|
82
83
|
import { window_exports } from "./window/index.js";
|
|
83
84
|
import { wordmark_exports } from "./wordmark/index.js";
|
|
84
85
|
import { wrap_exports } from "./wrap/index.js";
|
|
85
|
-
export { announcer_exports as Announcer, banner_exports as Banner, bench_exports as Bench, board_exports as Board, button_exports as Button, card_exports as Card, chip_exports as Chip, choice_exports as Choice, code_editor_exports as CodeEditor, code_surface_exports as CodeSurface, command_palette_exports as CommandPalette, confirm_dialog_exports as ConfirmDialog, copy_button_exports as CopyButton, crumbs_exports as Crumbs, deck_exports as Deck, dialog_exports as Dialog, disclosure_exports as Disclosure, drop_zone_exports as DropZone, empty_state_exports as EmptyState, error_summary_exports as ErrorSummary, field_exports as Field, field_grid_exports as FieldGrid, fieldset_exports as Fieldset, filter_chip_exports as FilterChip, filter_strip_exports as FilterStrip, flash_word_exports as FlashWord, focus_exports as Focus, format_exports as Format, glyph_exports as Glyph, group_exports as Group, history_exports as History, icon_button_exports as IconButton, identity_exports as Identity, inline_input_exports as InlineInput, key_help_exports as KeyHelp, key_hint_exports as KeyHint, line_diff_exports as LineDiff, link_button_exports as LinkButton, link_state_exports as LinkState, live_region_exports as LiveRegion, loading_exports as Loading, mark_exports as Mark, menu_exports as Menu, meter_exports as Meter, nav_strip_exports as NavStrip, notice_exports as Notice, outcome_exports as Outcome, page_head_exports as PageHead, panel_exports as Panel, password_field_exports as PasswordField, places_exports as Places, props_list_exports as PropsList, prose_exports as Prose, query_chip_exports as QueryChip, radio_choices_exports as RadioChoices, rail_exports as Rail, reel_exports as Reel, remote_exports as Remote, rows_exports as Rows, scheme_exports as Scheme, secret_exports as Secret, segmented_exports as Segmented, select_field_exports as SelectField, sheet_exports as Sheet, skip_link_exports as SkipLink, sortable_exports as Sortable, stack_exports as Stack, stage_exports as Stage, stat_exports as Stat, status_bar_exports as StatusBar, table_exports as Table, tabs_exports as Tabs, tag_exports as Tag, text_button_exports as TextButton, textarea_field_exports as TextareaField, time_exports as Time, tips_exports as Tips, toast_exports as Toast, toc_exports as Toc, top_bar_exports as TopBar, wall_exports as Wall, window_exports as Window, wordmark_exports as Wordmark, wrap_exports as Wrap };
|
|
86
|
+
export { announcer_exports as Announcer, banner_exports as Banner, bench_exports as Bench, board_exports as Board, button_exports as Button, card_exports as Card, chip_exports as Chip, choice_exports as Choice, code_editor_exports as CodeEditor, code_surface_exports as CodeSurface, command_palette_exports as CommandPalette, confirm_dialog_exports as ConfirmDialog, copy_button_exports as CopyButton, crumbs_exports as Crumbs, deck_exports as Deck, dialog_exports as Dialog, disclosure_exports as Disclosure, drop_zone_exports as DropZone, empty_state_exports as EmptyState, error_summary_exports as ErrorSummary, field_exports as Field, field_grid_exports as FieldGrid, fieldset_exports as Fieldset, filter_chip_exports as FilterChip, filter_strip_exports as FilterStrip, flash_word_exports as FlashWord, focus_exports as Focus, format_exports as Format, glyph_exports as Glyph, group_exports as Group, history_exports as History, icon_button_exports as IconButton, identity_exports as Identity, inline_input_exports as InlineInput, key_help_exports as KeyHelp, key_hint_exports as KeyHint, line_diff_exports as LineDiff, link_button_exports as LinkButton, link_state_exports as LinkState, live_region_exports as LiveRegion, loading_exports as Loading, mark_exports as Mark, markdown_editor_exports as MarkdownEditor, menu_exports as Menu, meter_exports as Meter, nav_strip_exports as NavStrip, notice_exports as Notice, outcome_exports as Outcome, page_head_exports as PageHead, panel_exports as Panel, password_field_exports as PasswordField, places_exports as Places, props_list_exports as PropsList, prose_exports as Prose, query_chip_exports as QueryChip, radio_choices_exports as RadioChoices, rail_exports as Rail, reel_exports as Reel, remote_exports as Remote, rows_exports as Rows, scheme_exports as Scheme, secret_exports as Secret, segmented_exports as Segmented, select_field_exports as SelectField, sheet_exports as Sheet, skip_link_exports as SkipLink, sortable_exports as Sortable, stack_exports as Stack, stage_exports as Stage, stat_exports as Stat, status_bar_exports as StatusBar, table_exports as Table, tabs_exports as Tabs, tag_exports as Tag, text_button_exports as TextButton, textarea_field_exports as TextareaField, time_exports as Time, tips_exports as Tips, toast_exports as Toast, toc_exports as Toc, top_bar_exports as TopBar, wall_exports as Wall, window_exports as Window, wordmark_exports as Wordmark, wrap_exports as Wrap };
|
|
@@ -96,13 +96,13 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
96
96
|
readonly isRepeating: boolean;
|
|
97
97
|
};
|
|
98
98
|
commands?: Update.Commands<{
|
|
99
|
-
readonly _tag: "PressedEscape";
|
|
100
|
-
} | {
|
|
101
99
|
readonly _tag: "CompletedFocusField";
|
|
102
100
|
} | {
|
|
103
101
|
readonly _tag: "BlurredField";
|
|
104
102
|
} | {
|
|
105
103
|
readonly _tag: "PressedEnter";
|
|
104
|
+
} | {
|
|
105
|
+
readonly _tag: "PressedEscape";
|
|
106
106
|
} | {
|
|
107
107
|
readonly _tag: "UpdatedDraft";
|
|
108
108
|
readonly value: string;
|
|
@@ -134,9 +134,9 @@ export declare const failed: (model: Model, error?: string) => Update.Return<Mod
|
|
|
134
134
|
* never also closes the dialog around the field. Attached by `view`. In a Scene, resolve it
|
|
135
135
|
* with `Message.PressedEscape`. */
|
|
136
136
|
export declare const BindFieldKeys: Mount.MountDefinitionNoArgs<"BindFieldKeys", {
|
|
137
|
-
readonly _tag: "PressedEscape";
|
|
138
|
-
} | {
|
|
139
137
|
readonly _tag: "PressedEnter";
|
|
138
|
+
} | {
|
|
139
|
+
readonly _tag: "PressedEscape";
|
|
140
140
|
}>;
|
|
141
141
|
/** Per-render inputs passed to `view` through `h.submodel`'s `viewInputs`. */
|
|
142
142
|
export type ViewInputs = Readonly<{
|
|
@@ -172,13 +172,13 @@ export declare const view: import("foldkit/submodel").View<{
|
|
|
172
172
|
readonly maybeLastSavedId: Option.Option<string>;
|
|
173
173
|
readonly isRepeating: boolean;
|
|
174
174
|
}, {
|
|
175
|
-
readonly _tag: "PressedEscape";
|
|
176
|
-
} | {
|
|
177
175
|
readonly _tag: "CompletedFocusField";
|
|
178
176
|
} | {
|
|
179
177
|
readonly _tag: "BlurredField";
|
|
180
178
|
} | {
|
|
181
179
|
readonly _tag: "PressedEnter";
|
|
180
|
+
} | {
|
|
181
|
+
readonly _tag: "PressedEscape";
|
|
182
182
|
} | {
|
|
183
183
|
readonly _tag: "UpdatedDraft";
|
|
184
184
|
readonly value: string;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Registers `<pp-markdown-editor>`. Call it once from the client entry, before the first
|
|
2
|
+
* render. This subpath carries CodeMirror, so the package's root never registers it for an
|
|
3
|
+
* application that does not ask. */
|
|
4
|
+
export declare const defineMarkdownEditorElement: () => void;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
+
import { spec } from "./markdown-editor.js";
|
|
3
|
+
import { afterEmission, afterSource } from "./reconcile.js";
|
|
4
|
+
import { createEngine } from "./engine.js";
|
|
5
|
+
// src/markdown-editor/element.ts
|
|
6
|
+
const MIRRORED_ATTRIBUTES = ["aria-describedby", "aria-invalid"];
|
|
7
|
+
const MOTION_END_EVENTS = ["animationend", "transitionend"];
|
|
8
|
+
const mirroredAttributes = (textarea) => __foldkitBrandViewResult((Object.fromEntries(MIRRORED_ATTRIBUTES.flatMap((name) => {
|
|
9
|
+
const value = textarea.getAttribute(name);
|
|
10
|
+
return __foldkitBrandViewResult((value === null ? [] : [[name, value]]), "@gjermundgaraba/pixel-paper/markdown-editor/element.js#anonymous");
|
|
11
|
+
}))), "@gjermundgaraba/pixel-paper/markdown-editor/element.js#mirroredAttributes");
|
|
12
|
+
const namedBy = (textarea) => {
|
|
13
|
+
const [label] = textarea.labels ?? [];
|
|
14
|
+
if (label === void 0) return __foldkitBrandViewResult(({}), "@gjermundgaraba/pixel-paper/markdown-editor/element.js#namedBy");
|
|
15
|
+
if (label.id === "") label.id = `${textarea.id}-label`;
|
|
16
|
+
return __foldkitBrandViewResult(({ "aria-labelledby": label.id }), "@gjermundgaraba/pixel-paper/markdown-editor/element.js#namedBy");
|
|
17
|
+
};
|
|
18
|
+
const createEngineOrReport = (config) => {
|
|
19
|
+
try {
|
|
20
|
+
return __foldkitBrandViewResult((createEngine(config)), "@gjermundgaraba/pixel-paper/markdown-editor/element.js#createEngineOrReport");
|
|
21
|
+
} catch (error) {
|
|
22
|
+
reportError(error);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
var MarkdownEditorElement = class extends HTMLElement {
|
|
27
|
+
static formAssociated = true;
|
|
28
|
+
#source = "";
|
|
29
|
+
#isDisabled = false;
|
|
30
|
+
#pending = [];
|
|
31
|
+
#mounted;
|
|
32
|
+
get source() {
|
|
33
|
+
return __foldkitBrandViewResult((this.#source), "@gjermundgaraba/pixel-paper/markdown-editor/element.js#source");
|
|
34
|
+
}
|
|
35
|
+
set source(next) {
|
|
36
|
+
this.#source = next;
|
|
37
|
+
const engine = this.#mounted?.engine;
|
|
38
|
+
if (engine === void 0) return;
|
|
39
|
+
const { pending, isExternal } = afterSource(this.#pending, next, engine.doc());
|
|
40
|
+
this.#pending = pending;
|
|
41
|
+
if (isExternal) engine.applyExternal(next);
|
|
42
|
+
}
|
|
43
|
+
formDisabledCallback(isDisabled) {
|
|
44
|
+
this.#isDisabled = isDisabled;
|
|
45
|
+
this.#mounted?.syncAccess();
|
|
46
|
+
}
|
|
47
|
+
connectedCallback() {
|
|
48
|
+
const textarea = this.querySelector("textarea");
|
|
49
|
+
if (this.#mounted === void 0 && textarea !== null) this.#mounted = this.#mount(textarea);
|
|
50
|
+
}
|
|
51
|
+
disconnectedCallback() {
|
|
52
|
+
queueMicrotask(() => {
|
|
53
|
+
if (!this.isConnected) this.#mounted?.unmount();
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
#mount(textarea) {
|
|
57
|
+
const surface = document.createElement("div");
|
|
58
|
+
surface.className = "markdown-surface";
|
|
59
|
+
surface.style.setProperty("--rows", `${textarea.rows}`);
|
|
60
|
+
textarea.after(surface);
|
|
61
|
+
const accessAttributes = () => (__foldkitBrandViewResult(({
|
|
62
|
+
...namedBy(textarea),
|
|
63
|
+
...mirroredAttributes(textarea)
|
|
64
|
+
}), "@gjermundgaraba/pixel-paper/markdown-editor/element.js#accessAttributes"));
|
|
65
|
+
const engine = createEngineOrReport({
|
|
66
|
+
parent: surface,
|
|
67
|
+
doc: this.#source,
|
|
68
|
+
attributes: accessAttributes(),
|
|
69
|
+
isReadOnly: this.#isDisabled,
|
|
70
|
+
onLocalChange: (doc) => {
|
|
71
|
+
this.#pending = afterEmission(this.#pending, doc);
|
|
72
|
+
this.dispatchEvent(new CustomEvent("value-change", { detail: { value: doc } }));
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
if (engine === void 0) {
|
|
76
|
+
surface.remove();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const syncAccess = () => {
|
|
80
|
+
engine.configureAccess(accessAttributes(), this.#isDisabled);
|
|
81
|
+
};
|
|
82
|
+
const lifetime = new AbortController();
|
|
83
|
+
const { signal } = lifetime;
|
|
84
|
+
const motion = new AbortController();
|
|
85
|
+
const remeasureAfterMotion = (event) => {
|
|
86
|
+
if (event.target instanceof Node && event.target.contains(this)) {
|
|
87
|
+
engine.requestMeasure();
|
|
88
|
+
motion.abort();
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
const attributeObserver = new MutationObserver(syncAccess);
|
|
92
|
+
textarea.tabIndex = -1;
|
|
93
|
+
textarea.setAttribute("aria-hidden", "true");
|
|
94
|
+
textarea.addEventListener("focus", engine.focus, { signal });
|
|
95
|
+
textarea.labels?.[0]?.addEventListener("click", (event) => {
|
|
96
|
+
event.preventDefault();
|
|
97
|
+
engine.focus();
|
|
98
|
+
}, { signal });
|
|
99
|
+
for (const name of MOTION_END_EVENTS) document.addEventListener(name, remeasureAfterMotion, {
|
|
100
|
+
capture: true,
|
|
101
|
+
signal: motion.signal
|
|
102
|
+
});
|
|
103
|
+
attributeObserver.observe(textarea, {
|
|
104
|
+
attributes: true,
|
|
105
|
+
attributeFilter: [...MIRRORED_ATTRIBUTES]
|
|
106
|
+
});
|
|
107
|
+
return __foldkitBrandViewResult(({
|
|
108
|
+
engine,
|
|
109
|
+
syncAccess,
|
|
110
|
+
unmount: () => {
|
|
111
|
+
lifetime.abort();
|
|
112
|
+
motion.abort();
|
|
113
|
+
attributeObserver.disconnect();
|
|
114
|
+
engine.destroy();
|
|
115
|
+
surface.remove();
|
|
116
|
+
this.#mounted = void 0;
|
|
117
|
+
this.#pending = [];
|
|
118
|
+
}
|
|
119
|
+
}), "@gjermundgaraba/pixel-paper/markdown-editor/element.js#mount");
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
/** Registers `<pp-markdown-editor>`. Call it once from the client entry, before the first
|
|
123
|
+
* render. This subpath carries CodeMirror, so the package's root never registers it for an
|
|
124
|
+
* application that does not ask. */
|
|
125
|
+
const defineMarkdownEditorElement = () => {
|
|
126
|
+
if (customElements.get(spec.tag) === void 0) customElements.define(spec.tag, MarkdownEditorElement);
|
|
127
|
+
};
|
|
128
|
+
export { defineMarkdownEditorElement };
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
+
import { liveMarkdown } from "./live/live.js";
|
|
3
|
+
import { withLfLineEndings } from "./reconcile.js";
|
|
4
|
+
import { defaultKeymap, history, historyKeymap } from "@codemirror/commands";
|
|
5
|
+
import { commonmarkLanguage, markdownKeymap } from "@codemirror/lang-markdown";
|
|
6
|
+
import { Language } from "@codemirror/language";
|
|
7
|
+
import { diff } from "@codemirror/merge";
|
|
8
|
+
import { Compartment, EditorState, Prec, Transaction } from "@codemirror/state";
|
|
9
|
+
import { EditorView, keymap } from "@codemirror/view";
|
|
10
|
+
import { GFM, MarkdownParser } from "@lezer/markdown";
|
|
11
|
+
// src/markdown-editor/engine.ts
|
|
12
|
+
const DIFF_TIMEOUT_MS = 50;
|
|
13
|
+
const historyCompartment = new Compartment();
|
|
14
|
+
const language = new Language(commonmarkLanguage.data, commonmarkLanguage.parser instanceof MarkdownParser ? commonmarkLanguage.parser.configure(GFM) : commonmarkLanguage.parser, [], "markdown");
|
|
15
|
+
/** Who is named by what, and whether the document may change. `readOnly` alone lets Enter and
|
|
16
|
+
* the Markdown keymap edit, so the filter refuses every change but an outside one. */
|
|
17
|
+
const accessExtension = (attributes, isReadOnly) => __foldkitBrandViewResult(([
|
|
18
|
+
EditorState.readOnly.of(isReadOnly),
|
|
19
|
+
...isReadOnly ? [EditorState.changeFilter.of((transaction) => __foldkitBrandViewResult((transaction.annotation(Transaction.remote) === true), "@gjermundgaraba/pixel-paper/markdown-editor/engine.js#anonymous"))] : [],
|
|
20
|
+
EditorView.contentAttributes.of({
|
|
21
|
+
...attributes,
|
|
22
|
+
...isReadOnly ? { "aria-disabled": "true" } : {}
|
|
23
|
+
})
|
|
24
|
+
]), "@gjermundgaraba/pixel-paper/markdown-editor/engine.js#accessExtension");
|
|
25
|
+
/** The editor's state. No line separator is set, so CRLF text parses like LF text, and the
|
|
26
|
+
* first edit hands it back with LF line endings. Tab stays unbound and nothing inside the
|
|
27
|
+
* field takes focus, so Tab leaves the field. Mod-Enter only opens a link at the caret, so
|
|
28
|
+
* elsewhere it does nothing, as in a textarea. */
|
|
29
|
+
const editorState = (doc, extensions = []) => __foldkitBrandViewResult((EditorState.create({
|
|
30
|
+
doc,
|
|
31
|
+
extensions: [
|
|
32
|
+
historyCompartment.of(history()),
|
|
33
|
+
language,
|
|
34
|
+
liveMarkdown(),
|
|
35
|
+
Prec.high(keymap.of(markdownKeymap)),
|
|
36
|
+
keymap.of([...defaultKeymap.filter(({ key }) => __foldkitBrandViewResult((key !== "Mod-Enter"), "@gjermundgaraba/pixel-paper/markdown-editor/engine.js#anonymous~2")), ...historyKeymap]),
|
|
37
|
+
EditorView.lineWrapping,
|
|
38
|
+
EditorView.contentAttributes.of({
|
|
39
|
+
spellcheck: "true",
|
|
40
|
+
autocorrect: "on",
|
|
41
|
+
autocapitalize: "sentences"
|
|
42
|
+
}),
|
|
43
|
+
extensions
|
|
44
|
+
]
|
|
45
|
+
})), "@gjermundgaraba/pixel-paper/markdown-editor/engine.js#editorState");
|
|
46
|
+
/** The whole document to send up after these transactions, if one of them was a local edit. */
|
|
47
|
+
const emission = (transactions, state) => __foldkitBrandViewResult((transactions.some((transaction) => __foldkitBrandViewResult((transaction.docChanged && transaction.annotation(Transaction.remote) !== true), "@gjermundgaraba/pixel-paper/markdown-editor/engine.js#anonymous~3")) ? state.doc.toString() : void 0), "@gjermundgaraba/pixel-paper/markdown-editor/engine.js#emission");
|
|
48
|
+
/** Puts an outside value in as a minimal edit, so the caret stays on the same text, and ends
|
|
49
|
+
* the undo history. Typed edits left in it would map onto letters of the outside text, and
|
|
50
|
+
* undo would delete those. Dropping the history field and adding it back starts it empty. */
|
|
51
|
+
const applyExternal = (target, source) => {
|
|
52
|
+
const current = target.state.doc.toString();
|
|
53
|
+
const next = withLfLineEndings(source);
|
|
54
|
+
target.dispatch(target.state.update({
|
|
55
|
+
changes: diff(current, next, { timeout: DIFF_TIMEOUT_MS }).map(({ fromA, toA, fromB, toB }) => (__foldkitBrandViewResult(({
|
|
56
|
+
from: fromA,
|
|
57
|
+
to: toA,
|
|
58
|
+
insert: next.slice(fromB, toB)
|
|
59
|
+
}), "@gjermundgaraba/pixel-paper/markdown-editor/engine.js#anonymous~4"))),
|
|
60
|
+
annotations: Transaction.remote.of(true),
|
|
61
|
+
effects: historyCompartment.reconfigure([])
|
|
62
|
+
}));
|
|
63
|
+
target.dispatch(target.state.update({ effects: historyCompartment.reconfigure(history()) }));
|
|
64
|
+
};
|
|
65
|
+
/** Mounts CodeMirror in `parent`, and returns what the element drives it with. */
|
|
66
|
+
const createEngine = (config) => {
|
|
67
|
+
const access = new Compartment();
|
|
68
|
+
const view = new EditorView({
|
|
69
|
+
parent: config.parent,
|
|
70
|
+
state: editorState(config.doc, [access.of(accessExtension(config.attributes, config.isReadOnly)), EditorView.updateListener.of((update) => {
|
|
71
|
+
const doc = emission(update.transactions, update.state);
|
|
72
|
+
if (doc !== void 0) config.onLocalChange(doc);
|
|
73
|
+
})])
|
|
74
|
+
});
|
|
75
|
+
return __foldkitBrandViewResult(({
|
|
76
|
+
doc: () => __foldkitBrandViewResult((view.state.doc.toString()), "@gjermundgaraba/pixel-paper/markdown-editor/engine.js#doc"),
|
|
77
|
+
focus: () => {
|
|
78
|
+
view.focus();
|
|
79
|
+
},
|
|
80
|
+
requestMeasure: () => {
|
|
81
|
+
view.requestMeasure();
|
|
82
|
+
},
|
|
83
|
+
applyExternal: (source) => {
|
|
84
|
+
applyExternal(view, source);
|
|
85
|
+
},
|
|
86
|
+
configureAccess: (attributes, isReadOnly) => {
|
|
87
|
+
view.dispatch({ effects: access.reconfigure(accessExtension(attributes, isReadOnly)) });
|
|
88
|
+
},
|
|
89
|
+
destroy: () => {
|
|
90
|
+
view.destroy();
|
|
91
|
+
}
|
|
92
|
+
}), "@gjermundgaraba/pixel-paper/markdown-editor/engine.js#createEngine");
|
|
93
|
+
};
|
|
94
|
+
export { accessExtension, applyExternal, createEngine, editorState, emission };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
+
import { __exportAll } from "../_virtual/_rolldown/runtime.js";
|
|
3
|
+
import { view } from "./markdown-editor.js";
|
|
4
|
+
// src/markdown-editor/index.ts
|
|
5
|
+
var markdown_editor_exports = /* @__PURE__ */ __exportAll({ view: () => __foldkitBrandViewResult((view), "@gjermundgaraba/pixel-paper/markdown-editor/index.js#view") });
|
|
6
|
+
export { markdown_editor_exports, view };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
+
// src/markdown-editor/link-policy.ts
|
|
3
|
+
const LINK_PROTOCOLS = /* @__PURE__ */ new Set([
|
|
4
|
+
"http:",
|
|
5
|
+
"https:",
|
|
6
|
+
"mailto:"
|
|
7
|
+
]);
|
|
8
|
+
const IMAGE_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
|
|
9
|
+
const allowedUrl = (protocols, url, base) => {
|
|
10
|
+
const parsed = URL.parse(url, base);
|
|
11
|
+
return __foldkitBrandViewResult((parsed !== null && protocols.has(parsed.protocol) ? parsed.href : void 0), "@gjermundgaraba/pixel-paper/markdown-editor/link-policy.js#allowedUrl");
|
|
12
|
+
};
|
|
13
|
+
/** A link's target as an absolute URL, when it is one a click may open. The browser's own
|
|
14
|
+
* URL parser decides, so a tab, a newline or mixed case cannot hide a scheme from it. */
|
|
15
|
+
const safeHref = (url, base) => __foldkitBrandViewResult((allowedUrl(LINK_PROTOCOLS, url, base)), "@gjermundgaraba/pixel-paper/markdown-editor/link-policy.js#safeHref");
|
|
16
|
+
/** An image's source as an absolute URL, when the page may fetch it on render. */
|
|
17
|
+
const safeImageSource = (url, base) => __foldkitBrandViewResult((allowedUrl(IMAGE_PROTOCOLS, url, base)), "@gjermundgaraba/pixel-paper/markdown-editor/link-policy.js#safeImageSource");
|
|
18
|
+
export { safeHref, safeImageSource };
|