@panneau/editor 0.0.0-stage → 5.0.0-alpha.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +129 -2
  2. package/dist/LinkDialog.d.ts +18 -0
  3. package/dist/LinkDialog.d.ts.map +1 -0
  4. package/dist/LinkDialog.js +220 -0
  5. package/dist/LinkDialog.js.map +1 -0
  6. package/dist/RichTextField.css +257 -0
  7. package/dist/RichTextField.d.ts +43 -0
  8. package/dist/RichTextField.d.ts.map +1 -0
  9. package/dist/RichTextField.js +361 -0
  10. package/dist/RichTextField.js.map +1 -0
  11. package/dist/RichTextField.module.js +28 -0
  12. package/dist/RichTextField.module.js.map +1 -0
  13. package/dist/Toolbar.d.ts +20 -0
  14. package/dist/Toolbar.d.ts.map +1 -0
  15. package/dist/Toolbar.js +203 -0
  16. package/dist/Toolbar.js.map +1 -0
  17. package/dist/buttons.d.ts +23 -0
  18. package/dist/buttons.d.ts.map +1 -0
  19. package/dist/buttons.js +117 -0
  20. package/dist/buttons.js.map +1 -0
  21. package/dist/extensions/attributes.d.ts +44 -0
  22. package/dist/extensions/attributes.d.ts.map +1 -0
  23. package/dist/extensions/attributes.js +138 -0
  24. package/dist/extensions/attributes.js.map +1 -0
  25. package/dist/extensions/index.d.ts +19 -0
  26. package/dist/extensions/index.d.ts.map +1 -0
  27. package/dist/extensions/index.js +96 -0
  28. package/dist/extensions/index.js.map +1 -0
  29. package/dist/extensions/marks.d.ts +4 -0
  30. package/dist/extensions/marks.d.ts.map +1 -0
  31. package/dist/extensions/marks.js +62 -0
  32. package/dist/extensions/marks.js.map +1 -0
  33. package/dist/extensions/paste.d.ts +32 -0
  34. package/dist/extensions/paste.d.ts.map +1 -0
  35. package/dist/extensions/paste.js +131 -0
  36. package/dist/extensions/paste.js.map +1 -0
  37. package/dist/extensions/raw.d.ts +23 -0
  38. package/dist/extensions/raw.d.ts.map +1 -0
  39. package/dist/extensions/raw.js +269 -0
  40. package/dist/extensions/raw.js.map +1 -0
  41. package/dist/html.d.ts +21 -0
  42. package/dist/html.d.ts.map +1 -0
  43. package/dist/html.js +51 -0
  44. package/dist/html.js.map +1 -0
  45. package/dist/index.d.ts +8 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +7 -0
  48. package/dist/plugin.d.ts +26 -0
  49. package/dist/plugin.d.ts.map +1 -0
  50. package/dist/plugin.js +46 -0
  51. package/dist/plugin.js.map +1 -0
  52. package/dist/settings.d.ts +22 -0
  53. package/dist/settings.d.ts.map +1 -0
  54. package/dist/settings.js +45 -0
  55. package/dist/settings.js.map +1 -0
  56. package/dist/styles.d.ts +16 -0
  57. package/dist/styles.d.ts.map +1 -0
  58. package/dist/styles.js +86 -0
  59. package/dist/styles.js.map +1 -0
  60. package/package.json +71 -5
