@verbb/plugin-kit-tiptap-core 2.0.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/CHANGELOG.md +11 -0
- package/LICENSE.md +21 -0
- package/README.md +36 -0
- package/dist/extensions/create-extensions.d.ts +13 -0
- package/dist/extensions/create-extensions.d.ts.map +1 -0
- package/dist/extensions/create-extensions.js +92 -0
- package/dist/extensions/create-extensions.js.map +1 -0
- package/dist/extensions/index.d.ts +6 -0
- package/dist/extensions/index.d.ts.map +1 -0
- package/dist/extensions/index.js +4 -0
- package/dist/extensions/one-liner-document.d.ts +2 -0
- package/dist/extensions/one-liner-document.d.ts.map +1 -0
- package/dist/extensions/one-liner-document.js +7 -0
- package/dist/extensions/one-liner-document.js.map +1 -0
- package/dist/extensions/variable-tag.d.ts +7 -0
- package/dist/extensions/variable-tag.d.ts.map +1 -0
- package/dist/extensions/variable-tag.js +156 -0
- package/dist/extensions/variable-tag.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/links/commands.d.ts +9 -0
- package/dist/links/commands.d.ts.map +1 -0
- package/dist/links/commands.js +63 -0
- package/dist/links/commands.js.map +1 -0
- package/dist/links/craft-element.d.ts +28 -0
- package/dist/links/craft-element.d.ts.map +1 -0
- package/dist/links/craft-element.js +80 -0
- package/dist/links/craft-element.js.map +1 -0
- package/dist/links/extension.d.ts +3 -0
- package/dist/links/extension.d.ts.map +1 -0
- package/dist/links/extension.js +17 -0
- package/dist/links/extension.js.map +1 -0
- package/dist/links/index.d.ts +5 -0
- package/dist/links/index.d.ts.map +1 -0
- package/dist/links/index.js +4 -0
- package/dist/links/types.d.ts +62 -0
- package/dist/links/types.d.ts.map +1 -0
- package/dist/links/types.js +0 -0
- package/dist/serialization/editor.d.ts +9 -0
- package/dist/serialization/editor.d.ts.map +1 -0
- package/dist/serialization/editor.js +112 -0
- package/dist/serialization/editor.js.map +1 -0
- package/dist/serialization/input.d.ts +55 -0
- package/dist/serialization/input.d.ts.map +1 -0
- package/dist/serialization/input.js +293 -0
- package/dist/serialization/input.js.map +1 -0
- package/dist/toolbar/button-registry.d.ts +14 -0
- package/dist/toolbar/button-registry.d.ts.map +1 -0
- package/dist/toolbar/button-registry.js +114 -0
- package/dist/toolbar/button-registry.js.map +1 -0
- package/dist/toolbar/index.d.ts +3 -0
- package/dist/toolbar/index.d.ts.map +1 -0
- package/dist/toolbar/index.js +3 -0
- package/dist/toolbar/toolbar-schema.d.ts +66 -0
- package/dist/toolbar/toolbar-schema.d.ts.map +1 -0
- package/dist/toolbar/toolbar-schema.js +340 -0
- package/dist/toolbar/toolbar-schema.js.map +1 -0
- package/dist/types/variable-option.d.ts +10 -0
- package/dist/types/variable-option.d.ts.map +1 -0
- package/dist/types/variable-option.js +0 -0
- package/package.json +99 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
//#region src/links/craft-element.ts
|
|
2
|
+
function isLinkOptionsArray(value) {
|
|
3
|
+
return Array.isArray(value) && value.length > 0;
|
|
4
|
+
}
|
|
5
|
+
function getCraftLinkOptions(linkOptions) {
|
|
6
|
+
if (!linkOptions) return [];
|
|
7
|
+
if (isLinkOptionsArray(linkOptions)) return linkOptions;
|
|
8
|
+
const items = [];
|
|
9
|
+
if (linkOptions.linkToEntry) items.push({
|
|
10
|
+
...linkOptions.linkToEntry,
|
|
11
|
+
optionTitle: "Link to an entry"
|
|
12
|
+
});
|
|
13
|
+
if (linkOptions.linkToAsset) items.push({
|
|
14
|
+
...linkOptions.linkToAsset,
|
|
15
|
+
optionTitle: "Link to an asset"
|
|
16
|
+
});
|
|
17
|
+
if (linkOptions.linkToCategory) items.push({
|
|
18
|
+
...linkOptions.linkToCategory,
|
|
19
|
+
optionTitle: "Link to a category"
|
|
20
|
+
});
|
|
21
|
+
return items;
|
|
22
|
+
}
|
|
23
|
+
function getLinkOptionsElementSiteId(linkOptions) {
|
|
24
|
+
if (!linkOptions || isLinkOptionsArray(linkOptions)) return;
|
|
25
|
+
return linkOptions.elementSiteId;
|
|
26
|
+
}
|
|
27
|
+
function hasCraftLinkOptions(linkOptions) {
|
|
28
|
+
return getCraftLinkOptions(linkOptions).length > 0;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Build a Craft element link URL with the standard ref fragment:
|
|
32
|
+
* `https://example.com/page#refHandle:123@1`
|
|
33
|
+
*/
|
|
34
|
+
function buildCraftElementLinkUrl(element, refHandle) {
|
|
35
|
+
return `${element.url || ""}#${refHandle}:${element.id}@${element.siteId}`;
|
|
36
|
+
}
|
|
37
|
+
/** Parse a Craft element link URL back into its parts. */
|
|
38
|
+
function parseCraftElementLink(href) {
|
|
39
|
+
const hashIndex = href.indexOf("#");
|
|
40
|
+
if (hashIndex === -1) return null;
|
|
41
|
+
const baseUrl = href.slice(0, hashIndex);
|
|
42
|
+
const match = href.slice(hashIndex + 1).match(/^([^:]+):(\d+)@(\d+)$/);
|
|
43
|
+
if (!match) return null;
|
|
44
|
+
return {
|
|
45
|
+
baseUrl,
|
|
46
|
+
refHandle: match[1],
|
|
47
|
+
id: Number(match[2]),
|
|
48
|
+
siteId: Number(match[3])
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function isCraftElementLink(href) {
|
|
52
|
+
return parseCraftElementLink(href) !== null;
|
|
53
|
+
}
|
|
54
|
+
function buildCraftElementSelectorStorageKey(linkSelectorStorageKeyPrefix, elementType) {
|
|
55
|
+
return `${linkSelectorStorageKeyPrefix}.${elementType}`;
|
|
56
|
+
}
|
|
57
|
+
/** Open Craft's element selector modal and return a Plugin Kit link URL on selection. */
|
|
58
|
+
function openCraftElementLinkSelector({ config, elementSiteId, linkSelectorStorageKeyPrefix, getSelectedText, onSelect, host }) {
|
|
59
|
+
if (!linkSelectorStorageKeyPrefix) throw new Error("Craft element links require \"linkSelectorStorageKeyPrefix\".");
|
|
60
|
+
host.openElementSelector(config.elementType, {
|
|
61
|
+
storageKey: buildCraftElementSelectorStorageKey(linkSelectorStorageKeyPrefix, config.elementType),
|
|
62
|
+
sources: config.sources,
|
|
63
|
+
criteria: config.criteria,
|
|
64
|
+
defaultSiteId: elementSiteId,
|
|
65
|
+
autoFocusSearchBox: false,
|
|
66
|
+
onSelect: (elements) => {
|
|
67
|
+
if (!elements?.length) return;
|
|
68
|
+
const [element] = elements;
|
|
69
|
+
onSelect({
|
|
70
|
+
url: buildCraftElementLinkUrl(element, config.refHandle),
|
|
71
|
+
text: getSelectedText() || element.label || ""
|
|
72
|
+
});
|
|
73
|
+
},
|
|
74
|
+
closeOtherModals: false
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
//#endregion
|
|
78
|
+
export { buildCraftElementLinkUrl, buildCraftElementSelectorStorageKey, getCraftLinkOptions, getLinkOptionsElementSiteId, hasCraftLinkOptions, isCraftElementLink, isLinkOptionsArray, openCraftElementLinkSelector, parseCraftElementLink };
|
|
79
|
+
|
|
80
|
+
//# sourceMappingURL=craft-element.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"craft-element.js","names":[],"sources":["../../src/links/craft-element.ts"],"sourcesContent":["import type {\n CraftSelectedElement,\n ElementSelectorHost,\n LinkElementConfig,\n LinkOptionSchemaItem,\n LinkOptionsInput,\n ParsedCraftElementLink,\n} from './types.js';\n\nexport function isLinkOptionsArray(value: LinkOptionsInput | undefined): value is LinkOptionSchemaItem[] {\n return Array.isArray(value) && value.length > 0;\n}\n\nexport function getCraftLinkOptions(linkOptions: LinkOptionsInput | undefined): LinkOptionSchemaItem[] {\n if (!linkOptions) {\n return [];\n }\n\n if (isLinkOptionsArray(linkOptions)) {\n return linkOptions;\n }\n\n const items: LinkOptionSchemaItem[] = [];\n\n if (linkOptions.linkToEntry) {\n items.push({ ...linkOptions.linkToEntry, optionTitle: 'Link to an entry' });\n }\n\n if (linkOptions.linkToAsset) {\n items.push({ ...linkOptions.linkToAsset, optionTitle: 'Link to an asset' });\n }\n\n if (linkOptions.linkToCategory) {\n items.push({ ...linkOptions.linkToCategory, optionTitle: 'Link to a category' });\n }\n\n return items;\n}\n\nexport function getLinkOptionsElementSiteId(linkOptions: LinkOptionsInput | undefined): number | undefined {\n if (!linkOptions || isLinkOptionsArray(linkOptions)) {\n return undefined;\n }\n\n return linkOptions.elementSiteId;\n}\n\nexport function hasCraftLinkOptions(linkOptions: LinkOptionsInput | undefined): boolean {\n return getCraftLinkOptions(linkOptions).length > 0;\n}\n\n/**\n * Build a Craft element link URL with the standard ref fragment:\n * `https://example.com/page#refHandle:123@1`\n */\nexport function buildCraftElementLinkUrl(\n element: CraftSelectedElement,\n refHandle: string,\n): string {\n return `${element.url || ''}#${refHandle}:${element.id}@${element.siteId}`;\n}\n\n/** Parse a Craft element link URL back into its parts. */\nexport function parseCraftElementLink(href: string): ParsedCraftElementLink | null {\n const hashIndex = href.indexOf('#');\n\n if (hashIndex === -1) {\n return null;\n }\n\n const baseUrl = href.slice(0, hashIndex);\n const fragment = href.slice(hashIndex + 1);\n const match = fragment.match(/^([^:]+):(\\d+)@(\\d+)$/);\n\n if (!match) {\n return null;\n }\n\n return {\n baseUrl,\n refHandle: match[1],\n id: Number(match[2]),\n siteId: Number(match[3]),\n };\n}\n\nexport function isCraftElementLink(href: string): boolean {\n return parseCraftElementLink(href) !== null;\n}\n\nexport function buildCraftElementSelectorStorageKey(\n linkSelectorStorageKeyPrefix: string,\n elementType: string,\n): string {\n return `${linkSelectorStorageKeyPrefix}.${elementType}`;\n}\n\nexport type OpenCraftElementLinkSelectorParams = {\n config: LinkElementConfig;\n elementSiteId?: number;\n linkSelectorStorageKeyPrefix?: string;\n getSelectedText: () => string;\n onSelect: (result: { url: string; text: string }) => void;\n host: ElementSelectorHost;\n};\n\n/** Open Craft's element selector modal and return a Plugin Kit link URL on selection. */\nexport function openCraftElementLinkSelector({\n config,\n elementSiteId,\n linkSelectorStorageKeyPrefix,\n getSelectedText,\n onSelect,\n host,\n}: OpenCraftElementLinkSelectorParams): void {\n if (!linkSelectorStorageKeyPrefix) {\n throw new Error('Craft element links require \"linkSelectorStorageKeyPrefix\".');\n }\n\n host.openElementSelector(config.elementType, {\n storageKey: buildCraftElementSelectorStorageKey(linkSelectorStorageKeyPrefix, config.elementType),\n sources: config.sources,\n criteria: config.criteria,\n defaultSiteId: elementSiteId,\n autoFocusSearchBox: false,\n onSelect: (elements) => {\n if (!elements?.length) {\n return;\n }\n\n const [element] = elements;\n const url = buildCraftElementLinkUrl(element, config.refHandle);\n const text = getSelectedText() || element.label || '';\n\n onSelect({ url, text });\n },\n closeOtherModals: false,\n });\n}\n"],"mappings":";AASA,SAAgB,mBAAmB,OAAsE;AACrG,QAAO,MAAM,QAAQ,MAAM,IAAI,MAAM,SAAS;;AAGlD,SAAgB,oBAAoB,aAAmE;AACnG,KAAI,CAAC,YACD,QAAO,EAAE;AAGb,KAAI,mBAAmB,YAAY,CAC/B,QAAO;CAGX,MAAM,QAAgC,EAAE;AAExC,KAAI,YAAY,YACZ,OAAM,KAAK;EAAE,GAAG,YAAY;EAAa,aAAa;EAAoB,CAAC;AAG/E,KAAI,YAAY,YACZ,OAAM,KAAK;EAAE,GAAG,YAAY;EAAa,aAAa;EAAoB,CAAC;AAG/E,KAAI,YAAY,eACZ,OAAM,KAAK;EAAE,GAAG,YAAY;EAAgB,aAAa;EAAsB,CAAC;AAGpF,QAAO;;AAGX,SAAgB,4BAA4B,aAA+D;AACvG,KAAI,CAAC,eAAe,mBAAmB,YAAY,CAC/C;AAGJ,QAAO,YAAY;;AAGvB,SAAgB,oBAAoB,aAAoD;AACpF,QAAO,oBAAoB,YAAY,CAAC,SAAS;;;;;;AAOrD,SAAgB,yBACZ,SACA,WACM;AACN,QAAO,GAAG,QAAQ,OAAO,GAAG,GAAG,UAAU,GAAG,QAAQ,GAAG,GAAG,QAAQ;;;AAItE,SAAgB,sBAAsB,MAA6C;CAC/E,MAAM,YAAY,KAAK,QAAQ,IAAI;AAEnC,KAAI,cAAc,GACd,QAAO;CAGX,MAAM,UAAU,KAAK,MAAM,GAAG,UAAU;CAExC,MAAM,QADW,KAAK,MAAM,YAAY,EAC1B,CAAS,MAAM,wBAAwB;AAErD,KAAI,CAAC,MACD,QAAO;AAGX,QAAO;EACH;EACA,WAAW,MAAM;EACjB,IAAI,OAAO,MAAM,GAAG;EACpB,QAAQ,OAAO,MAAM,GAAG;EAC3B;;AAGL,SAAgB,mBAAmB,MAAuB;AACtD,QAAO,sBAAsB,KAAK,KAAK;;AAG3C,SAAgB,oCACZ,8BACA,aACM;AACN,QAAO,GAAG,6BAA6B,GAAG;;;AAa9C,SAAgB,6BAA6B,EACzC,QACA,eACA,8BACA,iBACA,UACA,QACyC;AACzC,KAAI,CAAC,6BACD,OAAM,IAAI,MAAM,gEAA8D;AAGlF,MAAK,oBAAoB,OAAO,aAAa;EACzC,YAAY,oCAAoC,8BAA8B,OAAO,YAAY;EACjG,SAAS,OAAO;EAChB,UAAU,OAAO;EACjB,eAAe;EACf,oBAAoB;EACpB,WAAW,aAAa;AACpB,OAAI,CAAC,UAAU,OACX;GAGJ,MAAM,CAAC,WAAW;AAIlB,YAAS;IAAE,KAHC,yBAAyB,SAAS,OAAO,UAG1C;IAAK,MAFH,iBAAiB,IAAI,QAAQ,SAAS;IAE7B,CAAC;;EAE3B,kBAAkB;EACrB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../../src/links/extension.ts"],"names":[],"mappings":"AAEA,oEAAoE;AACpE,wBAAgB,mBAAmB,mFAMlC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import Link from "@tiptap/extension-link";
|
|
2
|
+
//#region src/links/extension.ts
|
|
3
|
+
/** Shared Tiptap link mark configuration for Plugin Kit editors. */
|
|
4
|
+
function createLinkExtension() {
|
|
5
|
+
return Link.configure({
|
|
6
|
+
openOnClick: false,
|
|
7
|
+
enableClickSelection: false,
|
|
8
|
+
HTMLAttributes: {
|
|
9
|
+
target: null,
|
|
10
|
+
rel: null
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
export { createLinkExtension };
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=extension.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension.js","names":[],"sources":["../../src/links/extension.ts"],"sourcesContent":["import Link from '@tiptap/extension-link';\n\n/** Shared Tiptap link mark configuration for Plugin Kit editors. */\nexport function createLinkExtension() {\n return Link.configure({\n openOnClick: false,\n enableClickSelection: false,\n HTMLAttributes: { target: null, rel: null },\n });\n}\n"],"mappings":";;;AAGA,SAAgB,sBAAsB;AAClC,QAAO,KAAK,UAAU;EAClB,aAAa;EACb,sBAAsB;EACtB,gBAAgB;GAAE,QAAQ;GAAM,KAAK;GAAM;EAC9C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/links/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { createLinkExtension } from "./extension.js";
|
|
2
|
+
import { buildCraftElementLinkUrl, buildCraftElementSelectorStorageKey, getCraftLinkOptions, getLinkOptionsElementSiteId, hasCraftLinkOptions, isCraftElementLink, isLinkOptionsArray, openCraftElementLinkSelector, parseCraftElementLink } from "./craft-element.js";
|
|
3
|
+
import { applyLinkToEditor, buildLinkMarkAttributes, getLinkEditState, getLinkOpenInNewTab, getSelectedText, unsetLinkFromEditor } from "./commands.js";
|
|
4
|
+
export { applyLinkToEditor, buildCraftElementLinkUrl, buildCraftElementSelectorStorageKey, buildLinkMarkAttributes, createLinkExtension, getCraftLinkOptions, getLinkEditState, getLinkOpenInNewTab, getLinkOptionsElementSiteId, getSelectedText, hasCraftLinkOptions, isCraftElementLink, isLinkOptionsArray, openCraftElementLinkSelector, parseCraftElementLink, unsetLinkFromEditor };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export type LinkElementConfig = {
|
|
2
|
+
elementType: string;
|
|
3
|
+
refHandle: string;
|
|
4
|
+
sources?: string[];
|
|
5
|
+
criteria?: Record<string, unknown>;
|
|
6
|
+
};
|
|
7
|
+
export type LinkOptionSchemaItem = LinkElementConfig & {
|
|
8
|
+
optionTitle: string;
|
|
9
|
+
};
|
|
10
|
+
export type LinkOptions = {
|
|
11
|
+
elementSiteId?: number;
|
|
12
|
+
linkToEntry?: LinkElementConfig;
|
|
13
|
+
linkToAsset?: LinkElementConfig;
|
|
14
|
+
linkToCategory?: LinkElementConfig;
|
|
15
|
+
};
|
|
16
|
+
/** linkOptions can be the object format above, or an array from schema. */
|
|
17
|
+
export type LinkOptionsInput = LinkOptions | LinkOptionSchemaItem[];
|
|
18
|
+
export type CraftSelectedElement = {
|
|
19
|
+
id?: number;
|
|
20
|
+
siteId?: number;
|
|
21
|
+
label?: string;
|
|
22
|
+
url?: string;
|
|
23
|
+
};
|
|
24
|
+
export type ParsedCraftElementLink = {
|
|
25
|
+
baseUrl: string;
|
|
26
|
+
refHandle: string;
|
|
27
|
+
id: number;
|
|
28
|
+
siteId: number;
|
|
29
|
+
};
|
|
30
|
+
export type ElementSelectorOpenOptions = {
|
|
31
|
+
storageKey: string;
|
|
32
|
+
sources?: string[];
|
|
33
|
+
criteria?: Record<string, unknown>;
|
|
34
|
+
defaultSiteId?: number;
|
|
35
|
+
autoFocusSearchBox?: boolean;
|
|
36
|
+
onSelect: (elements: CraftSelectedElement[]) => void;
|
|
37
|
+
closeOtherModals?: boolean;
|
|
38
|
+
};
|
|
39
|
+
export type ElementSelectorHost = {
|
|
40
|
+
openElementSelector: (elementType: string, options: ElementSelectorOpenOptions) => void;
|
|
41
|
+
};
|
|
42
|
+
export type InsertLinkDialogState = {
|
|
43
|
+
url: string;
|
|
44
|
+
text: string;
|
|
45
|
+
openInNewTab: boolean;
|
|
46
|
+
};
|
|
47
|
+
export type InsertLinkParams = InsertLinkDialogState & {
|
|
48
|
+
from?: number;
|
|
49
|
+
to?: number;
|
|
50
|
+
};
|
|
51
|
+
export type LinkMarkAttributes = {
|
|
52
|
+
href: string;
|
|
53
|
+
target?: string | null;
|
|
54
|
+
};
|
|
55
|
+
export type LinkEditState = {
|
|
56
|
+
from: number;
|
|
57
|
+
to: number;
|
|
58
|
+
href: string;
|
|
59
|
+
text: string;
|
|
60
|
+
openInNewTab: boolean;
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/links/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,iBAAiB,GAAG;IACnD,WAAW,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,cAAc,CAAC,EAAE,iBAAiB,CAAC;CACtC,CAAC;AAEF,2EAA2E;AAC3E,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,oBAAoB,EAAE,CAAC;AAEpE,MAAM,MAAM,oBAAoB,GAAG;IAC/B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,EAAE,CAAC,QAAQ,EAAE,oBAAoB,EAAE,KAAK,IAAI,CAAC;IACrD,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAC9B,mBAAmB,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,0BAA0B,KAAK,IAAI,CAAC;CAC3F,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,qBAAqB,GAAG;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,CAAC;CACzB,CAAC"}
|
|
File without changes
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { JSONContent } from '@tiptap/core';
|
|
2
|
+
type NormalizeContentOptions = {
|
|
3
|
+
trailingCursorText?: string;
|
|
4
|
+
};
|
|
5
|
+
export declare const normalizeContentArray: (content: unknown, { trailingCursorText }?: NormalizeContentOptions) => JSONContent[];
|
|
6
|
+
export declare const valueToContent: (value: unknown, options?: NormalizeContentOptions) => JSONContent | null;
|
|
7
|
+
export declare const getFatalTiptapContentError: (value: unknown) => string;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=editor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../src/serialization/editor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,KAAK,uBAAuB,GAAG;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAsBF,eAAO,MAAM,qBAAqB,GAC9B,SAAS,OAAO,EAChB,yBAAwB,uBAA4B,KACrD,WAAW,EAwCb,CAAC;AAEF,eAAO,MAAM,cAAc,GACvB,OAAO,OAAO,EACd,UAAS,uBAA4B,KACtC,WAAW,GAAG,IAgDhB,CAAC;AAEF,eAAO,MAAM,0BAA0B,GAAI,OAAO,OAAO,KAAG,MA8B3D,CAAC"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
//#region src/serialization/editor.ts
|
|
2
|
+
var isJsonContent = (value) => {
|
|
3
|
+
return Boolean(value) && typeof value === "object";
|
|
4
|
+
};
|
|
5
|
+
var withTrailingCursorText = (content, trailingCursorText) => {
|
|
6
|
+
if (!trailingCursorText || !content.length) return content;
|
|
7
|
+
if (content[content.length - 1].type !== "variableTag") return content;
|
|
8
|
+
return [...content, {
|
|
9
|
+
type: "text",
|
|
10
|
+
text: trailingCursorText
|
|
11
|
+
}];
|
|
12
|
+
};
|
|
13
|
+
var normalizeContentArray = (content, { trailingCursorText } = {}) => {
|
|
14
|
+
if (!Array.isArray(content)) return [];
|
|
15
|
+
return withTrailingCursorText(content.flatMap((node) => {
|
|
16
|
+
if (!node) return [];
|
|
17
|
+
if (Array.isArray(node)) return normalizeContentArray(node, { trailingCursorText });
|
|
18
|
+
if (typeof node !== "object") return [];
|
|
19
|
+
if (!("type" in node)) {
|
|
20
|
+
if (isJsonContent(node) && Array.isArray(node.content)) return normalizeContentArray(node.content, { trailingCursorText });
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
if (isJsonContent(node) && node.type === "text" && typeof node.text === "string") {
|
|
24
|
+
const text = node.text.replace(/[\u200B\u2060]/g, "");
|
|
25
|
+
return text ? [{
|
|
26
|
+
...node,
|
|
27
|
+
text
|
|
28
|
+
}] : [];
|
|
29
|
+
}
|
|
30
|
+
if (isJsonContent(node) && Array.isArray(node.content)) {
|
|
31
|
+
const cleaned = normalizeContentArray(node.content, { trailingCursorText });
|
|
32
|
+
return [{
|
|
33
|
+
...node,
|
|
34
|
+
content: cleaned
|
|
35
|
+
}];
|
|
36
|
+
}
|
|
37
|
+
return isJsonContent(node) ? [node] : [];
|
|
38
|
+
}), trailingCursorText);
|
|
39
|
+
};
|
|
40
|
+
var valueToContent = (value, options = {}) => {
|
|
41
|
+
if (!value) return null;
|
|
42
|
+
if (Array.isArray(value)) {
|
|
43
|
+
const cleaned = normalizeContentArray(value, options);
|
|
44
|
+
return cleaned.length ? {
|
|
45
|
+
type: "doc",
|
|
46
|
+
content: cleaned
|
|
47
|
+
} : null;
|
|
48
|
+
}
|
|
49
|
+
if (isJsonContent(value)) {
|
|
50
|
+
if (value.type === "doc" && Array.isArray(value.content)) {
|
|
51
|
+
const cleaned = normalizeContentArray(value.content, options);
|
|
52
|
+
return cleaned.length ? {
|
|
53
|
+
...value,
|
|
54
|
+
content: cleaned
|
|
55
|
+
} : null;
|
|
56
|
+
}
|
|
57
|
+
if (Array.isArray(value.content)) {
|
|
58
|
+
const cleaned = normalizeContentArray(value.content, options);
|
|
59
|
+
return cleaned.length ? {
|
|
60
|
+
type: "doc",
|
|
61
|
+
content: cleaned
|
|
62
|
+
} : null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (typeof value === "string") try {
|
|
66
|
+
const parsed = JSON.parse(value);
|
|
67
|
+
if (Array.isArray(parsed)) {
|
|
68
|
+
const cleaned = normalizeContentArray(parsed, options);
|
|
69
|
+
return cleaned.length ? {
|
|
70
|
+
type: "doc",
|
|
71
|
+
content: cleaned
|
|
72
|
+
} : null;
|
|
73
|
+
}
|
|
74
|
+
if (isJsonContent(parsed)) {
|
|
75
|
+
if (parsed.type === "doc" && Array.isArray(parsed.content)) {
|
|
76
|
+
const cleaned = normalizeContentArray(parsed.content, options);
|
|
77
|
+
return cleaned.length ? {
|
|
78
|
+
...parsed,
|
|
79
|
+
content: cleaned
|
|
80
|
+
} : null;
|
|
81
|
+
}
|
|
82
|
+
if (Array.isArray(parsed.content)) {
|
|
83
|
+
const cleaned = normalizeContentArray(parsed.content, options);
|
|
84
|
+
return cleaned.length ? {
|
|
85
|
+
type: "doc",
|
|
86
|
+
content: cleaned
|
|
87
|
+
} : null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
} catch {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
return null;
|
|
94
|
+
};
|
|
95
|
+
var getFatalTiptapContentError = (value) => {
|
|
96
|
+
const content = valueToContent(value);
|
|
97
|
+
if (!content) return "";
|
|
98
|
+
const visit = (node) => {
|
|
99
|
+
if (!node || typeof node !== "object") return false;
|
|
100
|
+
const jsonNode = node;
|
|
101
|
+
if (jsonNode.type === "text" && typeof jsonNode.text === "string" && jsonNode.text === "") return true;
|
|
102
|
+
if (!Array.isArray(jsonNode.content)) return false;
|
|
103
|
+
return jsonNode.content.some((child) => {
|
|
104
|
+
return visit(child);
|
|
105
|
+
});
|
|
106
|
+
};
|
|
107
|
+
return visit(content) ? "This field contains invalid rich-text content. The editor could not fully parse the stored document, so some content may not be shown until it is repaired and saved again." : "";
|
|
108
|
+
};
|
|
109
|
+
//#endregion
|
|
110
|
+
export { getFatalTiptapContentError, normalizeContentArray, valueToContent };
|
|
111
|
+
|
|
112
|
+
//# sourceMappingURL=editor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editor.js","names":[],"sources":["../../src/serialization/editor.ts"],"sourcesContent":["import type { JSONContent } from '@tiptap/core';\n\ntype NormalizeContentOptions = {\n trailingCursorText?: string;\n};\n\nconst isJsonContent = (value: unknown): value is JSONContent => {\n return Boolean(value) && typeof value === 'object';\n};\n\nconst withTrailingCursorText = (\n content: JSONContent[],\n trailingCursorText?: string,\n): JSONContent[] => {\n if (!trailingCursorText || !content.length) {\n return content;\n }\n\n const lastNode = content[content.length - 1] as { type?: string };\n if (lastNode.type !== 'variableTag') {\n return content;\n }\n\n return [...content, { type: 'text', text: trailingCursorText }];\n};\n\nexport const normalizeContentArray = (\n content: unknown,\n { trailingCursorText }: NormalizeContentOptions = {},\n): JSONContent[] => {\n if (!Array.isArray(content)) {\n return [];\n }\n\n const normalized = content.flatMap((node) => {\n if (!node) {\n return [];\n }\n\n if (Array.isArray(node)) {\n return normalizeContentArray(node, { trailingCursorText });\n }\n\n if (typeof node !== 'object') {\n return [];\n }\n\n if (!('type' in node)) {\n if (isJsonContent(node) && Array.isArray(node.content)) {\n return normalizeContentArray(node.content, { trailingCursorText });\n }\n\n return [];\n }\n\n if (isJsonContent(node) && node.type === 'text' && typeof node.text === 'string') {\n const text = node.text.replace(/[\\u200B\\u2060]/g, '');\n return text ? [{ ...node, text }] : [];\n }\n\n if (isJsonContent(node) && Array.isArray(node.content)) {\n const cleaned = normalizeContentArray(node.content, { trailingCursorText });\n return [{ ...node, content: cleaned }];\n }\n\n return isJsonContent(node) ? [node] : [];\n });\n\n return withTrailingCursorText(normalized, trailingCursorText);\n};\n\nexport const valueToContent = (\n value: unknown,\n options: NormalizeContentOptions = {},\n): JSONContent | null => {\n if (!value) {\n return null;\n }\n\n if (Array.isArray(value)) {\n const cleaned = normalizeContentArray(value, options);\n return cleaned.length ? { type: 'doc', content: cleaned } : null;\n }\n\n if (isJsonContent(value)) {\n if (value.type === 'doc' && Array.isArray(value.content)) {\n const cleaned = normalizeContentArray(value.content, options);\n return cleaned.length ? { ...value, content: cleaned } : null;\n }\n\n if (Array.isArray(value.content)) {\n const cleaned = normalizeContentArray(value.content, options);\n return cleaned.length ? { type: 'doc', content: cleaned } : null;\n }\n }\n\n if (typeof value === 'string') {\n try {\n const parsed = JSON.parse(value);\n\n if (Array.isArray(parsed)) {\n const cleaned = normalizeContentArray(parsed, options);\n return cleaned.length ? { type: 'doc', content: cleaned } : null;\n }\n\n if (isJsonContent(parsed)) {\n if (parsed.type === 'doc' && Array.isArray(parsed.content)) {\n const cleaned = normalizeContentArray(parsed.content, options);\n return cleaned.length ? { ...parsed, content: cleaned } : null;\n }\n\n if (Array.isArray(parsed.content)) {\n const cleaned = normalizeContentArray(parsed.content, options);\n return cleaned.length ? { type: 'doc', content: cleaned } : null;\n }\n }\n } catch {\n return null;\n }\n }\n\n return null;\n};\n\nexport const getFatalTiptapContentError = (value: unknown): string => {\n const content = valueToContent(value);\n\n if (!content) {\n return '';\n }\n\n const visit = (node: unknown): boolean => {\n if (!node || typeof node !== 'object') {\n return false;\n }\n\n const jsonNode = node as JSONContent;\n\n if (jsonNode.type === 'text' && typeof jsonNode.text === 'string' && jsonNode.text === '') {\n return true;\n }\n\n if (!Array.isArray(jsonNode.content)) {\n return false;\n }\n\n return jsonNode.content.some((child) => {\n return visit(child);\n });\n };\n\n return visit(content)\n ? 'This field contains invalid rich-text content. The editor could not fully parse the stored document, so some content may not be shown until it is repaired and saved again.'\n : '';\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Editor, JSONContent } from '@tiptap/core';
|
|
2
|
+
import { VariableOption } from '../types/variable-option.js';
|
|
3
|
+
export type VariableTagAttrs = {
|
|
4
|
+
label: string;
|
|
5
|
+
value: string;
|
|
6
|
+
openOnInsert: boolean;
|
|
7
|
+
/** True when the token did not match a known variable option (display-only). */
|
|
8
|
+
unresolved?: boolean;
|
|
9
|
+
/** Inline default when value is empty (e.g. {user:firstName|Guest}) */
|
|
10
|
+
default?: string;
|
|
11
|
+
/** Optional transform id (e.g. "round", "format"). */
|
|
12
|
+
transformerId?: string;
|
|
13
|
+
/** Optional transform params payload. */
|
|
14
|
+
transformerParams?: Record<string, unknown>;
|
|
15
|
+
};
|
|
16
|
+
export declare function dedupeVariableOptions(items: VariableOption[]): VariableOption[];
|
|
17
|
+
export declare function flattenVariableOptions(items: VariableOption[]): VariableOption[];
|
|
18
|
+
/**
|
|
19
|
+
* Build VariableTag attributes from base and selected variable options.
|
|
20
|
+
* Optional defaultIfEmpty is used when the resolved value is empty (e.g. "Guest" for {user:firstName|Guest}).
|
|
21
|
+
*/
|
|
22
|
+
export declare function buildVariableTagAttrs(baseVariable: VariableOption, selectedVariable?: VariableOption, options?: {
|
|
23
|
+
openOnInsert?: boolean;
|
|
24
|
+
defaultIfEmpty?: string;
|
|
25
|
+
transformerId?: string;
|
|
26
|
+
transformerParams?: Record<string, unknown>;
|
|
27
|
+
label?: string;
|
|
28
|
+
value?: string;
|
|
29
|
+
}): VariableTagAttrs;
|
|
30
|
+
/**
|
|
31
|
+
* Strip optional inline default from token for lookup: {user:firstName|Guest} -> {user:firstName}.
|
|
32
|
+
* Returns [tokenWithoutDefault, defaultText].
|
|
33
|
+
*/
|
|
34
|
+
export declare function parseTokenWithDefault(tokenValue: string): [string, string | undefined];
|
|
35
|
+
export declare function getReferenceBaseToken(tokenValue: string): string;
|
|
36
|
+
export declare function resolveVariableTagLabel(tokenValue: string, option: VariableOption | null): string;
|
|
37
|
+
/**
|
|
38
|
+
* Resolve variable tag attrs from a token string (e.g. '{form:name}' or '{user:firstName|Guest}').
|
|
39
|
+
*/
|
|
40
|
+
export declare function resolveVariableTagByValue(tokenValue: string, topLevelVariables: VariableOption[], allVariables: VariableOption[]): VariableTagAttrs | null;
|
|
41
|
+
/**
|
|
42
|
+
* Convert string value with {token} placeholders to Tiptap doc content.
|
|
43
|
+
*/
|
|
44
|
+
export declare function valueToContent(value: string, topLevelVariables: VariableOption[], allVariables: VariableOption[], trailingCursorText?: string): JSONContent | null;
|
|
45
|
+
/**
|
|
46
|
+
* Convert Tiptap content to string value.
|
|
47
|
+
* Content is typically editor.getJSON().content (array of block/inline nodes).
|
|
48
|
+
*/
|
|
49
|
+
export declare function contentToValue(content: unknown): string;
|
|
50
|
+
/**
|
|
51
|
+
* Replace a range in the editor with a variable tag node.
|
|
52
|
+
* @param editor - Tiptap editor instance
|
|
53
|
+
*/
|
|
54
|
+
export declare function replaceTokenWithVariable(editor: Editor, attrs: VariableTagAttrs, from: number, to: number): void;
|
|
55
|
+
//# sourceMappingURL=input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../src/serialization/input.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,MAAM,MAAM,gBAAgB,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,OAAO,CAAC;IACtB,gFAAgF;IAChF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yCAAyC;IACzC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/C,CAAC;AA0KF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE,CAe/E;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE,CAehF;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACjC,YAAY,EAAE,cAAc,EAC5B,gBAAgB,GAAE,cAA6B,EAC/C,OAAO,GAAE;IACL,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CACb,GACP,gBAAgB,CAoBlB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAGtF;AAED,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAWhE;AAcD,wBAAgB,uBAAuB,CACnC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,cAAc,GAAG,IAAI,GAC9B,MAAM,CAQR;AAoCD;;GAEG;AACH,wBAAgB,yBAAyB,CACrC,UAAU,EAAE,MAAM,EAClB,iBAAiB,EAAE,cAAc,EAAE,EACnC,YAAY,EAAE,cAAc,EAAE,GAC/B,gBAAgB,GAAG,IAAI,CA+CzB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC1B,KAAK,EAAE,MAAM,EACb,iBAAiB,EAAE,cAAc,EAAE,EACnC,YAAY,EAAE,cAAc,EAAE,EAC9B,kBAAkB,SAAW,GAC9B,WAAW,GAAG,IAAI,CA0BpB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CA4CvD;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACpC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,gBAAgB,EACvB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,GACX,IAAI,CAqBN"}
|