@blankdotpage/cake 0.1.15 → 0.1.16
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 +4 -0
- package/dist/cake/core/runtime.d.ts +32 -72
- package/dist/cake/core/runtime.d.ts.map +1 -1
- package/dist/cake/core/runtime.js +149 -85
- package/dist/cake/dom/dom-map.d.ts.map +1 -1
- package/dist/cake/dom/dom-map.js +3 -1
- package/dist/cake/dom/render.d.ts +3 -3
- package/dist/cake/dom/render.d.ts.map +1 -1
- package/dist/cake/dom/render.js +12 -27
- package/dist/cake/editor/cake-editor.d.ts +42 -5
- package/dist/cake/editor/cake-editor.d.ts.map +1 -1
- package/dist/cake/editor/cake-editor.js +228 -69
- package/dist/cake/editor/extension-types.d.ts +7 -0
- package/dist/cake/editor/extension-types.d.ts.map +1 -0
- package/dist/cake/editor/extension-types.js +1 -0
- package/dist/cake/editor/selection/selection-geometry-dom.d.ts.map +1 -1
- package/dist/cake/editor/selection/selection-geometry-dom.js +2 -1
- package/dist/cake/editor/selection/selection-layout-dom.d.ts.map +1 -1
- package/dist/cake/editor/selection/selection-layout-dom.js +2 -2
- package/dist/cake/editor/selection/selection-navigation.d.ts.map +1 -1
- package/dist/cake/editor/selection/selection-navigation.js +5 -1
- package/dist/cake/extensions/blockquote/blockquote.d.ts +2 -1
- package/dist/cake/extensions/blockquote/blockquote.d.ts.map +1 -1
- package/dist/cake/extensions/blockquote/blockquote.js +15 -12
- package/dist/cake/extensions/bold/bold.d.ts +2 -1
- package/dist/cake/extensions/bold/bold.d.ts.map +1 -1
- package/dist/cake/extensions/bold/bold.js +23 -18
- package/dist/cake/extensions/combined-emphasis/combined-emphasis.d.ts +2 -1
- package/dist/cake/extensions/combined-emphasis/combined-emphasis.d.ts.map +1 -1
- package/dist/cake/extensions/combined-emphasis/combined-emphasis.js +5 -6
- package/dist/cake/extensions/heading/heading.d.ts +2 -1
- package/dist/cake/extensions/heading/heading.d.ts.map +1 -1
- package/dist/cake/extensions/heading/heading.js +21 -15
- package/dist/cake/extensions/image/image.d.ts +2 -1
- package/dist/cake/extensions/image/image.d.ts.map +1 -1
- package/dist/cake/extensions/image/image.js +15 -12
- package/dist/cake/extensions/italic/italic.d.ts +2 -1
- package/dist/cake/extensions/italic/italic.d.ts.map +1 -1
- package/dist/cake/extensions/italic/italic.js +23 -18
- package/dist/cake/extensions/link/link-popover.d.ts +3 -15
- package/dist/cake/extensions/link/link-popover.d.ts.map +1 -1
- package/dist/cake/extensions/link/link-popover.js +30 -3
- package/dist/cake/extensions/link/link.d.ts +2 -1
- package/dist/cake/extensions/link/link.d.ts.map +1 -1
- package/dist/cake/extensions/link/link.js +23 -26
- package/dist/cake/extensions/list/list.d.ts +2 -1
- package/dist/cake/extensions/list/list.d.ts.map +1 -1
- package/dist/cake/extensions/list/list.js +13 -10
- package/dist/cake/extensions/scrollbar/index.d.ts +2 -1
- package/dist/cake/extensions/scrollbar/index.d.ts.map +1 -1
- package/dist/cake/extensions/scrollbar/index.js +10 -8
- package/dist/cake/extensions/strikethrough/strikethrough.d.ts +2 -1
- package/dist/cake/extensions/strikethrough/strikethrough.d.ts.map +1 -1
- package/dist/cake/extensions/strikethrough/strikethrough.js +23 -18
- package/dist/cake/extensions/types.d.ts +1 -1
- package/dist/cake/extensions/types.d.ts.map +1 -1
- package/dist/cake/extensions/underline/underline.d.ts +2 -1
- package/dist/cake/extensions/underline/underline.d.ts.map +1 -1
- package/dist/cake/extensions/underline/underline.js +40 -21
- package/dist/cake/index.d.ts +1 -1
- package/dist/cake/index.d.ts.map +1 -1
- package/dist/cake/react/index.d.ts.map +1 -1
- package/dist/cake/react/index.js +7 -49
- package/dist/cake/test/harness.d.ts +1 -1
- package/dist/cake/test/harness.d.ts.map +1 -1
- package/dist/cake/test/harness.js +4 -50
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -119,3 +119,7 @@ engine.destroy();
|
|
|
119
119
|
- `plainTextListExtension` - Ordered and unordered lists
|
|
120
120
|
- `scrollbarExtension` - Custom scrollbar styling
|
|
121
121
|
- `strikethroughExtension` - Strikethrough (`~~text~~`)
|
|
122
|
+
|
|
123
|
+
## Writing extensions
|
|
124
|
+
|
|
125
|
+
See [docs/extensions.md](docs/extensions.md) for the full extension API, including examples of pure logic extensions and React-based UI extensions.
|
|
@@ -1,25 +1,8 @@
|
|
|
1
1
|
import type { Block, Doc, Inline, Selection } from "./types";
|
|
2
|
-
import type {
|
|
2
|
+
import type { CakeExtension } from "../editor/extension-types";
|
|
3
|
+
export type { CakeExtension, CakeUIComponent } from "../editor/extension-types";
|
|
3
4
|
import { type CursorSourceMap } from "./mapping/cursor-source-map";
|
|
4
5
|
import type { DomRenderContext } from "../dom/types";
|
|
5
|
-
export type OverlayExtensionContext = {
|
|
6
|
-
container: HTMLElement;
|
|
7
|
-
insertText: (text: string) => void;
|
|
8
|
-
replaceText: (oldText: string, newText: string) => void;
|
|
9
|
-
getSelection: () => {
|
|
10
|
-
start: number;
|
|
11
|
-
end: number;
|
|
12
|
-
} | null;
|
|
13
|
-
executeCommand: (command: EditCommand) => boolean;
|
|
14
|
-
contentRoot?: HTMLElement;
|
|
15
|
-
overlayRoot?: HTMLElement;
|
|
16
|
-
toOverlayRect?: (rect: DOMRectReadOnly) => {
|
|
17
|
-
top: number;
|
|
18
|
-
left: number;
|
|
19
|
-
width: number;
|
|
20
|
-
height: number;
|
|
21
|
-
};
|
|
22
|
-
};
|
|
23
6
|
type BlockParseResult = {
|
|
24
7
|
block: Block;
|
|
25
8
|
nextPos: number;
|
|
@@ -105,57 +88,15 @@ export type ExtensionContext = {
|
|
|
105
88
|
serializeInline: (inline: Inline) => SerializeInlineResult;
|
|
106
89
|
serializeBlock: (block: Block) => SerializeBlockResult;
|
|
107
90
|
};
|
|
108
|
-
export type
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
toggleInline?: {
|
|
117
|
-
kind: string;
|
|
118
|
-
markers: Array<string | {
|
|
119
|
-
open: string;
|
|
120
|
-
close: string;
|
|
121
|
-
}>;
|
|
122
|
-
};
|
|
123
|
-
parseBlock?: (source: string, start: number, context: ExtensionContext) => ParseBlockResult;
|
|
124
|
-
parseInline?: (source: string, start: number, end: number, context: ExtensionContext) => ParseInlineResult;
|
|
125
|
-
serializeBlock?: (block: Block, context: ExtensionContext) => SerializeBlockResult | null;
|
|
126
|
-
serializeInline?: (inline: Inline, context: ExtensionContext) => SerializeInlineResult | null;
|
|
127
|
-
normalizeBlock?: (block: Block) => Block | null;
|
|
128
|
-
normalizeInline?: (inline: Inline) => Inline | null;
|
|
129
|
-
onEdit?: (command: EditCommand, state: RuntimeState) => EditResult | EditCommand | null;
|
|
130
|
-
onPasteText?: (text: string, state: RuntimeState) => EditCommand | null;
|
|
131
|
-
keybindings?: KeyBinding[];
|
|
132
|
-
renderInline?: (inline: Inline, context: DomRenderContext) => Node | Node[] | null;
|
|
133
|
-
renderBlock?: (block: Block, context: DomRenderContext) => Node | Node[] | null;
|
|
134
|
-
renderOverlay?: (context: OverlayExtensionContext) => ReactElement | null;
|
|
135
|
-
};
|
|
136
|
-
/**
|
|
137
|
-
* Extension config with typed custom commands.
|
|
138
|
-
*/
|
|
139
|
-
export type ExtensionConfig<TCommand extends ExtensionCommand> = Omit<CakeExtension, "onEdit"> & {
|
|
140
|
-
onEdit?: (command: EditCommand | TCommand, state: RuntimeState) => EditResult | EditCommand | TCommand | null;
|
|
91
|
+
export type DomInlineRenderer = (inline: Inline, context: DomRenderContext) => Node | Node[] | null;
|
|
92
|
+
export type DomBlockRenderer = (block: Block, context: DomRenderContext) => Node | Node[] | null;
|
|
93
|
+
export type ToggleInlineSpec = {
|
|
94
|
+
kind: string;
|
|
95
|
+
markers: Array<string | {
|
|
96
|
+
open: string;
|
|
97
|
+
close: string;
|
|
98
|
+
}>;
|
|
141
99
|
};
|
|
142
|
-
/**
|
|
143
|
-
* Define an extension with typed custom commands.
|
|
144
|
-
*
|
|
145
|
-
* @example
|
|
146
|
-
* type MyCommand = { type: "my-command"; value: number };
|
|
147
|
-
* export const myExtension = defineExtension<MyCommand>({
|
|
148
|
-
* name: "my-extension",
|
|
149
|
-
* onEdit(command, state) {
|
|
150
|
-
* if (command.type === "my-command") {
|
|
151
|
-
* // command is narrowed to MyCommand here
|
|
152
|
-
* console.log(command.value);
|
|
153
|
-
* }
|
|
154
|
-
* return null;
|
|
155
|
-
* },
|
|
156
|
-
* });
|
|
157
|
-
*/
|
|
158
|
-
export declare function defineExtension<TCommand extends ExtensionCommand>(extension: ExtensionConfig<TCommand>): CakeExtension;
|
|
159
100
|
export type RuntimeState = {
|
|
160
101
|
source: string;
|
|
161
102
|
selection: Selection;
|
|
@@ -164,7 +105,10 @@ export type RuntimeState = {
|
|
|
164
105
|
runtime: Runtime;
|
|
165
106
|
};
|
|
166
107
|
export type Runtime = {
|
|
167
|
-
|
|
108
|
+
dom: {
|
|
109
|
+
inlineRenderers: DomInlineRenderer[];
|
|
110
|
+
blockRenderers: DomBlockRenderer[];
|
|
111
|
+
};
|
|
168
112
|
parse(source: string): Doc;
|
|
169
113
|
serialize(doc: Doc): {
|
|
170
114
|
source: string;
|
|
@@ -178,6 +122,22 @@ export type Runtime = {
|
|
|
178
122
|
serializeSelectionToHtml(state: RuntimeState, selection: Selection): string;
|
|
179
123
|
applyEdit(command: EditCommand, state: RuntimeState): RuntimeState;
|
|
180
124
|
};
|
|
181
|
-
export declare function
|
|
182
|
-
export {
|
|
125
|
+
export declare function createRuntimeForTests(extensions: CakeExtension[]): Runtime;
|
|
126
|
+
export declare function createRuntimeFromRegistry(registry: {
|
|
127
|
+
toggleMarkerToSpec: Map<string, {
|
|
128
|
+
kind: string;
|
|
129
|
+
open: string;
|
|
130
|
+
close: string;
|
|
131
|
+
}>;
|
|
132
|
+
inclusiveAtEndByKind: Map<string, boolean>;
|
|
133
|
+
parseBlockFns: Array<(source: string, start: number, context: ExtensionContext) => ParseBlockResult>;
|
|
134
|
+
parseInlineFns: Array<(source: string, start: number, end: number, context: ExtensionContext) => ParseInlineResult>;
|
|
135
|
+
serializeBlockFns: Array<(block: Block, context: ExtensionContext) => SerializeBlockResult | null>;
|
|
136
|
+
serializeInlineFns: Array<(inline: Inline, context: ExtensionContext) => SerializeInlineResult | null>;
|
|
137
|
+
normalizeBlockFns: Array<(block: Block) => Block | null>;
|
|
138
|
+
normalizeInlineFns: Array<(inline: Inline) => Inline | null>;
|
|
139
|
+
onEditFns: Array<(command: EditCommand, state: RuntimeState) => EditResult | EditCommand | null>;
|
|
140
|
+
domInlineRenderers: DomInlineRenderer[];
|
|
141
|
+
domBlockRenderers: DomBlockRenderer[];
|
|
142
|
+
}): Runtime;
|
|
183
143
|
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/cake/core/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/cake/core/runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,52 +17,128 @@ export function isApplyEditCommand(command) {
|
|
|
17
17
|
command.type === "delete-backward" ||
|
|
18
18
|
command.type === "delete-forward");
|
|
19
19
|
}
|
|
20
|
-
/**
|
|
21
|
-
* Define an extension with typed custom commands.
|
|
22
|
-
*
|
|
23
|
-
* @example
|
|
24
|
-
* type MyCommand = { type: "my-command"; value: number };
|
|
25
|
-
* export const myExtension = defineExtension<MyCommand>({
|
|
26
|
-
* name: "my-extension",
|
|
27
|
-
* onEdit(command, state) {
|
|
28
|
-
* if (command.type === "my-command") {
|
|
29
|
-
* // command is narrowed to MyCommand here
|
|
30
|
-
* console.log(command.value);
|
|
31
|
-
* }
|
|
32
|
-
* return null;
|
|
33
|
-
* },
|
|
34
|
-
* });
|
|
35
|
-
*/
|
|
36
|
-
export function defineExtension(extension) {
|
|
37
|
-
return extension;
|
|
38
|
-
}
|
|
39
20
|
const defaultSelection = { start: 0, end: 0, affinity: "forward" };
|
|
40
|
-
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if (!toggle) {
|
|
45
|
-
continue;
|
|
46
|
-
}
|
|
47
|
-
for (const marker of toggle.markers) {
|
|
48
|
-
const spec = typeof marker === "string"
|
|
49
|
-
? { kind: toggle.kind, open: marker, close: marker }
|
|
50
|
-
: { kind: toggle.kind, open: marker.open, close: marker.close };
|
|
51
|
-
toggleMarkerToSpec.set(spec.open, spec);
|
|
52
|
-
}
|
|
21
|
+
function removeFromArray(arr, value) {
|
|
22
|
+
const index = arr.indexOf(value);
|
|
23
|
+
if (index === -1) {
|
|
24
|
+
return;
|
|
53
25
|
}
|
|
26
|
+
arr.splice(index, 1);
|
|
27
|
+
}
|
|
28
|
+
export function createRuntimeForTests(extensions) {
|
|
29
|
+
const toggleMarkerToSpec = new Map();
|
|
54
30
|
const inclusiveAtEndByKind = new Map();
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
31
|
+
const parseBlockFns = [];
|
|
32
|
+
const parseInlineFns = [];
|
|
33
|
+
const serializeBlockFns = [];
|
|
34
|
+
const serializeInlineFns = [];
|
|
35
|
+
const normalizeBlockFns = [];
|
|
36
|
+
const normalizeInlineFns = [];
|
|
37
|
+
const onEditFns = [];
|
|
38
|
+
const domInlineRenderers = [];
|
|
39
|
+
const domBlockRenderers = [];
|
|
40
|
+
const editor = {
|
|
41
|
+
registerInlineWrapperAffinity: (specs) => {
|
|
42
|
+
for (const spec of specs) {
|
|
43
|
+
if (!inclusiveAtEndByKind.has(spec.kind)) {
|
|
44
|
+
inclusiveAtEndByKind.set(spec.kind, spec.inclusive);
|
|
45
|
+
}
|
|
63
46
|
}
|
|
64
|
-
|
|
47
|
+
return () => {
|
|
48
|
+
for (const spec of specs) {
|
|
49
|
+
const current = inclusiveAtEndByKind.get(spec.kind);
|
|
50
|
+
if (current === spec.inclusive) {
|
|
51
|
+
inclusiveAtEndByKind.delete(spec.kind);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
},
|
|
56
|
+
registerToggleInline: (toggle) => {
|
|
57
|
+
const added = [];
|
|
58
|
+
for (const marker of toggle.markers) {
|
|
59
|
+
const spec = typeof marker === "string"
|
|
60
|
+
? { kind: toggle.kind, open: marker, close: marker }
|
|
61
|
+
: { kind: toggle.kind, open: marker.open, close: marker.close };
|
|
62
|
+
toggleMarkerToSpec.set(spec.open, spec);
|
|
63
|
+
added.push(spec);
|
|
64
|
+
}
|
|
65
|
+
return () => {
|
|
66
|
+
for (const spec of added) {
|
|
67
|
+
const current = toggleMarkerToSpec.get(spec.open);
|
|
68
|
+
if (current &&
|
|
69
|
+
current.kind === spec.kind &&
|
|
70
|
+
current.close === spec.close) {
|
|
71
|
+
toggleMarkerToSpec.delete(spec.open);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
},
|
|
76
|
+
registerParseBlock: (fn) => {
|
|
77
|
+
parseBlockFns.push(fn);
|
|
78
|
+
return () => removeFromArray(parseBlockFns, fn);
|
|
79
|
+
},
|
|
80
|
+
registerParseInline: (fn) => {
|
|
81
|
+
parseInlineFns.push(fn);
|
|
82
|
+
return () => removeFromArray(parseInlineFns, fn);
|
|
83
|
+
},
|
|
84
|
+
registerSerializeBlock: (fn) => {
|
|
85
|
+
serializeBlockFns.push(fn);
|
|
86
|
+
return () => removeFromArray(serializeBlockFns, fn);
|
|
87
|
+
},
|
|
88
|
+
registerSerializeInline: (fn) => {
|
|
89
|
+
serializeInlineFns.push(fn);
|
|
90
|
+
return () => removeFromArray(serializeInlineFns, fn);
|
|
91
|
+
},
|
|
92
|
+
registerNormalizeBlock: (fn) => {
|
|
93
|
+
normalizeBlockFns.push(fn);
|
|
94
|
+
return () => removeFromArray(normalizeBlockFns, fn);
|
|
95
|
+
},
|
|
96
|
+
registerNormalizeInline: (fn) => {
|
|
97
|
+
normalizeInlineFns.push(fn);
|
|
98
|
+
return () => removeFromArray(normalizeInlineFns, fn);
|
|
99
|
+
},
|
|
100
|
+
registerOnEdit: (fn) => {
|
|
101
|
+
onEditFns.push(fn);
|
|
102
|
+
return () => removeFromArray(onEditFns, fn);
|
|
103
|
+
},
|
|
104
|
+
registerOnPasteText: () => {
|
|
105
|
+
return () => { };
|
|
106
|
+
},
|
|
107
|
+
registerKeybindings: () => {
|
|
108
|
+
return () => { };
|
|
109
|
+
},
|
|
110
|
+
registerInlineRenderer: (fn) => {
|
|
111
|
+
domInlineRenderers.push(fn);
|
|
112
|
+
return () => removeFromArray(domInlineRenderers, fn);
|
|
113
|
+
},
|
|
114
|
+
registerBlockRenderer: (fn) => {
|
|
115
|
+
domBlockRenderers.push(fn);
|
|
116
|
+
return () => removeFromArray(domBlockRenderers, fn);
|
|
117
|
+
},
|
|
118
|
+
registerUI: () => {
|
|
119
|
+
return () => { };
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
for (const extension of extensions) {
|
|
123
|
+
extension(editor);
|
|
65
124
|
}
|
|
125
|
+
const runtime = createRuntimeFromRegistry({
|
|
126
|
+
toggleMarkerToSpec,
|
|
127
|
+
inclusiveAtEndByKind,
|
|
128
|
+
parseBlockFns,
|
|
129
|
+
parseInlineFns,
|
|
130
|
+
serializeBlockFns,
|
|
131
|
+
serializeInlineFns,
|
|
132
|
+
normalizeBlockFns,
|
|
133
|
+
normalizeInlineFns,
|
|
134
|
+
onEditFns,
|
|
135
|
+
domInlineRenderers,
|
|
136
|
+
domBlockRenderers,
|
|
137
|
+
});
|
|
138
|
+
return runtime;
|
|
139
|
+
}
|
|
140
|
+
export function createRuntimeFromRegistry(registry) {
|
|
141
|
+
const { toggleMarkerToSpec, inclusiveAtEndByKind, parseBlockFns, parseInlineFns, serializeBlockFns, serializeInlineFns, normalizeBlockFns, normalizeInlineFns, onEditFns, domInlineRenderers, domBlockRenderers, } = registry;
|
|
66
142
|
const isInclusiveAtEnd = (kind) => inclusiveAtEndByKind.get(kind) ?? true;
|
|
67
143
|
const context = {
|
|
68
144
|
parseInline: (source, start, end) => parseInlineRange(source, start, end),
|
|
@@ -70,11 +146,8 @@ export function createRuntime(extensions) {
|
|
|
70
146
|
serializeBlock: (block) => serializeBlock(block),
|
|
71
147
|
};
|
|
72
148
|
function parseBlockAt(source, start) {
|
|
73
|
-
for (const
|
|
74
|
-
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
|
-
const result = extension.parseBlock(source, start, context);
|
|
149
|
+
for (const parseBlock of parseBlockFns) {
|
|
150
|
+
const result = parseBlock(source, start, context);
|
|
78
151
|
if (result) {
|
|
79
152
|
return result;
|
|
80
153
|
}
|
|
@@ -86,11 +159,8 @@ export function createRuntime(extensions) {
|
|
|
86
159
|
let pos = start;
|
|
87
160
|
while (pos < end) {
|
|
88
161
|
let matched = false;
|
|
89
|
-
for (const
|
|
90
|
-
|
|
91
|
-
continue;
|
|
92
|
-
}
|
|
93
|
-
const result = extension.parseInline(source, pos, end, context);
|
|
162
|
+
for (const parseInline of parseInlineFns) {
|
|
163
|
+
const result = parseInline(source, pos, end, context);
|
|
94
164
|
if (result) {
|
|
95
165
|
inlines.push(result.inline);
|
|
96
166
|
pos = result.nextPos;
|
|
@@ -138,11 +208,8 @@ export function createRuntime(extensions) {
|
|
|
138
208
|
return builder.build();
|
|
139
209
|
}
|
|
140
210
|
function serializeBlock(block) {
|
|
141
|
-
for (const
|
|
142
|
-
|
|
143
|
-
continue;
|
|
144
|
-
}
|
|
145
|
-
const result = extension.serializeBlock(block, context);
|
|
211
|
+
for (const serializeBlockFn of serializeBlockFns) {
|
|
212
|
+
const result = serializeBlockFn(block, context);
|
|
146
213
|
if (result) {
|
|
147
214
|
return result;
|
|
148
215
|
}
|
|
@@ -156,11 +223,8 @@ export function createRuntime(extensions) {
|
|
|
156
223
|
return { source: "", map: new CursorSourceBuilder().build().map };
|
|
157
224
|
}
|
|
158
225
|
function serializeInline(inline) {
|
|
159
|
-
for (const
|
|
160
|
-
|
|
161
|
-
continue;
|
|
162
|
-
}
|
|
163
|
-
const result = extension.serializeInline(inline, context);
|
|
226
|
+
for (const serializeInlineFn of serializeInlineFns) {
|
|
227
|
+
const result = serializeInlineFn(inline, context);
|
|
164
228
|
if (result) {
|
|
165
229
|
return result;
|
|
166
230
|
}
|
|
@@ -185,14 +249,12 @@ export function createRuntime(extensions) {
|
|
|
185
249
|
}
|
|
186
250
|
function normalizeBlock(block) {
|
|
187
251
|
let next = block;
|
|
188
|
-
for (const
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
return null;
|
|
193
|
-
}
|
|
194
|
-
next = result;
|
|
252
|
+
for (const normalizeBlockFn of normalizeBlockFns) {
|
|
253
|
+
const result = normalizeBlockFn(next);
|
|
254
|
+
if (result === null) {
|
|
255
|
+
return null;
|
|
195
256
|
}
|
|
257
|
+
next = result;
|
|
196
258
|
}
|
|
197
259
|
if (next.type === "paragraph") {
|
|
198
260
|
return {
|
|
@@ -214,11 +276,8 @@ export function createRuntime(extensions) {
|
|
|
214
276
|
}
|
|
215
277
|
function applyInlineNormalizers(inline) {
|
|
216
278
|
let next = inline;
|
|
217
|
-
for (const
|
|
218
|
-
|
|
219
|
-
continue;
|
|
220
|
-
}
|
|
221
|
-
const result = extension.normalizeInline(next);
|
|
279
|
+
for (const normalizeInlineFn of normalizeInlineFns) {
|
|
280
|
+
const result = normalizeInlineFn(next);
|
|
222
281
|
if (result === null) {
|
|
223
282
|
return null;
|
|
224
283
|
}
|
|
@@ -275,11 +334,8 @@ export function createRuntime(extensions) {
|
|
|
275
334
|
// If an extension delegates in a loop, this will loop as well.
|
|
276
335
|
while (true) {
|
|
277
336
|
let delegated = false;
|
|
278
|
-
for (const
|
|
279
|
-
|
|
280
|
-
continue;
|
|
281
|
-
}
|
|
282
|
-
const result = extension.onEdit(command, state);
|
|
337
|
+
for (const onEdit of onEditFns) {
|
|
338
|
+
const result = onEdit(command, state);
|
|
283
339
|
if (!result) {
|
|
284
340
|
continue;
|
|
285
341
|
}
|
|
@@ -474,8 +530,7 @@ export function createRuntime(extensions) {
|
|
|
474
530
|
endLoc.offsetInLine === 0 &&
|
|
475
531
|
endLoc.lineIndex > 0) {
|
|
476
532
|
const prevLine = lines[endLoc.lineIndex - 1];
|
|
477
|
-
if (prevLine &&
|
|
478
|
-
!pathsEqual(prevLine.parentPath, endLine.parentPath)) {
|
|
533
|
+
if (prevLine && !pathsEqual(prevLine.parentPath, endLine.parentPath)) {
|
|
479
534
|
const prevBlock = getBlockAtPath(doc.blocks, prevLine.path);
|
|
480
535
|
const currentBlock = getBlockAtPath(doc.blocks, endLine.path);
|
|
481
536
|
if (prevBlock &&
|
|
@@ -1259,7 +1314,7 @@ export function createRuntime(extensions) {
|
|
|
1259
1314
|
if (!markerSpec) {
|
|
1260
1315
|
return state;
|
|
1261
1316
|
}
|
|
1262
|
-
const { kind: markerKind, open: openMarker, close: closeMarker } = markerSpec;
|
|
1317
|
+
const { kind: markerKind, open: openMarker, close: closeMarker, } = markerSpec;
|
|
1263
1318
|
const openLen = openMarker.length;
|
|
1264
1319
|
const closeLen = closeMarker.length;
|
|
1265
1320
|
if (selection.start === selection.end) {
|
|
@@ -1401,7 +1456,9 @@ export function createRuntime(extensions) {
|
|
|
1401
1456
|
continue;
|
|
1402
1457
|
}
|
|
1403
1458
|
const startInLine = lineIndex === startLoc.lineIndex ? startLoc.offsetInLine : 0;
|
|
1404
|
-
const endInLine = lineIndex === endLoc.lineIndex
|
|
1459
|
+
const endInLine = lineIndex === endLoc.lineIndex
|
|
1460
|
+
? endLoc.offsetInLine
|
|
1461
|
+
: line.cursorLength;
|
|
1405
1462
|
if (startInLine === endInLine) {
|
|
1406
1463
|
continue;
|
|
1407
1464
|
}
|
|
@@ -1590,7 +1647,9 @@ export function createRuntime(extensions) {
|
|
|
1590
1647
|
}
|
|
1591
1648
|
};
|
|
1592
1649
|
const openList = (type, indent) => {
|
|
1593
|
-
if (activeList &&
|
|
1650
|
+
if (activeList &&
|
|
1651
|
+
activeList.type === type &&
|
|
1652
|
+
activeList.indent === indent) {
|
|
1594
1653
|
return;
|
|
1595
1654
|
}
|
|
1596
1655
|
closeList();
|
|
@@ -1608,7 +1667,9 @@ export function createRuntime(extensions) {
|
|
|
1608
1667
|
}
|
|
1609
1668
|
const runs = paragraphToRuns(block);
|
|
1610
1669
|
const startInLine = lineIndex === startLoc.lineIndex ? startLoc.offsetInLine : 0;
|
|
1611
|
-
const endInLine = lineIndex === endLoc.lineIndex
|
|
1670
|
+
const endInLine = lineIndex === endLoc.lineIndex
|
|
1671
|
+
? endLoc.offsetInLine
|
|
1672
|
+
: line.cursorLength;
|
|
1612
1673
|
const selectedRuns = sliceRuns(runs, startInLine, endInLine).selected;
|
|
1613
1674
|
// Check if this line is inside a block-wrapper (heading or list)
|
|
1614
1675
|
let wrapperKind = null;
|
|
@@ -1671,7 +1732,10 @@ export function createRuntime(extensions) {
|
|
|
1671
1732
|
return `<div>${html}</div>`;
|
|
1672
1733
|
}
|
|
1673
1734
|
const runtime = {
|
|
1674
|
-
|
|
1735
|
+
dom: {
|
|
1736
|
+
inlineRenderers: domInlineRenderers,
|
|
1737
|
+
blockRenderers: domBlockRenderers,
|
|
1738
|
+
},
|
|
1675
1739
|
parse,
|
|
1676
1740
|
serialize,
|
|
1677
1741
|
createState,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dom-map.d.ts","sourceRoot":"","sources":["../../../src/cake/dom/dom-map.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,IAAI,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD,MAAM,MAAM,MAAM,GAAG;IACnB,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAAC;IACvE,WAAW,CACT,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,GACb;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,QAAQ,CAAA;KAAE,GAAG,IAAI,CAAC;CACxD,CAAC;AASF,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAqBtE;AAqDD,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"dom-map.d.ts","sourceRoot":"","sources":["../../../src/cake/dom/dom-map.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,IAAI,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD,MAAM,MAAM,MAAM,GAAG;IACnB,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAAC;IACvE,WAAW,CACT,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,GACb;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,QAAQ,CAAA;KAAE,GAAG,IAAI,CAAC;CACxD,CAAC;AASF,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAqBtE;AAqDD,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CA+GpD"}
|
package/dist/cake/dom/dom-map.js
CHANGED
|
@@ -85,7 +85,9 @@ export function createDomMap(runs) {
|
|
|
85
85
|
const run = runs[runIndex];
|
|
86
86
|
const previous = runIndex > 0 ? runs[runIndex - 1] : null;
|
|
87
87
|
const next = nextIndex < runs.length ? runs[nextIndex] : null;
|
|
88
|
-
if (cursorOffset === run.cursorStart &&
|
|
88
|
+
if (cursorOffset === run.cursorStart &&
|
|
89
|
+
previous &&
|
|
90
|
+
affinity === "backward") {
|
|
89
91
|
return {
|
|
90
92
|
node: previous.node,
|
|
91
93
|
offset: previous.boundaryOffsets[previous.boundaryOffsets.length - 1],
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Doc, Inline } from "../core/types";
|
|
2
|
-
import type {
|
|
2
|
+
import type { Runtime } from "../core/runtime";
|
|
3
3
|
import { createDomMap } from "./dom-map";
|
|
4
4
|
export type RenderResult = {
|
|
5
5
|
root: HTMLElement;
|
|
@@ -9,7 +9,7 @@ export type RenderContentResult = {
|
|
|
9
9
|
content: Node[];
|
|
10
10
|
map: ReturnType<typeof createDomMap>;
|
|
11
11
|
};
|
|
12
|
-
export declare function renderDocContent(doc: Doc,
|
|
13
|
-
export declare function renderDoc(doc: Doc,
|
|
12
|
+
export declare function renderDocContent(doc: Doc, dom: Runtime["dom"], root?: HTMLElement): RenderContentResult;
|
|
13
|
+
export declare function renderDoc(doc: Doc, dom: Runtime["dom"]): RenderResult;
|
|
14
14
|
export declare function mergeInlineForRender(inlines: Inline[]): Inline[];
|
|
15
15
|
//# sourceMappingURL=render.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/cake/dom/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,GAAG,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/cake/dom/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,GAAG,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,EACL,YAAY,EAGb,MAAM,WAAW,CAAC;AAEnB,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,WAAW,CAAC;IAClB,GAAG,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,IAAI,EAAE,CAAC;IAChB,GAAG,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;CACtC,CAAC;AASF,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,EACnB,IAAI,CAAC,EAAE,WAAW,GACjB,mBAAmB,CA4WrB;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,CA0IrE;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAiChE"}
|
package/dist/cake/dom/render.js
CHANGED
|
@@ -5,7 +5,7 @@ function normalizeNodes(result) {
|
|
|
5
5
|
}
|
|
6
6
|
return Array.isArray(result) ? result : [result];
|
|
7
7
|
}
|
|
8
|
-
export function renderDocContent(doc,
|
|
8
|
+
export function renderDocContent(doc, dom, root) {
|
|
9
9
|
const runs = [];
|
|
10
10
|
let cursorOffset = 0;
|
|
11
11
|
let lineIndex = 0;
|
|
@@ -79,12 +79,8 @@ export function renderDocContent(doc, extensions, root) {
|
|
|
79
79
|
return "unknown";
|
|
80
80
|
}
|
|
81
81
|
function reconcileInline(inline, existing) {
|
|
82
|
-
for (const
|
|
83
|
-
const
|
|
84
|
-
if (!render) {
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
const result = render(inline, context);
|
|
82
|
+
for (const renderInline of dom.inlineRenderers) {
|
|
83
|
+
const result = renderInline(inline, context);
|
|
88
84
|
if (result) {
|
|
89
85
|
return normalizeNodes(result);
|
|
90
86
|
}
|
|
@@ -157,7 +153,8 @@ export function renderDocContent(doc, extensions, root) {
|
|
|
157
153
|
const newChildren = [];
|
|
158
154
|
mergedInlines.forEach((inline, i) => {
|
|
159
155
|
const existingChild = existingChildren[i] ?? null;
|
|
160
|
-
const canReuse = existingChild &&
|
|
156
|
+
const canReuse = existingChild &&
|
|
157
|
+
getInlineElementKey(existingChild) === getInlineKey(inline);
|
|
161
158
|
const nodes = reconcileInline(inline, canReuse ? existingChild : null);
|
|
162
159
|
newChildren.push(...nodes);
|
|
163
160
|
});
|
|
@@ -171,12 +168,8 @@ export function renderDocContent(doc, extensions, root) {
|
|
|
171
168
|
return reconcileInline(inline, null);
|
|
172
169
|
}
|
|
173
170
|
function reconcileBlock(block, existing) {
|
|
174
|
-
for (const
|
|
175
|
-
const
|
|
176
|
-
if (!render) {
|
|
177
|
-
continue;
|
|
178
|
-
}
|
|
179
|
-
const result = render(block, context);
|
|
171
|
+
for (const renderBlock of dom.blockRenderers) {
|
|
172
|
+
const result = renderBlock(block, context);
|
|
180
173
|
if (result) {
|
|
181
174
|
return normalizeNodes(result);
|
|
182
175
|
}
|
|
@@ -311,7 +304,7 @@ export function renderDocContent(doc, extensions, root) {
|
|
|
311
304
|
});
|
|
312
305
|
return { content: contentNodes, map: createDomMap(runs) };
|
|
313
306
|
}
|
|
314
|
-
export function renderDoc(doc,
|
|
307
|
+
export function renderDoc(doc, dom) {
|
|
315
308
|
const root = document.createElement("div");
|
|
316
309
|
root.className = "cake-content";
|
|
317
310
|
root.setAttribute("contenteditable", "true");
|
|
@@ -335,12 +328,8 @@ export function renderDoc(doc, extensions) {
|
|
|
335
328
|
},
|
|
336
329
|
};
|
|
337
330
|
function renderInline(inline) {
|
|
338
|
-
for (const
|
|
339
|
-
const
|
|
340
|
-
if (!render) {
|
|
341
|
-
continue;
|
|
342
|
-
}
|
|
343
|
-
const result = render(inline, context);
|
|
331
|
+
for (const renderInline of dom.inlineRenderers) {
|
|
332
|
+
const result = renderInline(inline, context);
|
|
344
333
|
if (result) {
|
|
345
334
|
return normalizeNodes(result);
|
|
346
335
|
}
|
|
@@ -374,12 +363,8 @@ export function renderDoc(doc, extensions) {
|
|
|
374
363
|
return [];
|
|
375
364
|
}
|
|
376
365
|
function renderBlock(block) {
|
|
377
|
-
for (const
|
|
378
|
-
const
|
|
379
|
-
if (!render) {
|
|
380
|
-
continue;
|
|
381
|
-
}
|
|
382
|
-
const result = render(block, context);
|
|
366
|
+
for (const renderBlock of dom.blockRenderers) {
|
|
367
|
+
const result = renderBlock(block, context);
|
|
383
368
|
if (result) {
|
|
384
369
|
return normalizeNodes(result);
|
|
385
370
|
}
|