@@ -0,0 +1,203 @@
1
+ import RichTextField_module_default from "./RichTextField.module.js";
2
+ import { LinkDialog } from "./LinkDialog.js";
3
+ import { builtInButtons } from "./buttons.js";
4
+ import { applyStyle, canApplyStyle, getActiveStyle } from "./styles.js";
5
+ import { c } from "react/compiler-runtime";
6
+ import { useEditorState } from "@tiptap/react";
7
+ import { useState } from "react";
8
+ import { editorMessages } from "@panneau/intl";
9
+ import { Select, Tooltip, usePanneauIntl } from "@panneau/ui";
10
+ import { Link } from "lucide-react";
11
+ import { Button as Button$1, Separator, ToggleButton, Toolbar } from "react-aria-components";
12
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
13
+ //#region src/Toolbar.tsx
14
+ var SEPARATOR = "|";
15
+ var NO_STYLE = "none";
16
+ /** The items that show: known ones, without separators at the ends or next to each other. */
17
+ function getShownItems(items, known) {
18
+ const shown = items.reduce((result, name) => {
19
+ if (name === SEPARATOR ? result.length > 0 && result.at(-1) !== SEPARATOR : known(name)) result.push(name);
20
+ return result;
21
+ }, []);
22
+ return shown.at(-1) === SEPARATOR ? shown.slice(0, -1) : shown;
23
+ }
24
+ /** The block of the selection, as the text style select names it: `paragraph`, `h2`. */
25
+ function getTextStyle(editor) {
26
+ const { $from } = editor.state.selection;
27
+ const block = $from.parent;
28
+ if (block.type.name === "heading") return `h${String(block.attrs.level)}`;
29
+ return block.type.name === "paragraph" ? "paragraph" : null;
30
+ }
31
+ function ToolbarButton(t0) {
32
+ const $ = c(11);
33
+ const { label, icon: Icon, isActive, isDisabled, onPress } = t0;
34
+ let t1;
35
+ if ($[0] !== Icon) {
36
+ t1 = /* @__PURE__ */ jsx(Icon, {
37
+ size: 16,
38
+ "aria-hidden": true
39
+ });
40
+ $[0] = Icon;
41
+ $[1] = t1;
42
+ } else t1 = $[1];
43
+ const icon = t1;
44
+ let t2;
45
+ if ($[2] !== icon || $[3] !== isActive || $[4] !== isDisabled || $[5] !== label || $[6] !== onPress) {
46
+ t2 = isActive !== void 0 ? /* @__PURE__ */ jsx(ToggleButton, {
47
+ className: RichTextField_module_default.button,
48
+ "aria-label": label,
49
+ isSelected: isActive,
50
+ isDisabled,
51
+ onChange: onPress,
52
+ children: icon
53
+ }) : /* @__PURE__ */ jsx(Button$1, {
54
+ className: RichTextField_module_default.button,
55
+ "aria-label": label,
56
+ isDisabled,
57
+ onPress,
58
+ children: icon
59
+ });
60
+ $[2] = icon;
61
+ $[3] = isActive;
62
+ $[4] = isDisabled;
63
+ $[5] = label;
64
+ $[6] = onPress;
65
+ $[7] = t2;
66
+ } else t2 = $[7];
67
+ let t3;
68
+ if ($[8] !== label || $[9] !== t2) {
69
+ t3 = /* @__PURE__ */ jsx(Tooltip, {
70
+ content: label,
71
+ children: t2
72
+ });
73
+ $[8] = label;
74
+ $[9] = t2;
75
+ $[10] = t3;
76
+ } else t3 = $[10];
77
+ return t3;
78
+ }
79
+ /**
80
+ * The toolbar of the rich text field: the text style (paragraph or a heading level), the block
81
+ * styles, marks, links, lists and the buttons of plugins, as the field's `toolbar` lists them.
82
+ */
83
+ function Toolbar$1(t0) {
84
+ const $ = c(2);
85
+ const { editor, items, headings, styles: blockStyles, newTab, buttons } = t0;
86
+ const intl = usePanneauIntl();
87
+ const [linkOpen, setLinkOpen] = useState(false);
88
+ const allButtons = new Map([...builtInButtons, ...buttons].map(_temp));
89
+ const known = (name) => allButtons.has(name) || name === "heading" || name === "link" || name === "style" && blockStyles.length > 0;
90
+ const shown = getShownItems(items, known);
91
+ const state = useEditorState({
92
+ editor,
93
+ selector: (t1) => {
94
+ const { editor: current } = t1;
95
+ return {
96
+ buttons: Object.fromEntries(shown.flatMap((name_0) => {
97
+ const button_0 = allButtons.get(name_0);
98
+ return button_0 !== void 0 ? [[name_0, {
99
+ active: button_0.isActive?.(current),
100
+ disabled: button_0.isDisabled?.(current) ?? false
101
+ }]] : [];
102
+ })),
103
+ textStyle: getTextStyle(current),
104
+ canSetTextStyle: current.can().setParagraph(),
105
+ style: (() => {
106
+ const active = getActiveStyle(current.state, blockStyles);
107
+ return active !== null ? blockStyles.indexOf(active) : -1;
108
+ })(),
109
+ applicable: blockStyles.map((style) => canApplyStyle(current.state, style)),
110
+ link: current.isActive("link"),
111
+ canLink: current.can().setLink({ href: "" })
112
+ };
113
+ }
114
+ });
115
+ const textStyle = state.textStyle;
116
+ const levels = textStyle !== null && textStyle !== "paragraph" && !headings.includes(Number(textStyle[1])) ? [...headings, Number(textStyle[1])] : headings;
117
+ let t2;
118
+ if ($[0] !== intl) {
119
+ t2 = intl.formatMessage(editorMessages.toolbar);
120
+ $[0] = intl;
121
+ $[1] = t2;
122
+ } else t2 = $[1];
123
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Toolbar, {
124
+ "aria-label": t2,
125
+ className: RichTextField_module_default.toolbar,
126
+ children: shown.map((name_1, index) => {
127
+ const key = `${name_1}-${String(index)}`;
128
+ if (name_1 === SEPARATOR) return /* @__PURE__ */ jsx(Separator, {
129
+ orientation: "vertical",
130
+ className: RichTextField_module_default.separator
131
+ }, key);
132
+ if (name_1 === "heading") return /* @__PURE__ */ jsx(Select, {
133
+ "aria-label": intl.formatMessage(editorMessages.textStyle),
134
+ className: RichTextField_module_default.select,
135
+ isDisabled: !state.canSetTextStyle,
136
+ options: [{
137
+ value: "paragraph",
138
+ label: intl.formatMessage(editorMessages.paragraph)
139
+ }, ...levels.map((level) => ({
140
+ value: `h${String(level)}`,
141
+ label: intl.formatMessage(editorMessages.heading, { level })
142
+ }))],
143
+ value: textStyle,
144
+ onChange: (value) => {
145
+ if (value === "paragraph") editor.chain().focus().setParagraph().run();
146
+ else if (typeof value === "string") {
147
+ const level_0 = Number(value.slice(1));
148
+ if (level_0 >= 1 && level_0 <= 6) editor.chain().focus().setHeading({ level: level_0 }).run();
149
+ }
150
+ }
151
+ }, key);
152
+ if (name_1 === "style") {
153
+ const active_0 = state.style;
154
+ return /* @__PURE__ */ jsx(Select, {
155
+ "aria-label": intl.formatMessage(editorMessages.blockStyle),
156
+ className: RichTextField_module_default.select,
157
+ options: [{
158
+ value: NO_STYLE,
159
+ label: intl.formatMessage(editorMessages.noStyle)
160
+ }, ...blockStyles.map((style_0, styleIndex) => ({
161
+ value: String(styleIndex),
162
+ label: style_0.label,
163
+ disabled: state.applicable[styleIndex] !== true
164
+ }))],
165
+ value: active_0 >= 0 ? String(active_0) : NO_STYLE,
166
+ onChange: (value_0) => {
167
+ const style_1 = value_0 === NO_STYLE ? null : blockStyles[Number(value_0)];
168
+ applyStyle(editor, style_1 ?? null, blockStyles);
169
+ }
170
+ }, key);
171
+ }
172
+ if (name_1 === "link") return /* @__PURE__ */ jsx(ToolbarButton, {
173
+ label: intl.formatMessage(editorMessages.link),
174
+ icon: Link,
175
+ isActive: state.link,
176
+ isDisabled: !state.canLink,
177
+ onPress: () => setLinkOpen(true)
178
+ }, key);
179
+ const button_1 = allButtons.get(name_1);
180
+ if (button_1 === void 0) return null;
181
+ const buttonState = state.buttons[name_1];
182
+ return /* @__PURE__ */ jsx(ToolbarButton, {
183
+ label: typeof button_1.label === "string" ? button_1.label : intl.formatMessage(button_1.label),
184
+ icon: button_1.icon,
185
+ isActive: buttonState?.active,
186
+ isDisabled: buttonState?.disabled === true,
187
+ onPress: () => button_1.run(editor)
188
+ }, key);
189
+ })
190
+ }), shown.includes("link") ? /* @__PURE__ */ jsx(LinkDialog, {
191
+ editor,
192
+ newTab,
193
+ isOpen: linkOpen,
194
+ onOpenChange: setLinkOpen
195
+ }) : null] });
196
+ }
197
+ function _temp(button) {
198
+ return [button.name, button];
199
+ }
200
+ //#endregion
201
+ export { Toolbar$1 as Toolbar };
202
+
203
+ //# sourceMappingURL=Toolbar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Toolbar.js","names":["Editor","useEditorState","Link","useState","Button","AriaButton","Toolbar","AriaToolbar","Separator","ToggleButton","editorMessages","messages","RichTextStyle","IconComponent","Select","Tooltip","usePanneauIntl","LinkDialog","styles","RichTextButton","builtInButtons","NewTabLinks","applyStyle","canApplyStyle","getActiveStyle","ToolbarProps","editor","items","headings","newTab","buttons","SEPARATOR","NO_STYLE","getShownItems","known","name","shown","reduce","result","length","at","push","slice","getTextStyle","$from","state","selection","block","parent","type","String","attrs","level","ToolbarButton","t0","$","_c","label","icon","Icon","isActive","isDisabled","onPress","t1","t2","undefined","button","t3","blockStyles","intl","linkOpen","setLinkOpen","allButtons","Map","map","_temp","has","selector","current","Object","fromEntries","flatMap","name_0","button_0","get","active","disabled","textStyle","canSetTextStyle","can","setParagraph","style","indexOf","applicable","link","canLink","setLink","href","levels","includes","Number","formatMessage","toolbar","name_1","index","key","separator","select","value","paragraph","heading","chain","focus","run","level_0","setHeading","active_0","blockStyle","noStyle","style_0","styleIndex","value_0","style_1","button_1","buttonState","_c","styles","AriaButton","Toolbar","messages","_Fragment","AriaToolbar"],"sources":["../src/Toolbar.tsx"],"sourcesContent":["import type { Editor } from '@tiptap/core';\nimport { useEditorState } from '@tiptap/react';\nimport { Link } from 'lucide-react';\nimport { useState } from 'react';\nimport {\n Button as AriaButton,\n Toolbar as AriaToolbar,\n Separator,\n ToggleButton,\n} from 'react-aria-components';\n\nimport { editorMessages as messages } from '@panneau/intl';\nimport type { RichTextStyle } from '@panneau/protocol';\nimport { type IconComponent, Select, Tooltip, usePanneauIntl } from '@panneau/ui';\n\nimport { LinkDialog } from './LinkDialog';\nimport styles from './RichTextField.module.css';\nimport { type RichTextButton, builtInButtons } from './buttons';\nimport type { NewTabLinks } from './settings';\nimport { applyStyle, canApplyStyle, getActiveStyle } from './styles';\n\nexport interface ToolbarProps {\n editor: Editor;\n /** The items, in order: built-in names, names of `buttons`, and `|` between groups. */\n items: readonly string[];\n headings: readonly number[];\n styles: readonly RichTextStyle[];\n newTab: NewTabLinks;\n /** Buttons of plugins. One with the name of a built-in button replaces it. */\n buttons: readonly RichTextButton[];\n}\n\nconst SEPARATOR = '|';\nconst NO_STYLE = 'none';\n\n/** The items that show: known ones, without separators at the ends or next to each other. */\nfunction getShownItems(\n items: readonly string[],\n known: (name: string) => boolean,\n): readonly string[] {\n const shown = items.reduce<string[]>((result, name) => {\n if (name === SEPARATOR ? result.length > 0 && result.at(-1) !== SEPARATOR : known(name)) {\n result.push(name);\n }\n return result;\n }, []);\n return shown.at(-1) === SEPARATOR ? shown.slice(0, -1) : shown;\n}\n\n/** The block of the selection, as the text style select names it: `paragraph`, `h2`. */\nfunction getTextStyle(editor: Editor): string | null {\n const { $from } = editor.state.selection;\n const block = $from.parent;\n if (block.type.name === 'heading') {\n return `h${String(block.attrs.level)}`;\n }\n return block.type.name === 'paragraph' ? 'paragraph' : null;\n}\n\nfunction ToolbarButton({\n label,\n icon: Icon,\n isActive,\n isDisabled,\n onPress,\n}: {\n label: string;\n icon: IconComponent;\n isActive: boolean | undefined;\n isDisabled: boolean;\n onPress: () => void;\n}) {\n const icon = <Icon size={16} aria-hidden />;\n return (\n <Tooltip content={label}>\n {isActive !== undefined ? (\n <ToggleButton\n className={styles.button}\n aria-label={label}\n isSelected={isActive}\n isDisabled={isDisabled}\n onChange={onPress}\n >\n {icon}\n </ToggleButton>\n ) : (\n <AriaButton\n className={styles.button}\n aria-label={label}\n isDisabled={isDisabled}\n onPress={onPress}\n >\n {icon}\n </AriaButton>\n )}\n </Tooltip>\n );\n}\n\n/**\n * The toolbar of the rich text field: the text style (paragraph or a heading level), the block\n * styles, marks, links, lists and the buttons of plugins, as the field's `toolbar` lists them.\n */\nexport function Toolbar({\n editor,\n items,\n headings,\n styles: blockStyles,\n newTab,\n buttons,\n}: ToolbarProps) {\n const intl = usePanneauIntl();\n const [linkOpen, setLinkOpen] = useState(false);\n const allButtons = new Map(\n [...builtInButtons, ...buttons].map((button) => [button.name, button]),\n );\n const known = (name: string) =>\n allButtons.has(name) ||\n name === 'heading' ||\n name === 'link' ||\n (name === 'style' && blockStyles.length > 0);\n const shown = getShownItems(items, known);\n\n // Only what the toolbar shows: it renders again when it changes\n const state = useEditorState({\n editor,\n selector: ({ editor: current }) => ({\n buttons: Object.fromEntries(\n shown.flatMap((name) => {\n const button = allButtons.get(name);\n return button !== undefined\n ? [\n [\n name,\n {\n active: button.isActive?.(current),\n disabled: button.isDisabled?.(current) ?? false,\n },\n ],\n ]\n : [];\n }),\n ),\n textStyle: getTextStyle(current),\n canSetTextStyle: current.can().setParagraph(),\n style: (() => {\n const active = getActiveStyle(current.state, blockStyles);\n return active !== null ? blockStyles.indexOf(active) : -1;\n })(),\n applicable: blockStyles.map((style) => canApplyStyle(current.state, style)),\n link: current.isActive('link'),\n canLink: current.can().setLink({ href: '' }),\n }),\n });\n\n const textStyle = state.textStyle;\n const levels =\n textStyle !== null && textStyle !== 'paragraph' && !headings.includes(Number(textStyle[1]))\n ? [...headings, Number(textStyle[1])]\n : headings;\n\n return (\n <>\n <AriaToolbar\n aria-label={intl.formatMessage(messages.toolbar)}\n className={styles.toolbar}\n >\n {shown.map((name, index) => {\n const key = `${name}-${String(index)}`;\n if (name === SEPARATOR) {\n return (\n <Separator\n key={key}\n orientation=\"vertical\"\n className={styles.separator}\n />\n );\n }\n if (name === 'heading') {\n return (\n <Select\n key={key}\n aria-label={intl.formatMessage(messages.textStyle)}\n className={styles.select}\n isDisabled={!state.canSetTextStyle}\n options={[\n {\n value: 'paragraph',\n label: intl.formatMessage(messages.paragraph),\n },\n ...levels.map((level) => ({\n value: `h${String(level)}`,\n label: intl.formatMessage(messages.heading, { level }),\n })),\n ]}\n value={textStyle}\n onChange={(value) => {\n if (value === 'paragraph') {\n editor.chain().focus().setParagraph().run();\n } else if (typeof value === 'string') {\n const level = Number(value.slice(1));\n if (level >= 1 && level <= 6) {\n editor\n .chain()\n .focus()\n .setHeading({\n level: level as 1 | 2 | 3 | 4 | 5 | 6,\n })\n .run();\n }\n }\n }}\n />\n );\n }\n if (name === 'style') {\n const active = state.style;\n return (\n <Select\n key={key}\n aria-label={intl.formatMessage(messages.blockStyle)}\n className={styles.select}\n options={[\n {\n value: NO_STYLE,\n label: intl.formatMessage(messages.noStyle),\n },\n ...blockStyles.map((style, styleIndex) => ({\n value: String(styleIndex),\n label: style.label,\n disabled: state.applicable[styleIndex] !== true,\n })),\n ]}\n value={active >= 0 ? String(active) : NO_STYLE}\n onChange={(value) => {\n const style =\n value === NO_STYLE ? null : blockStyles[Number(value)];\n applyStyle(editor, style ?? null, blockStyles);\n }}\n />\n );\n }\n if (name === 'link') {\n return (\n <ToolbarButton\n key={key}\n label={intl.formatMessage(messages.link)}\n icon={Link}\n isActive={state.link}\n isDisabled={!state.canLink}\n onPress={() => setLinkOpen(true)}\n />\n );\n }\n const button = allButtons.get(name);\n if (button === undefined) {\n return null;\n }\n const buttonState = state.buttons[name];\n return (\n <ToolbarButton\n key={key}\n label={\n typeof button.label === 'string'\n ? button.label\n : intl.formatMessage(button.label)\n }\n icon={button.icon}\n isActive={buttonState?.active}\n isDisabled={buttonState?.disabled === true}\n onPress={() => button.run(editor)}\n />\n );\n })}\n </AriaToolbar>\n {shown.includes('link') ? (\n <LinkDialog\n editor={editor}\n newTab={newTab}\n isOpen={linkOpen}\n onOpenChange={setLinkOpen}\n />\n ) : null}\n </>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { Editor } from '@tiptap/core';
2
+ import type { MessageDescriptor } from 'react-intl';
3
+ import type { IconComponent } from '@panneau/ui';
4
+ /**
5
+ * A button of the toolbar. Plugins add their own (an inline logo), which the `toolbar` setting
6
+ * names like the built-in ones.
7
+ */
8
+ export interface RichTextButton {
9
+ /** Its name in the `toolbar` setting: `logo`. */
10
+ name: string;
11
+ /** Its accessible label, also shown as a tooltip. */
12
+ label: string | MessageDescriptor;
13
+ icon: IconComponent;
14
+ /** Runs its command on the editor. */
15
+ run: (editor: Editor) => void;
16
+ /** Makes it a toggle, pressed when the selection has what it adds. */
17
+ isActive?: (editor: Editor) => boolean;
18
+ /** Whether it can't run on the selection. Defaults to never. */
19
+ isDisabled?: (editor: Editor) => boolean;
20
+ }
21
+ /** The buttons of the field's own marks and blocks, by name. */
22
+ export declare const builtInButtons: readonly RichTextButton[];
23
+ //# sourceMappingURL=buttons.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buttons.d.ts","sourceRoot":"","sources":["../src/buttons.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAiB3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAGpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC3B,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,KAAK,EAAE,MAAM,GAAG,iBAAiB,CAAC;IAClC,IAAI,EAAE,aAAa,CAAC;IACpB,sCAAsC;IACtC,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,sEAAsE;IACtE,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;IACvC,gEAAgE;IAChE,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;CAC5C;AAED,gEAAgE;AAChE,eAAO,MAAM,cAAc,EAAE,SAAS,cAAc,EA4GnD,CAAC"}
@@ -0,0 +1,117 @@
1
+ import { editorMessages } from "@panneau/intl";
2
+ import { Bold, Code, Italic, List, ListOrdered, Minus, Redo2, RemoveFormatting, Strikethrough, Subscript, Superscript, TextQuote, Underline, Undo2 } from "lucide-react";
3
+ //#region src/buttons.ts
4
+ /** The buttons of the field's own marks and blocks, by name. */
5
+ var builtInButtons = [
6
+ {
7
+ name: "bold",
8
+ label: editorMessages.bold,
9
+ icon: Bold,
10
+ run: (editor) => editor.chain().focus().toggleBold().run(),
11
+ isActive: (editor) => editor.isActive("bold"),
12
+ isDisabled: (editor) => !editor.can().toggleBold()
13
+ },
14
+ {
15
+ name: "italic",
16
+ label: editorMessages.italic,
17
+ icon: Italic,
18
+ run: (editor) => editor.chain().focus().toggleItalic().run(),
19
+ isActive: (editor) => editor.isActive("italic"),
20
+ isDisabled: (editor) => !editor.can().toggleItalic()
21
+ },
22
+ {
23
+ name: "underline",
24
+ label: editorMessages.underline,
25
+ icon: Underline,
26
+ run: (editor) => editor.chain().focus().toggleUnderline().run(),
27
+ isActive: (editor) => editor.isActive("underline"),
28
+ isDisabled: (editor) => !editor.can().toggleUnderline()
29
+ },
30
+ {
31
+ name: "strike",
32
+ label: editorMessages.strike,
33
+ icon: Strikethrough,
34
+ run: (editor) => editor.chain().focus().toggleStrike().run(),
35
+ isActive: (editor) => editor.isActive("strike"),
36
+ isDisabled: (editor) => !editor.can().toggleStrike()
37
+ },
38
+ {
39
+ name: "superscript",
40
+ label: editorMessages.superscript,
41
+ icon: Superscript,
42
+ run: (editor) => editor.chain().focus().toggleSuperscript().run(),
43
+ isActive: (editor) => editor.isActive("superscript"),
44
+ isDisabled: (editor) => !editor.can().toggleSuperscript()
45
+ },
46
+ {
47
+ name: "subscript",
48
+ label: editorMessages.subscript,
49
+ icon: Subscript,
50
+ run: (editor) => editor.chain().focus().toggleSubscript().run(),
51
+ isActive: (editor) => editor.isActive("subscript"),
52
+ isDisabled: (editor) => !editor.can().toggleSubscript()
53
+ },
54
+ {
55
+ name: "code",
56
+ label: editorMessages.code,
57
+ icon: Code,
58
+ run: (editor) => editor.chain().focus().toggleCode().run(),
59
+ isActive: (editor) => editor.isActive("code"),
60
+ isDisabled: (editor) => !editor.can().toggleCode()
61
+ },
62
+ {
63
+ name: "bulletList",
64
+ label: editorMessages.bulletList,
65
+ icon: List,
66
+ run: (editor) => editor.chain().focus().toggleBulletList().run(),
67
+ isActive: (editor) => editor.isActive("bulletList"),
68
+ isDisabled: (editor) => !editor.can().toggleBulletList()
69
+ },
70
+ {
71
+ name: "orderedList",
72
+ label: editorMessages.orderedList,
73
+ icon: ListOrdered,
74
+ run: (editor) => editor.chain().focus().toggleOrderedList().run(),
75
+ isActive: (editor) => editor.isActive("orderedList"),
76
+ isDisabled: (editor) => !editor.can().toggleOrderedList()
77
+ },
78
+ {
79
+ name: "blockquote",
80
+ label: editorMessages.blockquote,
81
+ icon: TextQuote,
82
+ run: (editor) => editor.chain().focus().toggleBlockquote().run(),
83
+ isActive: (editor) => editor.isActive("blockquote"),
84
+ isDisabled: (editor) => !editor.can().toggleBlockquote()
85
+ },
86
+ {
87
+ name: "horizontalRule",
88
+ label: editorMessages.horizontalRule,
89
+ icon: Minus,
90
+ run: (editor) => editor.chain().focus().setHorizontalRule().run(),
91
+ isDisabled: (editor) => !editor.can().setHorizontalRule()
92
+ },
93
+ {
94
+ name: "clear",
95
+ label: editorMessages.clear,
96
+ icon: RemoveFormatting,
97
+ run: (editor) => editor.chain().focus().unsetAllMarks().run()
98
+ },
99
+ {
100
+ name: "undo",
101
+ label: editorMessages.undo,
102
+ icon: Undo2,
103
+ run: (editor) => editor.chain().focus().undo().run(),
104
+ isDisabled: (editor) => !editor.can().undo()
105
+ },
106
+ {
107
+ name: "redo",
108
+ label: editorMessages.redo,
109
+ icon: Redo2,
110
+ run: (editor) => editor.chain().focus().redo().run(),
111
+ isDisabled: (editor) => !editor.can().redo()
112
+ }
113
+ ];
114
+ //#endregion
115
+ export { builtInButtons };
116
+
117
+ //# sourceMappingURL=buttons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buttons.js","names":["Editor","Bold","Code","Italic","List","ListOrdered","Minus","Redo2","RemoveFormatting","Strikethrough","Subscript","Superscript","TextQuote","Underline","Undo2","MessageDescriptor","editorMessages","messages","IconComponent","RichTextButton","name","label","icon","run","editor","isActive","isDisabled","builtInButtons","bold","chain","focus","toggleBold","can","italic","toggleItalic","underline","toggleUnderline","strike","toggleStrike","superscript","toggleSuperscript","subscript","toggleSubscript","code","toggleCode","bulletList","toggleBulletList","orderedList","toggleOrderedList","blockquote","toggleBlockquote","horizontalRule","setHorizontalRule","clear","unsetAllMarks","undo","redo","messages"],"sources":["../src/buttons.ts"],"sourcesContent":["import type { Editor } from '@tiptap/core';\nimport {\n Bold,\n Code,\n Italic,\n List,\n ListOrdered,\n Minus,\n Redo2,\n RemoveFormatting,\n Strikethrough,\n Subscript,\n Superscript,\n TextQuote,\n Underline,\n Undo2,\n} from 'lucide-react';\nimport type { MessageDescriptor } from 'react-intl';\n\nimport { editorMessages as messages } from '@panneau/intl';\nimport type { IconComponent } from '@panneau/ui';\n\n/**\n * A button of the toolbar. Plugins add their own (an inline logo), which the `toolbar` setting\n * names like the built-in ones.\n */\nexport interface RichTextButton {\n /** Its name in the `toolbar` setting: `logo`. */\n name: string;\n /** Its accessible label, also shown as a tooltip. */\n label: string | MessageDescriptor;\n icon: IconComponent;\n /** Runs its command on the editor. */\n run: (editor: Editor) => void;\n /** Makes it a toggle, pressed when the selection has what it adds. */\n isActive?: (editor: Editor) => boolean;\n /** Whether it can't run on the selection. Defaults to never. */\n isDisabled?: (editor: Editor) => boolean;\n}\n\n/** The buttons of the field's own marks and blocks, by name. */\nexport const builtInButtons: readonly RichTextButton[] = [\n {\n name: 'bold',\n label: messages.bold,\n icon: Bold,\n run: (editor) => editor.chain().focus().toggleBold().run(),\n isActive: (editor) => editor.isActive('bold'),\n isDisabled: (editor) => !editor.can().toggleBold(),\n },\n {\n name: 'italic',\n label: messages.italic,\n icon: Italic,\n run: (editor) => editor.chain().focus().toggleItalic().run(),\n isActive: (editor) => editor.isActive('italic'),\n isDisabled: (editor) => !editor.can().toggleItalic(),\n },\n {\n name: 'underline',\n label: messages.underline,\n icon: Underline,\n run: (editor) => editor.chain().focus().toggleUnderline().run(),\n isActive: (editor) => editor.isActive('underline'),\n isDisabled: (editor) => !editor.can().toggleUnderline(),\n },\n {\n name: 'strike',\n label: messages.strike,\n icon: Strikethrough,\n run: (editor) => editor.chain().focus().toggleStrike().run(),\n isActive: (editor) => editor.isActive('strike'),\n isDisabled: (editor) => !editor.can().toggleStrike(),\n },\n {\n name: 'superscript',\n label: messages.superscript,\n icon: Superscript,\n run: (editor) => editor.chain().focus().toggleSuperscript().run(),\n isActive: (editor) => editor.isActive('superscript'),\n isDisabled: (editor) => !editor.can().toggleSuperscript(),\n },\n {\n name: 'subscript',\n label: messages.subscript,\n icon: Subscript,\n run: (editor) => editor.chain().focus().toggleSubscript().run(),\n isActive: (editor) => editor.isActive('subscript'),\n isDisabled: (editor) => !editor.can().toggleSubscript(),\n },\n {\n name: 'code',\n label: messages.code,\n icon: Code,\n run: (editor) => editor.chain().focus().toggleCode().run(),\n isActive: (editor) => editor.isActive('code'),\n isDisabled: (editor) => !editor.can().toggleCode(),\n },\n {\n name: 'bulletList',\n label: messages.bulletList,\n icon: List,\n run: (editor) => editor.chain().focus().toggleBulletList().run(),\n isActive: (editor) => editor.isActive('bulletList'),\n isDisabled: (editor) => !editor.can().toggleBulletList(),\n },\n {\n name: 'orderedList',\n label: messages.orderedList,\n icon: ListOrdered,\n run: (editor) => editor.chain().focus().toggleOrderedList().run(),\n isActive: (editor) => editor.isActive('orderedList'),\n isDisabled: (editor) => !editor.can().toggleOrderedList(),\n },\n {\n name: 'blockquote',\n label: messages.blockquote,\n icon: TextQuote,\n run: (editor) => editor.chain().focus().toggleBlockquote().run(),\n isActive: (editor) => editor.isActive('blockquote'),\n isDisabled: (editor) => !editor.can().toggleBlockquote(),\n },\n {\n name: 'horizontalRule',\n label: messages.horizontalRule,\n icon: Minus,\n run: (editor) => editor.chain().focus().setHorizontalRule().run(),\n isDisabled: (editor) => !editor.can().setHorizontalRule(),\n },\n {\n name: 'clear',\n label: messages.clear,\n icon: RemoveFormatting,\n run: (editor) => editor.chain().focus().unsetAllMarks().run(),\n },\n {\n name: 'undo',\n label: messages.undo,\n icon: Undo2,\n run: (editor) => editor.chain().focus().undo().run(),\n isDisabled: (editor) => !editor.can().undo(),\n },\n {\n name: 'redo',\n label: messages.redo,\n icon: Redo2,\n run: (editor) => editor.chain().focus().redo().run(),\n isDisabled: (editor) => !editor.can().redo(),\n },\n];\n"],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { Extension } from '@tiptap/core';
2
+ /**
3
+ * Marks the paragraphs of list items that were not written as a `<p>`, while the content is
4
+ * serialized: a list item with one of them is written without it (`<li>Text</li>`), as CKEditor
5
+ * writes it. It never reaches the value.
6
+ */
7
+ export declare const IMPLICIT_PARAGRAPH = "data-panneau-implicit";
8
+ /** What ProseMirror puts on content it copies, to paste it back: never kept. */
9
+ export declare const CLIPBOARD_SLICE = "data-pm-slice";
10
+ /** What the field puts on content it copies, to know it when it is pasted: never kept. */
11
+ export declare const COPIED_FROM = "data-panneau-copy";
12
+ /**
13
+ * Where the field puts kept HTML when ProseMirror renders it without its view (see
14
+ * `restoreKeptHtml()`): never read from content.
15
+ */
16
+ export declare const KEPT_HTML = "data-panneau-html";
17
+ /** The nodes and marks of the field whose attributes are kept. */
18
+ export declare const KEPT_ATTRIBUTE_TYPES: readonly ["paragraph", "heading", "blockquote", "bulletList", "orderedList", "listItem", "horizontalRule", "hardBreak", "link", "bold", "italic", "underline", "strike", "code", "subscript", "superscript"];
19
+ /**
20
+ * Whether an attribute would run a script once rendered: an event handler (`onclick`), `srcdoc`,
21
+ * or a URL attribute (`href`, `src`…) with a `javascript:`, `vbscript:` or `data:text/html` URL,
22
+ * whatever the case and the whitespace and control characters in it. Values are read from the
23
+ * DOM, so their entities are already decoded. Other attributes can say "javascript:" (`title`).
24
+ */
25
+ export declare function isScriptAttribute(name: string, value: string): boolean;
26
+ /**
27
+ * Attributes that are safe to render: strings, without those that would run a script. Content
28
+ * reaches nodes through the parser, but also through the context of a pasted slice.
29
+ */
30
+ export declare function withoutScriptAttributes(attributes: unknown): Record<string, string>;
31
+ /**
32
+ * The attributes of an element, in their order, except those of `skip` and those that would run
33
+ * a script (`isScriptAttribute()`). `null` without any.
34
+ */
35
+ export declare function readAttributes(element: HTMLElement, skip?: readonly string[]): Record<string, string> | null;
36
+ /** The attributes kept on a node or a mark, in `htmlAttributes`, without script attributes. */
37
+ export declare function getHtmlAttributes(attrs: Record<string, unknown>): Record<string, string>;
38
+ /**
39
+ * Keeps the attributes of the elements the field knows (`class`, `style`, `id`, `lang`, `data-*`),
40
+ * in their order, so that content written by another editor keeps them once edited. Block styles
41
+ * are classes among them. Also remembers which paragraphs of list items were written as a `<p>`.
42
+ */
43
+ export declare const HtmlAttributes: Extension<any, any>;
44
+ //# sourceMappingURL=attributes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attributes.d.ts","sourceRoot":"","sources":["../../src/extensions/attributes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,0BAA0B,CAAC;AAE1D,gFAAgF;AAChF,eAAO,MAAM,eAAe,kBAAkB,CAAC;AAE/C,0FAA0F;AAC1F,eAAO,MAAM,WAAW,sBAAsB,CAAC;AAE/C;;;GAGG;AACH,eAAO,MAAM,SAAS,sBAAsB,CAAC;AAa7C,kEAAkE;AAClE,eAAO,MAAM,oBAAoB,8MAiBvB,CAAC;AAmBX;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAiBtE;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAUnF;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC1B,OAAO,EAAE,WAAW,EACpB,IAAI,GAAE,SAAS,MAAM,EAAO,GAC7B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAU/B;AAED,+FAA+F;AAC/F,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAExF;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc,qBAgCzB,CAAC"}
@@ -0,0 +1,138 @@
1
+ import { Extension } from "@tiptap/core";
2
+ //#region src/extensions/attributes.ts
3
+ /**
4
+ * Marks the paragraphs of list items that were not written as a `<p>`, while the content is
5
+ * serialized: a list item with one of them is written without it (`<li>Text</li>`), as CKEditor
6
+ * writes it. It never reaches the value.
7
+ */
8
+ var IMPLICIT_PARAGRAPH = "data-panneau-implicit";
9
+ /** What ProseMirror puts on content it copies, to paste it back: never kept. */
10
+ var CLIPBOARD_SLICE = "data-pm-slice";
11
+ /** What the field puts on content it copies, to know it when it is pasted: never kept. */
12
+ var COPIED_FROM = "data-panneau-copy";
13
+ /**
14
+ * Where the field puts kept HTML when ProseMirror renders it without its view (see
15
+ * `restoreKeptHtml()`): never read from content.
16
+ */
17
+ var KEPT_HTML = "data-panneau-html";
18
+ /** Attributes that the field and ProseMirror add, which never reach the value. */
19
+ var INTERNAL_ATTRIBUTES = [
20
+ IMPLICIT_PARAGRAPH,
21
+ CLIPBOARD_SLICE,
22
+ COPIED_FROM,
23
+ KEPT_HTML
24
+ ];
25
+ /**
26
+ * The attributes that an extension handles itself, by type: they are not kept a second time.
27
+ */
28
+ var OWN_ATTRIBUTES = {
29
+ orderedList: ["start", "type"],
30
+ link: [
31
+ "href",
32
+ "target",
33
+ "rel",
34
+ "class",
35
+ "title"
36
+ ]
37
+ };
38
+ /** The nodes and marks of the field whose attributes are kept. */
39
+ var KEPT_ATTRIBUTE_TYPES = [
40
+ "paragraph",
41
+ "heading",
42
+ "blockquote",
43
+ "bulletList",
44
+ "orderedList",
45
+ "listItem",
46
+ "horizontalRule",
47
+ "hardBreak",
48
+ "link",
49
+ "bold",
50
+ "italic",
51
+ "underline",
52
+ "strike",
53
+ "code",
54
+ "subscript",
55
+ "superscript"
56
+ ];
57
+ /** Attributes whose value is a URL, which a `javascript:` URL makes run a script. */
58
+ var URL_ATTRIBUTES = /* @__PURE__ */ new Set([
59
+ "action",
60
+ "background",
61
+ "cite",
62
+ "data",
63
+ "dynsrc",
64
+ "formaction",
65
+ "href",
66
+ "longdesc",
67
+ "lowsrc",
68
+ "poster",
69
+ "src",
70
+ "usemap",
71
+ "xlink:href"
72
+ ]);
73
+ /**
74
+ * Whether an attribute would run a script once rendered: an event handler (`onclick`), `srcdoc`,
75
+ * or a URL attribute (`href`, `src`…) with a `javascript:`, `vbscript:` or `data:text/html` URL,
76
+ * whatever the case and the whitespace and control characters in it. Values are read from the
77
+ * DOM, so their entities are already decoded. Other attributes can say "javascript:" (`title`).
78
+ */
79
+ function isScriptAttribute(name, value) {
80
+ const attribute = name.toLowerCase();
81
+ if (attribute.startsWith("on") || attribute === "srcdoc") return true;
82
+ if (!URL_ATTRIBUTES.has(attribute)) return false;
83
+ const url = Array.from(value).filter((character) => {
84
+ const code = character.charCodeAt(0);
85
+ return code > 32 && (code < 127 || code > 159);
86
+ }).join("").toLowerCase();
87
+ return /^(javascript|vbscript|data:text\/html)/.test(url);
88
+ }
89
+ /**
90
+ * Attributes that are safe to render: strings, without those that would run a script. Content
91
+ * reaches nodes through the parser, but also through the context of a pasted slice.
92
+ */
93
+ function withoutScriptAttributes(attributes) {
94
+ if (attributes === null || typeof attributes !== "object") return {};
95
+ return Object.fromEntries(Object.entries(attributes).filter((entry) => typeof entry[1] === "string" && !isScriptAttribute(entry[0], entry[1])));
96
+ }
97
+ /**
98
+ * The attributes of an element, in their order, except those of `skip` and those that would run
99
+ * a script (`isScriptAttribute()`). `null` without any.
100
+ */
101
+ function readAttributes(element, skip = []) {
102
+ const attributes = Array.from(element.attributes).filter((attribute) => !INTERNAL_ATTRIBUTES.includes(attribute.name) && !skip.includes(attribute.name) && !isScriptAttribute(attribute.name, attribute.value));
103
+ return attributes.length > 0 ? Object.fromEntries(attributes.map((attribute) => [attribute.name, attribute.value])) : null;
104
+ }
105
+ /** The attributes kept on a node or a mark, in `htmlAttributes`, without script attributes. */
106
+ function getHtmlAttributes(attrs) {
107
+ return withoutScriptAttributes(attrs.htmlAttributes);
108
+ }
109
+ /**
110
+ * Keeps the attributes of the elements the field knows (`class`, `style`, `id`, `lang`, `data-*`),
111
+ * in their order, so that content written by another editor keeps them once edited. Block styles
112
+ * are classes among them. Also remembers which paragraphs of list items were written as a `<p>`.
113
+ */
114
+ var HtmlAttributes = Extension.create({
115
+ name: "htmlAttributes",
116
+ addGlobalAttributes() {
117
+ return [...KEPT_ATTRIBUTE_TYPES.map((type) => ({
118
+ types: [type],
119
+ attributes: { htmlAttributes: {
120
+ default: null,
121
+ keepOnSplit: false,
122
+ parseHTML: (element) => readAttributes(element, OWN_ATTRIBUTES[type]),
123
+ renderHTML: (attrs) => getHtmlAttributes(attrs)
124
+ } }
125
+ })), {
126
+ types: ["paragraph"],
127
+ attributes: { explicit: {
128
+ default: false,
129
+ parseHTML: (element) => element.parentElement?.tagName === "LI",
130
+ renderHTML: (attrs) => attrs.explicit === true ? {} : { [IMPLICIT_PARAGRAPH]: "" }
131
+ } }
132
+ }];
133
+ }
134
+ });
135
+ //#endregion
136
+ export { CLIPBOARD_SLICE, COPIED_FROM, HtmlAttributes, IMPLICIT_PARAGRAPH, KEPT_ATTRIBUTE_TYPES, KEPT_HTML, getHtmlAttributes, isScriptAttribute, readAttributes, withoutScriptAttributes };
137
+
138
+ //# sourceMappingURL=attributes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attributes.js","names":["Extension","IMPLICIT_PARAGRAPH","CLIPBOARD_SLICE","COPIED_FROM","KEPT_HTML","INTERNAL_ATTRIBUTES","OWN_ATTRIBUTES","Readonly","Record","orderedList","link","KEPT_ATTRIBUTE_TYPES","const","URL_ATTRIBUTES","Set","isScriptAttribute","name","value","attribute","toLowerCase","startsWith","has","url","Array","from","filter","character","code","charCodeAt","join","test","withoutScriptAttributes","attributes","Object","fromEntries","entries","entry","readAttributes","element","HTMLElement","skip","includes","length","map","getHtmlAttributes","attrs","htmlAttributes","HtmlAttributes","create","addGlobalAttributes","type","types","default","keepOnSplit","parseHTML","renderHTML","explicit","parentElement","tagName"],"sources":["../../src/extensions/attributes.ts"],"sourcesContent":["import { Extension } from '@tiptap/core';\n\n/**\n * Marks the paragraphs of list items that were not written as a `<p>`, while the content is\n * serialized: a list item with one of them is written without it (`<li>Text</li>`), as CKEditor\n * writes it. It never reaches the value.\n */\nexport const IMPLICIT_PARAGRAPH = 'data-panneau-implicit';\n\n/** What ProseMirror puts on content it copies, to paste it back: never kept. */\nexport const CLIPBOARD_SLICE = 'data-pm-slice';\n\n/** What the field puts on content it copies, to know it when it is pasted: never kept. */\nexport const COPIED_FROM = 'data-panneau-copy';\n\n/**\n * Where the field puts kept HTML when ProseMirror renders it without its view (see\n * `restoreKeptHtml()`): never read from content.\n */\nexport const KEPT_HTML = 'data-panneau-html';\n\n/** Attributes that the field and ProseMirror add, which never reach the value. */\nconst INTERNAL_ATTRIBUTES = [IMPLICIT_PARAGRAPH, CLIPBOARD_SLICE, COPIED_FROM, KEPT_HTML];\n\n/**\n * The attributes that an extension handles itself, by type: they are not kept a second time.\n */\nconst OWN_ATTRIBUTES: Readonly<Record<string, readonly string[]>> = {\n orderedList: ['start', 'type'],\n link: ['href', 'target', 'rel', 'class', 'title'],\n};\n\n/** The nodes and marks of the field whose attributes are kept. */\nexport const KEPT_ATTRIBUTE_TYPES = [\n 'paragraph',\n 'heading',\n 'blockquote',\n 'bulletList',\n 'orderedList',\n 'listItem',\n 'horizontalRule',\n 'hardBreak',\n 'link',\n 'bold',\n 'italic',\n 'underline',\n 'strike',\n 'code',\n 'subscript',\n 'superscript',\n] as const;\n\n/** Attributes whose value is a URL, which a `javascript:` URL makes run a script. */\nconst URL_ATTRIBUTES = new Set([\n 'action',\n 'background',\n 'cite',\n 'data',\n 'dynsrc',\n 'formaction',\n 'href',\n 'longdesc',\n 'lowsrc',\n 'poster',\n 'src',\n 'usemap',\n 'xlink:href',\n]);\n\n/**\n * Whether an attribute would run a script once rendered: an event handler (`onclick`), `srcdoc`,\n * or a URL attribute (`href`, `src`…) with a `javascript:`, `vbscript:` or `data:text/html` URL,\n * whatever the case and the whitespace and control characters in it. Values are read from the\n * DOM, so their entities are already decoded. Other attributes can say \"javascript:\" (`title`).\n */\nexport function isScriptAttribute(name: string, value: string): boolean {\n const attribute = name.toLowerCase();\n if (attribute.startsWith('on') || attribute === 'srcdoc') {\n return true;\n }\n if (!URL_ATTRIBUTES.has(attribute)) {\n return false;\n }\n // Browsers skip whitespace and control characters in a URL's scheme\n const url = Array.from(value)\n .filter((character) => {\n const code = character.charCodeAt(0);\n return code > 0x20 && (code < 0x7f || code > 0x9f);\n })\n .join('')\n .toLowerCase();\n return /^(javascript|vbscript|data:text\\/html)/.test(url);\n}\n\n/**\n * Attributes that are safe to render: strings, without those that would run a script. Content\n * reaches nodes through the parser, but also through the context of a pasted slice.\n */\nexport function withoutScriptAttributes(attributes: unknown): Record<string, string> {\n if (attributes === null || typeof attributes !== 'object') {\n return {};\n }\n return Object.fromEntries(\n Object.entries(attributes).filter(\n (entry): entry is [string, string] =>\n typeof entry[1] === 'string' && !isScriptAttribute(entry[0], entry[1]),\n ),\n );\n}\n\n/**\n * The attributes of an element, in their order, except those of `skip` and those that would run\n * a script (`isScriptAttribute()`). `null` without any.\n */\nexport function readAttributes(\n element: HTMLElement,\n skip: readonly string[] = [],\n): Record<string, string> | null {\n const attributes = Array.from(element.attributes).filter(\n (attribute) =>\n !INTERNAL_ATTRIBUTES.includes(attribute.name) &&\n !skip.includes(attribute.name) &&\n !isScriptAttribute(attribute.name, attribute.value),\n );\n return attributes.length > 0\n ? Object.fromEntries(attributes.map((attribute) => [attribute.name, attribute.value]))\n : null;\n}\n\n/** The attributes kept on a node or a mark, in `htmlAttributes`, without script attributes. */\nexport function getHtmlAttributes(attrs: Record<string, unknown>): Record<string, string> {\n return withoutScriptAttributes(attrs.htmlAttributes);\n}\n\n/**\n * Keeps the attributes of the elements the field knows (`class`, `style`, `id`, `lang`, `data-*`),\n * in their order, so that content written by another editor keeps them once edited. Block styles\n * are classes among them. Also remembers which paragraphs of list items were written as a `<p>`.\n */\nexport const HtmlAttributes = Extension.create({\n name: 'htmlAttributes',\n\n addGlobalAttributes() {\n return [\n ...KEPT_ATTRIBUTE_TYPES.map((type) => ({\n types: [type],\n attributes: {\n htmlAttributes: {\n default: null,\n // A new paragraph doesn't take the style of the one it splits from.\n keepOnSplit: false,\n parseHTML: (element: HTMLElement) =>\n readAttributes(element, OWN_ATTRIBUTES[type]),\n renderHTML: (attrs: Record<string, unknown>) => getHtmlAttributes(attrs),\n },\n },\n })),\n {\n types: ['paragraph'],\n attributes: {\n explicit: {\n default: false,\n parseHTML: (element: HTMLElement) =>\n element.parentElement?.tagName === 'LI',\n renderHTML: (attrs: Record<string, unknown>) =>\n attrs.explicit === true ? {} : { [IMPLICIT_PARAGRAPH]: '' },\n },\n },\n },\n ];\n },\n});\n"],"mappings":";;;;;;;AAOA,IAAaC,qBAAqB;;AAGlC,IAAaC,kBAAkB;;AAG/B,IAAaC,cAAc;;;;;AAM3B,IAAaC,YAAY;;AAGzB,IAAMC,sBAAsB;CAACJ;CAAoBC;CAAiBC;CAAaC;AAAS;;;;AAKxF,IAAME,iBAA8D;CAChEG,aAAa,CAAC,SAAS,MAAM;CAC7BC,MAAM;EAAC;EAAQ;EAAU;EAAO;EAAS;CAAO;AACpD;;AAGA,IAAaC,uBAAuB;CAChC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AAAa;;AAIjB,IAAME,iCAAiB,IAAIC,IAAI;CAC3B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AAAY,CACf;;;;;;;AAQD,SAAgBC,kBAAkBC,MAAcC,OAAwB;CACpE,MAAMC,YAAYF,KAAKG,YAAY;CACnC,IAAID,UAAUE,WAAW,IAAI,KAAKF,cAAc,UAC5C,OAAO;CAEX,IAAI,CAACL,eAAeQ,IAAIH,SAAS,GAC7B,OAAO;CAGX,MAAMI,MAAMC,MAAMC,KAAKP,KAAK,CAAC,CACxBQ,QAAQC,cAAc;EACnB,MAAMC,OAAOD,UAAUE,WAAW,CAAC;EACnC,OAAOD,OAAO,OAASA,OAAO,OAAQA,OAAO;CACjD,CAAC,CAAC,CACDE,KAAK,EAAE,CAAC,CACRV,YAAY;CACjB,OAAO,yCAAyCW,KAAKR,GAAG;AAC5D;;;;;AAMA,SAAgBS,wBAAwBC,YAA6C;CACjF,IAAIA,eAAe,QAAQ,OAAOA,eAAe,UAC7C,OAAO,CAAC;CAEZ,OAAOC,OAAOC,YACVD,OAAOE,QAAQH,UAAU,CAAC,CAACP,QACtBW,UACG,OAAOA,MAAM,OAAO,YAAY,CAACrB,kBAAkBqB,MAAM,IAAIA,MAAM,EAAE,CAC7E,CACJ;AACJ;;;;;AAMA,SAAgBC,eACZC,SACAE,OAA0B,CAAA,GACG;CAC7B,MAAMR,aAAaT,MAAMC,KAAKc,QAAQN,UAAU,CAAC,CAACP,QAC7CP,cACG,CAACb,oBAAoBoC,SAASvB,UAAUF,IAAI,KAC5C,CAACwB,KAAKC,SAASvB,UAAUF,IAAI,KAC7B,CAACD,kBAAkBG,UAAUF,MAAME,UAAUD,KAAK,CAC1D;CACA,OAAOe,WAAWU,SAAS,IACrBT,OAAOC,YAAYF,WAAWW,KAAKzB,cAAc,CAACA,UAAUF,MAAME,UAAUD,KAAK,CAAC,CAAC,IACnF;AACV;;AAGA,SAAgB2B,kBAAkBC,OAAwD;CACtF,OAAOd,wBAAwBc,MAAMC,cAAc;AACvD;;;;;;AAOA,IAAaC,iBAAiB/C,UAAUgD,OAAO;CAC3ChC,MAAM;CAENiC,sBAAsB;EAClB,OAAO,CACH,GAAGtC,qBAAqBgC,KAAKO,UAAU;GACnCC,OAAO,CAACD,IAAI;GACZlB,YAAY,EACRc,gBAAgB;IACZM,SAAS;IAETC,aAAa;IACbC,YAAYhB,YACRD,eAAeC,SAAShC,eAAe4C,KAAK;IAChDK,aAAaV,UAAmCD,kBAAkBC,KAAK;GAC3E,EACJ;EACJ,EAAE,GACF;GACIM,OAAO,CAAC,WAAW;GACnBnB,YAAY,EACRwB,UAAU;IACNJ,SAAS;IACTE,YAAYhB,YACRA,QAAQmB,eAAeC,YAAY;IACvCH,aAAaV,UACTA,MAAMW,aAAa,OAAO,CAAC,IAAI,GAAGvD,qBAAqB,GAAG;GAClE,EACJ;EACJ,CAAC;CAET;AACJ,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { AnyExtension } from '@tiptap/core';
2
+ import { HtmlAttributes } from './attributes.js';
3
+ import { HtmlBlock, HtmlInline, HtmlMark, type HtmlNodeOptions } from './raw.js';
4
+ export interface RichTextExtensionsOptions {
5
+ /** TipTap extensions of the project. One with the name of a built-in extension replaces it. */
6
+ extensions?: readonly AnyExtension[];
7
+ /** Text shown in the empty editor. */
8
+ placeholder?: string;
9
+ /** How kept HTML shows in the editor. */
10
+ html?: Partial<HtmlNodeOptions>;
11
+ }
12
+ /**
13
+ * The TipTap extensions of the rich text field. Their schema reads everything the field may hold,
14
+ * whatever its toolbar offers: every heading level, the marks, attributes, and HTML it doesn't
15
+ * edit, kept as it was written.
16
+ */
17
+ export declare function createRichTextExtensions({ extensions, placeholder, html, }?: RichTextExtensionsOptions): AnyExtension[];
18
+ export { HtmlAttributes, HtmlBlock, HtmlInline, HtmlMark };
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/extensions/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAYjD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG9C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,OAAO,CAAC;AA8B9E,MAAM,WAAW,yBAAyB;IACtC,+FAA+F;IAC/F,UAAU,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IACrC,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,IAAI,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;CACnC;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,EACrC,UAAe,EACf,WAAW,EACX,IAAS,GACZ,GAAE,yBAA8B,GAAG,YAAY,EAAE,CAoCjD;AAED,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC"}