@domternal/core 0.2.1 → 0.4.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/README.md +16 -11
- package/dist/index.cjs +372 -75
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1040 -835
- package/dist/index.d.ts +1040 -835
- package/dist/index.js +369 -76
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Plugin, PluginKey, Selection, TextSelection, NodeSelection, AllSelection, EditorState } from '@domternal/pm/state';
|
|
2
2
|
export { PluginKey } from '@domternal/pm/state';
|
|
3
3
|
import { DecorationSet, Decoration, EditorView } from '@domternal/pm/view';
|
|
4
4
|
import { Slice, Fragment, Schema, Node as Node$1, DOMSerializer, DOMParser } from '@domternal/pm/model';
|
|
5
5
|
import { keymap } from '@domternal/pm/keymap';
|
|
6
|
-
import { textblockTypeInputRule, wrappingInputRule, InputRule, inputRules } from '@domternal/pm/inputrules';
|
|
7
6
|
import { chainCommands, newlineInCode, createParagraphNear, liftEmptyBlock, splitBlock, baseKeymap, selectNodeBackward as selectNodeBackward$1 } from '@domternal/pm/commands';
|
|
8
|
-
import {
|
|
7
|
+
import { InputRule } from '@domternal/pm/inputrules';
|
|
8
|
+
import { findWrapping, canJoin, liftTarget } from '@domternal/pm/transform';
|
|
9
9
|
import { liftListItem, sinkListItem, splitListItem, wrapRangeInList } from '@domternal/pm/schema-list';
|
|
10
10
|
import { offset, flip, shift, autoUpdate, hide, computePosition } from '@floating-ui/dom';
|
|
11
11
|
import { find } from 'linkifyjs';
|
|
@@ -108,6 +108,112 @@ var EventEmitter = class {
|
|
|
108
108
|
return Array.from(this.callbacks.keys());
|
|
109
109
|
}
|
|
110
110
|
};
|
|
111
|
+
var MAX_MATCH = 500;
|
|
112
|
+
function run(view, from, to, text, rules, plugin) {
|
|
113
|
+
if (view.composing) return false;
|
|
114
|
+
const state = view.state;
|
|
115
|
+
const $from = state.doc.resolve(from);
|
|
116
|
+
const textBefore = $from.parent.textBetween(
|
|
117
|
+
Math.max(0, $from.parentOffset - MAX_MATCH),
|
|
118
|
+
$from.parentOffset,
|
|
119
|
+
null,
|
|
120
|
+
"\uFFFC"
|
|
121
|
+
) + text;
|
|
122
|
+
for (const rawRule of rules) {
|
|
123
|
+
const rule = rawRule;
|
|
124
|
+
if (!rule.inCodeMark && $from.marks().some((m) => m.type.spec.code)) continue;
|
|
125
|
+
if ($from.parent.type.spec.code) {
|
|
126
|
+
if (!rule.inCode) continue;
|
|
127
|
+
} else if (rule.inCode === "only") {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
const match = rule.match.exec(textBefore);
|
|
131
|
+
if (!match || match[0].length < text.length) continue;
|
|
132
|
+
const startPos = from - (match[0].length - text.length);
|
|
133
|
+
if (!rule.inCodeMark) {
|
|
134
|
+
const codeMarks = [];
|
|
135
|
+
state.doc.nodesBetween(startPos, $from.pos, (node) => {
|
|
136
|
+
if (node.isInline && node.marks.some((m) => m.type.spec.code)) codeMarks.push(true);
|
|
137
|
+
});
|
|
138
|
+
if (codeMarks.length > 0) continue;
|
|
139
|
+
}
|
|
140
|
+
const tr = rule.handler(state, match, startPos, to);
|
|
141
|
+
if (!tr) continue;
|
|
142
|
+
if (rule.undoable) {
|
|
143
|
+
tr.setMeta(plugin, { transform: tr, from, to, text });
|
|
144
|
+
}
|
|
145
|
+
view.dispatch(tr);
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
function undoInputRule(plugin, state, dispatch) {
|
|
151
|
+
const undoable = plugin.getState(state);
|
|
152
|
+
if (!undoable) return false;
|
|
153
|
+
if (dispatch) {
|
|
154
|
+
const tr = state.tr;
|
|
155
|
+
const toUndo = undoable.transform;
|
|
156
|
+
for (let j = toUndo.steps.length - 1; j >= 0; j--) {
|
|
157
|
+
const step = toUndo.steps[j];
|
|
158
|
+
const doc = toUndo.docs[j];
|
|
159
|
+
if (step && doc) tr.step(step.invert(doc));
|
|
160
|
+
}
|
|
161
|
+
if (undoable.text) {
|
|
162
|
+
const marks = tr.doc.resolve(undoable.from).marks();
|
|
163
|
+
tr.replaceWith(undoable.from, undoable.to, state.schema.text(undoable.text, marks));
|
|
164
|
+
const endPos = undoable.from + undoable.text.length;
|
|
165
|
+
if (endPos <= tr.doc.content.size) {
|
|
166
|
+
tr.setSelection(TextSelection.create(tr.doc, endPos));
|
|
167
|
+
}
|
|
168
|
+
} else {
|
|
169
|
+
tr.delete(undoable.from, undoable.to);
|
|
170
|
+
}
|
|
171
|
+
dispatch(tr);
|
|
172
|
+
}
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
function inputRulesPlugin({ rules }) {
|
|
176
|
+
const plugin = new Plugin({
|
|
177
|
+
state: {
|
|
178
|
+
init() {
|
|
179
|
+
return null;
|
|
180
|
+
},
|
|
181
|
+
apply(tr, prev) {
|
|
182
|
+
const stored = tr.getMeta(plugin);
|
|
183
|
+
if (stored) return stored;
|
|
184
|
+
if (tr.getMeta("appendedTransaction")) return prev;
|
|
185
|
+
return tr.selectionSet || tr.docChanged ? null : prev;
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
props: {
|
|
189
|
+
handleTextInput(view, from, to, text) {
|
|
190
|
+
return run(view, from, to, text, rules, plugin);
|
|
191
|
+
},
|
|
192
|
+
handleKeyDown(view, event) {
|
|
193
|
+
if (event.key === "Backspace" && !event.ctrlKey && !event.metaKey && !event.altKey) {
|
|
194
|
+
return undoInputRule(plugin, view.state, (tr) => {
|
|
195
|
+
view.dispatch(tr);
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
return false;
|
|
199
|
+
},
|
|
200
|
+
handleDOMEvents: {
|
|
201
|
+
compositionend: (view) => {
|
|
202
|
+
setTimeout(() => {
|
|
203
|
+
const { $cursor } = view.state.selection;
|
|
204
|
+
if ($cursor) {
|
|
205
|
+
run(view, $cursor.pos, $cursor.pos, "", rules, plugin);
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
// Tag so external undoInputRule can also find this plugin
|
|
212
|
+
isInputRules: true
|
|
213
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
214
|
+
});
|
|
215
|
+
return plugin;
|
|
216
|
+
}
|
|
111
217
|
|
|
112
218
|
// src/helpers/callOrReturn.ts
|
|
113
219
|
function callOrReturn(value, context, ...args) {
|
|
@@ -485,14 +591,14 @@ var ExtensionManager = class {
|
|
|
485
591
|
*/
|
|
486
592
|
buildPlugins() {
|
|
487
593
|
const plugins = [];
|
|
594
|
+
const rules = this.collectInputRules();
|
|
595
|
+
if (rules.length > 0) {
|
|
596
|
+
plugins.push(inputRulesPlugin({ rules }));
|
|
597
|
+
}
|
|
488
598
|
const shortcuts = this.collectKeyboardShortcuts();
|
|
489
599
|
if (Object.keys(shortcuts).length > 0) {
|
|
490
600
|
plugins.push(keymap(shortcuts));
|
|
491
601
|
}
|
|
492
|
-
const rules = this.collectInputRules();
|
|
493
|
-
if (rules.length > 0) {
|
|
494
|
-
plugins.push(inputRules({ rules }));
|
|
495
|
-
}
|
|
496
602
|
for (const ext of this._extensions) {
|
|
497
603
|
const addPlugins = ext.config.addProseMirrorPlugins;
|
|
498
604
|
if (addPlugins) {
|
|
@@ -601,8 +707,12 @@ var ExtensionManager = class {
|
|
|
601
707
|
return items;
|
|
602
708
|
}
|
|
603
709
|
/**
|
|
604
|
-
* Collects node views from all Node extensions
|
|
605
|
-
* Returns a map of node name
|
|
710
|
+
* Collects node views from all Node extensions.
|
|
711
|
+
* Returns a map of node name to NodeViewConstructor for EditorView.
|
|
712
|
+
*
|
|
713
|
+
* Each constructor is annotated with `__domternalContext` containing
|
|
714
|
+
* the editor and extension metadata so framework wrappers (React, Vue)
|
|
715
|
+
* can access them without changing the ProseMirror calling convention.
|
|
606
716
|
*/
|
|
607
717
|
collectNodeViews() {
|
|
608
718
|
const nodeViews = {};
|
|
@@ -616,6 +726,10 @@ var ExtensionManager = class {
|
|
|
616
726
|
`${ext.name}.addNodeView`
|
|
617
727
|
);
|
|
618
728
|
if (nodeView) {
|
|
729
|
+
nodeView.__domternalContext = {
|
|
730
|
+
editor: this.editor,
|
|
731
|
+
extension: { name: nodeExt.name, options: nodeExt.options }
|
|
732
|
+
};
|
|
619
733
|
nodeViews[ext.name] = nodeView;
|
|
620
734
|
}
|
|
621
735
|
}
|
|
@@ -935,7 +1049,7 @@ function isDocumentEmpty(doc) {
|
|
|
935
1049
|
});
|
|
936
1050
|
}
|
|
937
1051
|
function markInputRule(options) {
|
|
938
|
-
const { find: find2, type, getAttributes } = options;
|
|
1052
|
+
const { find: find2, type, getAttributes, undoable } = options;
|
|
939
1053
|
return new InputRule(
|
|
940
1054
|
find2,
|
|
941
1055
|
(state, match, start, end) => {
|
|
@@ -952,7 +1066,8 @@ function markInputRule(options) {
|
|
|
952
1066
|
tr.addMark(start, start + textContent.length, type.create(attributes ?? void 0));
|
|
953
1067
|
tr.removeStoredMark(type);
|
|
954
1068
|
return tr;
|
|
955
|
-
}
|
|
1069
|
+
},
|
|
1070
|
+
undoable !== void 0 ? { undoable } : {}
|
|
956
1071
|
);
|
|
957
1072
|
}
|
|
958
1073
|
var markInputRulePatterns = {
|
|
@@ -977,6 +1092,69 @@ var markInputRulePatterns = {
|
|
|
977
1092
|
*/
|
|
978
1093
|
highlight: /(?:==)([^=]+)(?:==)$/
|
|
979
1094
|
};
|
|
1095
|
+
function wrappingInputRule(options) {
|
|
1096
|
+
const { find: find2, type, getAttributes = null, joinPredicate, undoable, guard } = options;
|
|
1097
|
+
return new InputRule(
|
|
1098
|
+
find2,
|
|
1099
|
+
(state, match, start, end) => {
|
|
1100
|
+
if (guard && !guard(state)) return null;
|
|
1101
|
+
const attrs = getAttributes instanceof Function ? getAttributes(match) : getAttributes;
|
|
1102
|
+
const tr = state.tr.delete(start, end);
|
|
1103
|
+
const $start = tr.doc.resolve(start);
|
|
1104
|
+
const range = $start.blockRange();
|
|
1105
|
+
const wrapping = range && findWrapping(range, type, attrs);
|
|
1106
|
+
if (!wrapping) return null;
|
|
1107
|
+
tr.wrap(range, wrapping);
|
|
1108
|
+
const before = tr.doc.resolve(start - 1).nodeBefore;
|
|
1109
|
+
if (before?.type === type && canJoin(tr.doc, start - 1) && (!joinPredicate || joinPredicate(match, before))) {
|
|
1110
|
+
tr.join(start - 1);
|
|
1111
|
+
}
|
|
1112
|
+
return tr;
|
|
1113
|
+
},
|
|
1114
|
+
undoable !== void 0 ? { undoable } : {}
|
|
1115
|
+
);
|
|
1116
|
+
}
|
|
1117
|
+
function notInsideList(state) {
|
|
1118
|
+
const { $from } = state.selection;
|
|
1119
|
+
for (let d = $from.depth; d > 0; d--) {
|
|
1120
|
+
const name = $from.node(d).type.name;
|
|
1121
|
+
if (name === "listItem" || name === "taskItem") return false;
|
|
1122
|
+
}
|
|
1123
|
+
return true;
|
|
1124
|
+
}
|
|
1125
|
+
function textblockTypeInputRule(options) {
|
|
1126
|
+
const { find: find2, type, getAttributes = null, undoable } = options;
|
|
1127
|
+
return new InputRule(
|
|
1128
|
+
find2,
|
|
1129
|
+
(state, match, start, end) => {
|
|
1130
|
+
const $start = state.doc.resolve(start);
|
|
1131
|
+
const attrs = getAttributes instanceof Function ? getAttributes(match) : getAttributes;
|
|
1132
|
+
if (!$start.node(-1).canReplaceWith($start.index(-1), $start.indexAfter(-1), type)) return null;
|
|
1133
|
+
return state.tr.delete(start, end).setBlockType(start, start, type, attrs);
|
|
1134
|
+
},
|
|
1135
|
+
undoable !== void 0 ? { undoable } : {}
|
|
1136
|
+
);
|
|
1137
|
+
}
|
|
1138
|
+
function textInputRule(options) {
|
|
1139
|
+
const { find: find2, replace, undoable } = options;
|
|
1140
|
+
return new InputRule(
|
|
1141
|
+
find2,
|
|
1142
|
+
(state, _match, start, end) => state.tr.replaceWith(start, end, state.schema.text(replace)),
|
|
1143
|
+
undoable !== void 0 ? { undoable } : {}
|
|
1144
|
+
);
|
|
1145
|
+
}
|
|
1146
|
+
function nodeInputRule(options) {
|
|
1147
|
+
const { find: find2, type, getAttributes = null, undoable } = options;
|
|
1148
|
+
return new InputRule(
|
|
1149
|
+
find2,
|
|
1150
|
+
(state, match, start, end) => {
|
|
1151
|
+
const attrs = getAttributes instanceof Function ? getAttributes(match, state) : getAttributes;
|
|
1152
|
+
if (getAttributes instanceof Function && attrs === null) return null;
|
|
1153
|
+
return state.tr.replaceWith(start, end, type.create(attrs));
|
|
1154
|
+
},
|
|
1155
|
+
undoable !== void 0 ? { undoable } : {}
|
|
1156
|
+
);
|
|
1157
|
+
}
|
|
980
1158
|
|
|
981
1159
|
// src/helpers/isValidUrl.ts
|
|
982
1160
|
function isValidUrl(url, options = {}) {
|
|
@@ -1865,8 +2043,18 @@ var toggleWrap = (nodeName, attributes) => (props) => {
|
|
|
1865
2043
|
const allWrapped = contentBlocks.length > 0 ? contentBlocks.every(({ pos }) => isInsideWrap(pos)) : isInsideWrap(from);
|
|
1866
2044
|
if (allWrapped) {
|
|
1867
2045
|
const first = contentBlocks[0];
|
|
1868
|
-
|
|
1869
|
-
|
|
2046
|
+
const last = contentBlocks[contentBlocks.length - 1];
|
|
2047
|
+
if (first && last) {
|
|
2048
|
+
const $liftFrom = tr.doc.resolve(first.pos + 1);
|
|
2049
|
+
const $liftTo = tr.doc.resolve(last.pos + 1);
|
|
2050
|
+
const range = $liftFrom.blockRange($liftTo);
|
|
2051
|
+
if (!range) return false;
|
|
2052
|
+
const target = liftTarget(range);
|
|
2053
|
+
if (target === null) return false;
|
|
2054
|
+
if (!dispatch) return true;
|
|
2055
|
+
tr.lift(range, target).scrollIntoView();
|
|
2056
|
+
dispatch(tr);
|
|
2057
|
+
return true;
|
|
1870
2058
|
}
|
|
1871
2059
|
return lift()(props);
|
|
1872
2060
|
}
|
|
@@ -1900,6 +2088,36 @@ var lift = () => ({ tr, dispatch }) => {
|
|
|
1900
2088
|
dispatch(tr);
|
|
1901
2089
|
return true;
|
|
1902
2090
|
};
|
|
2091
|
+
function joinListBackwards(tr, listType) {
|
|
2092
|
+
const { $from } = tr.selection;
|
|
2093
|
+
for (let d = $from.depth; d >= 0; d--) {
|
|
2094
|
+
if ($from.node(d).type === listType) {
|
|
2095
|
+
const listPos = $from.before(d);
|
|
2096
|
+
if (listPos > 0 && canJoin(tr.doc, listPos)) {
|
|
2097
|
+
const nodeBefore = tr.doc.resolve(listPos - 1).parent;
|
|
2098
|
+
if (nodeBefore.type === listType) {
|
|
2099
|
+
tr.join(listPos);
|
|
2100
|
+
}
|
|
2101
|
+
}
|
|
2102
|
+
return;
|
|
2103
|
+
}
|
|
2104
|
+
}
|
|
2105
|
+
}
|
|
2106
|
+
function joinListForwards(tr, listType) {
|
|
2107
|
+
const { $from } = tr.selection;
|
|
2108
|
+
for (let d = $from.depth; d >= 0; d--) {
|
|
2109
|
+
if ($from.node(d).type === listType) {
|
|
2110
|
+
const after = $from.after(d);
|
|
2111
|
+
if (after < tr.doc.content.size && canJoin(tr.doc, after)) {
|
|
2112
|
+
const nodeAfter = tr.doc.nodeAt(after);
|
|
2113
|
+
if (nodeAfter?.type === listType) {
|
|
2114
|
+
tr.join(after);
|
|
2115
|
+
}
|
|
2116
|
+
}
|
|
2117
|
+
return;
|
|
2118
|
+
}
|
|
2119
|
+
}
|
|
2120
|
+
}
|
|
1903
2121
|
var toggleList = (listNodeName, listItemNodeName, attributes) => ({ state, tr, dispatch }) => {
|
|
1904
2122
|
const listType = state.schema.nodes[listNodeName];
|
|
1905
2123
|
const listItemType = state.schema.nodes[listItemNodeName];
|
|
@@ -2055,11 +2273,56 @@ var toggleList = (listNodeName, listItemNodeName, attributes) => ({ state, tr, d
|
|
|
2055
2273
|
dispatch(tr);
|
|
2056
2274
|
return true;
|
|
2057
2275
|
}
|
|
2058
|
-
const
|
|
2276
|
+
const blocksInList = contentBlocks.filter((b) => b.inSomeList);
|
|
2277
|
+
if (blocksInList.length === 0) {
|
|
2278
|
+
const { $from: $wf, $to: $wt } = tr.selection;
|
|
2279
|
+
const wr = $wf.blockRange($wt);
|
|
2280
|
+
if (!wr) return false;
|
|
2281
|
+
if (!wrapRangeInList(dispatch ? tr : null, wr, listType, attributes)) return false;
|
|
2282
|
+
if (dispatch) {
|
|
2283
|
+
joinListBackwards(tr, listType);
|
|
2284
|
+
joinListForwards(tr, listType);
|
|
2285
|
+
dispatch(tr.scrollIntoView());
|
|
2286
|
+
}
|
|
2287
|
+
return true;
|
|
2288
|
+
}
|
|
2289
|
+
if (!dispatch) return true;
|
|
2290
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2291
|
+
const listPositions = [];
|
|
2292
|
+
for (const block of blocksInList) {
|
|
2293
|
+
const $pos = tr.doc.resolve(block.pos);
|
|
2294
|
+
for (let d = $pos.depth; d >= 0; d--) {
|
|
2295
|
+
const groups = ($pos.node(d).type.spec.group ?? "").split(/\s+/);
|
|
2296
|
+
if (groups.includes("list")) {
|
|
2297
|
+
const lpos = $pos.before(d);
|
|
2298
|
+
if (!seen.has(lpos)) {
|
|
2299
|
+
seen.add(lpos);
|
|
2300
|
+
listPositions.push(lpos);
|
|
2301
|
+
}
|
|
2302
|
+
break;
|
|
2303
|
+
}
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
2306
|
+
listPositions.sort((a, b) => b - a);
|
|
2307
|
+
for (const pos of listPositions) {
|
|
2308
|
+
const listNode = tr.doc.nodeAt(pos);
|
|
2309
|
+
if (!listNode) continue;
|
|
2310
|
+
const children = [];
|
|
2311
|
+
listNode.forEach((item) => {
|
|
2312
|
+
item.forEach((child) => children.push(child));
|
|
2313
|
+
});
|
|
2314
|
+
tr.replaceWith(pos, pos + listNode.nodeSize, children);
|
|
2315
|
+
}
|
|
2316
|
+
const mappedFrom = tr.mapping.map(from, -1);
|
|
2317
|
+
const mappedTo = tr.mapping.map(to, 1);
|
|
2318
|
+
const $wrapFrom = tr.doc.resolve(mappedFrom);
|
|
2319
|
+
const $wrapTo = tr.doc.resolve(mappedTo);
|
|
2059
2320
|
const wrapRange = $wrapFrom.blockRange($wrapTo);
|
|
2060
2321
|
if (!wrapRange) return false;
|
|
2061
|
-
|
|
2062
|
-
|
|
2322
|
+
wrapRangeInList(tr, wrapRange, listType, attributes);
|
|
2323
|
+
joinListBackwards(tr, listType);
|
|
2324
|
+
joinListForwards(tr, listType);
|
|
2325
|
+
dispatch(tr.scrollIntoView());
|
|
2063
2326
|
return true;
|
|
2064
2327
|
};
|
|
2065
2328
|
|
|
@@ -4408,7 +4671,32 @@ var Heading = Node.create({
|
|
|
4408
4671
|
];
|
|
4409
4672
|
},
|
|
4410
4673
|
addProseMirrorPlugins() {
|
|
4674
|
+
const { options, editor } = this;
|
|
4675
|
+
const codeToLevel = {};
|
|
4676
|
+
for (const level of options.levels) {
|
|
4677
|
+
codeToLevel[`Digit${String(level)}`] = level;
|
|
4678
|
+
}
|
|
4679
|
+
codeToLevel["Digit0"] = 0;
|
|
4411
4680
|
return [
|
|
4681
|
+
new Plugin({
|
|
4682
|
+
key: new PluginKey("headingKeydownFix"),
|
|
4683
|
+
props: {
|
|
4684
|
+
handleDOMEvents: {
|
|
4685
|
+
keydown(_view, event) {
|
|
4686
|
+
if (!event.altKey || !(event.metaKey || event.ctrlKey)) return false;
|
|
4687
|
+
const level = codeToLevel[event.code];
|
|
4688
|
+
if (level === void 0) return false;
|
|
4689
|
+
event.preventDefault();
|
|
4690
|
+
if (level === 0) {
|
|
4691
|
+
editor?.commands["setParagraph"]?.();
|
|
4692
|
+
} else {
|
|
4693
|
+
editor?.commands["toggleHeading"]?.({ level });
|
|
4694
|
+
}
|
|
4695
|
+
return true;
|
|
4696
|
+
}
|
|
4697
|
+
}
|
|
4698
|
+
}
|
|
4699
|
+
}),
|
|
4412
4700
|
keymap({
|
|
4413
4701
|
Backspace: ((state, dispatch) => {
|
|
4414
4702
|
const { selection } = state;
|
|
@@ -4435,10 +4723,10 @@ var Heading = Node.create({
|
|
|
4435
4723
|
}
|
|
4436
4724
|
const maxLevel = Math.max(...options.levels);
|
|
4437
4725
|
return [
|
|
4438
|
-
textblockTypeInputRule(
|
|
4439
|
-
new RegExp(`^(#{1,${String(maxLevel)}})\\s$`),
|
|
4440
|
-
nodeType,
|
|
4441
|
-
(match) => {
|
|
4726
|
+
textblockTypeInputRule({
|
|
4727
|
+
find: new RegExp(`^(#{1,${String(maxLevel)}})\\s$`),
|
|
4728
|
+
type: nodeType,
|
|
4729
|
+
getAttributes: (match) => {
|
|
4442
4730
|
const hashes = match[1];
|
|
4443
4731
|
if (!hashes) {
|
|
4444
4732
|
return null;
|
|
@@ -4449,10 +4737,12 @@ var Heading = Node.create({
|
|
|
4449
4737
|
}
|
|
4450
4738
|
return { level };
|
|
4451
4739
|
}
|
|
4452
|
-
)
|
|
4740
|
+
})
|
|
4453
4741
|
];
|
|
4454
4742
|
}
|
|
4455
4743
|
});
|
|
4744
|
+
|
|
4745
|
+
// src/nodes/Blockquote.ts
|
|
4456
4746
|
var Blockquote = Node.create({
|
|
4457
4747
|
name: "blockquote",
|
|
4458
4748
|
group: "block",
|
|
@@ -4512,7 +4802,7 @@ var Blockquote = Node.create({
|
|
|
4512
4802
|
return [];
|
|
4513
4803
|
}
|
|
4514
4804
|
return [
|
|
4515
|
-
wrappingInputRule(/^\s*>\s$/, nodeType)
|
|
4805
|
+
wrappingInputRule({ find: /^\s*>\s$/, type: nodeType })
|
|
4516
4806
|
];
|
|
4517
4807
|
}
|
|
4518
4808
|
});
|
|
@@ -4642,14 +4932,14 @@ var CodeBlock = Node.create({
|
|
|
4642
4932
|
return [];
|
|
4643
4933
|
}
|
|
4644
4934
|
return [
|
|
4645
|
-
textblockTypeInputRule(
|
|
4646
|
-
/^```([a-z]*)?[\s\n]$/,
|
|
4647
|
-
nodeType,
|
|
4648
|
-
(match) => {
|
|
4935
|
+
textblockTypeInputRule({
|
|
4936
|
+
find: /^```([a-z]*)?[\s\n]$/,
|
|
4937
|
+
type: nodeType,
|
|
4938
|
+
getAttributes: (match) => {
|
|
4649
4939
|
const language = match[1] ?? null;
|
|
4650
4940
|
return { language };
|
|
4651
4941
|
}
|
|
4652
|
-
)
|
|
4942
|
+
})
|
|
4653
4943
|
];
|
|
4654
4944
|
}
|
|
4655
4945
|
});
|
|
@@ -4833,14 +5123,16 @@ var BulletList = Node.create({
|
|
|
4833
5123
|
}
|
|
4834
5124
|
return [
|
|
4835
5125
|
// - item
|
|
4836
|
-
wrappingInputRule(/^\s*[-]\s$/, nodeType),
|
|
5126
|
+
wrappingInputRule({ find: /^\s*[-]\s$/, type: nodeType, guard: notInsideList }),
|
|
4837
5127
|
// * item
|
|
4838
|
-
wrappingInputRule(/^\s*[*]\s$/, nodeType),
|
|
5128
|
+
wrappingInputRule({ find: /^\s*[*]\s$/, type: nodeType, guard: notInsideList }),
|
|
4839
5129
|
// + item
|
|
4840
|
-
wrappingInputRule(/^\s*[+]\s$/, nodeType)
|
|
5130
|
+
wrappingInputRule({ find: /^\s*[+]\s$/, type: nodeType, guard: notInsideList })
|
|
4841
5131
|
];
|
|
4842
5132
|
}
|
|
4843
5133
|
});
|
|
5134
|
+
|
|
5135
|
+
// src/nodes/OrderedList.ts
|
|
4844
5136
|
var OrderedList = Node.create({
|
|
4845
5137
|
name: "orderedList",
|
|
4846
5138
|
group: "block list",
|
|
@@ -4916,14 +5208,15 @@ var OrderedList = Node.create({
|
|
|
4916
5208
|
}
|
|
4917
5209
|
return [
|
|
4918
5210
|
// 1. item (any number followed by . )
|
|
4919
|
-
wrappingInputRule(
|
|
4920
|
-
/^(\d+)\.\s$/,
|
|
4921
|
-
nodeType,
|
|
4922
|
-
|
|
5211
|
+
wrappingInputRule({
|
|
5212
|
+
find: /^(\d+)\.\s$/,
|
|
5213
|
+
type: nodeType,
|
|
5214
|
+
guard: notInsideList,
|
|
5215
|
+
getAttributes: (match) => {
|
|
4923
5216
|
const num = match[1];
|
|
4924
5217
|
return { start: num ? parseInt(num, 10) : 1 };
|
|
4925
5218
|
}
|
|
4926
|
-
)
|
|
5219
|
+
})
|
|
4927
5220
|
];
|
|
4928
5221
|
}
|
|
4929
5222
|
});
|
|
@@ -4998,13 +5291,12 @@ var HorizontalRule = Node.create({
|
|
|
4998
5291
|
const $start = state.doc.resolve(start);
|
|
4999
5292
|
const from = $start.before();
|
|
5000
5293
|
const to = $start.after();
|
|
5001
|
-
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
}
|
|
5294
|
+
const paragraph = state.schema.nodes["paragraph"]?.create();
|
|
5295
|
+
const nodes = paragraph ? [nodeType.create(), paragraph] : [nodeType.create()];
|
|
5296
|
+
tr.replaceWith(from, to, nodes);
|
|
5297
|
+
const sel = TextSelection.findFrom(tr.doc.resolve(from + 1), 1);
|
|
5298
|
+
if (sel) {
|
|
5299
|
+
tr.setSelection(sel);
|
|
5008
5300
|
}
|
|
5009
5301
|
}
|
|
5010
5302
|
return tr;
|
|
@@ -5295,9 +5587,9 @@ var TaskList = Node.create({
|
|
|
5295
5587
|
}
|
|
5296
5588
|
return [
|
|
5297
5589
|
// [ ] at start of line creates unchecked task
|
|
5298
|
-
wrappingInputRule(/^\s*\[\s?\]\s$/, nodeType),
|
|
5590
|
+
wrappingInputRule({ find: /^\s*\[\s?\]\s$/, type: nodeType, guard: notInsideList }),
|
|
5299
5591
|
// [x] or [X] at start of line creates checked task
|
|
5300
|
-
wrappingInputRule(/^\s*\[[xX]\]\s$/, nodeType)
|
|
5592
|
+
wrappingInputRule({ find: /^\s*\[[xX]\]\s$/, type: nodeType, guard: notInsideList })
|
|
5301
5593
|
];
|
|
5302
5594
|
}
|
|
5303
5595
|
});
|
|
@@ -6595,40 +6887,39 @@ var Typography = Extension.create({
|
|
|
6595
6887
|
},
|
|
6596
6888
|
addInputRules() {
|
|
6597
6889
|
const rules = [];
|
|
6598
|
-
const textReplace = (find2, replacement) => new InputRule(find2, (state, _match, start, end) => state.tr.replaceWith(start, end, state.schema.text(replacement)));
|
|
6599
6890
|
if (this.options.emDash) {
|
|
6600
|
-
rules.push(
|
|
6891
|
+
rules.push(textInputRule({ find: /--$/, replace: "\u2014" }));
|
|
6601
6892
|
}
|
|
6602
6893
|
if (this.options.ellipsis) {
|
|
6603
|
-
rules.push(
|
|
6894
|
+
rules.push(textInputRule({ find: /\.\.\.$/, replace: "\u2026" }));
|
|
6604
6895
|
}
|
|
6605
6896
|
if (this.options.arrows) {
|
|
6606
|
-
rules.push(
|
|
6607
|
-
rules.push(
|
|
6608
|
-
rules.push(
|
|
6897
|
+
rules.push(textInputRule({ find: /<-$/, replace: "\u2190" }));
|
|
6898
|
+
rules.push(textInputRule({ find: /->$/, replace: "\u2192" }));
|
|
6899
|
+
rules.push(textInputRule({ find: /=>$/, replace: "\u21D2" }));
|
|
6609
6900
|
}
|
|
6610
6901
|
if (this.options.fractions) {
|
|
6611
|
-
rules.push(
|
|
6612
|
-
rules.push(
|
|
6613
|
-
rules.push(
|
|
6614
|
-
rules.push(
|
|
6615
|
-
rules.push(
|
|
6902
|
+
rules.push(textInputRule({ find: /1\/2$/, replace: "\xBD" }));
|
|
6903
|
+
rules.push(textInputRule({ find: /1\/4$/, replace: "\xBC" }));
|
|
6904
|
+
rules.push(textInputRule({ find: /3\/4$/, replace: "\xBE" }));
|
|
6905
|
+
rules.push(textInputRule({ find: /1\/3$/, replace: "\u2153" }));
|
|
6906
|
+
rules.push(textInputRule({ find: /2\/3$/, replace: "\u2154" }));
|
|
6616
6907
|
}
|
|
6617
6908
|
if (this.options.symbols) {
|
|
6618
|
-
rules.push(
|
|
6619
|
-
rules.push(
|
|
6620
|
-
rules.push(
|
|
6621
|
-
rules.push(
|
|
6909
|
+
rules.push(textInputRule({ find: /\(c\)$/i, replace: "\xA9" }));
|
|
6910
|
+
rules.push(textInputRule({ find: /\(r\)$/i, replace: "\xAE" }));
|
|
6911
|
+
rules.push(textInputRule({ find: /\(tm\)$/i, replace: "\u2122" }));
|
|
6912
|
+
rules.push(textInputRule({ find: /\(sm\)$/i, replace: "\u2120" }));
|
|
6622
6913
|
}
|
|
6623
6914
|
if (this.options.math) {
|
|
6624
|
-
rules.push(
|
|
6625
|
-
rules.push(
|
|
6626
|
-
rules.push(
|
|
6627
|
-
rules.push(
|
|
6915
|
+
rules.push(textInputRule({ find: /\+\/-$/, replace: "\xB1" }));
|
|
6916
|
+
rules.push(textInputRule({ find: /!=$/, replace: "\u2260" }));
|
|
6917
|
+
rules.push(textInputRule({ find: /<=$/, replace: "\u2264" }));
|
|
6918
|
+
rules.push(textInputRule({ find: />=$/, replace: "\u2265" }));
|
|
6628
6919
|
}
|
|
6629
6920
|
if (this.options.guillemets) {
|
|
6630
|
-
rules.push(
|
|
6631
|
-
rules.push(
|
|
6921
|
+
rules.push(textInputRule({ find: /<<$/, replace: "\xAB" }));
|
|
6922
|
+
rules.push(textInputRule({ find: />>$/, replace: "\xBB" }));
|
|
6632
6923
|
}
|
|
6633
6924
|
if (this.options.smartQuotes) {
|
|
6634
6925
|
const { openDoubleQuote, closeDoubleQuote, openSingleQuote, closeSingleQuote } = this.options;
|
|
@@ -7373,31 +7664,31 @@ var InvisibleChars = Extension.create({
|
|
|
7373
7664
|
|
|
7374
7665
|
// src/extensions/TextColor.ts
|
|
7375
7666
|
var DEFAULT_TEXT_COLORS = [
|
|
7376
|
-
// Row 1
|
|
7667
|
+
// Row 1 - Neutrals
|
|
7377
7668
|
"#000000",
|
|
7378
7669
|
"#595959",
|
|
7379
7670
|
"#a6a6a6",
|
|
7380
7671
|
"#d9d9d9",
|
|
7381
7672
|
"#ffffff",
|
|
7382
|
-
// Row 2
|
|
7673
|
+
// Row 2 - Pastel
|
|
7383
7674
|
"#ffc9c9",
|
|
7384
7675
|
"#fff3bf",
|
|
7385
7676
|
"#b2f2bb",
|
|
7386
7677
|
"#a5d8ff",
|
|
7387
7678
|
"#d0bfff",
|
|
7388
|
-
// Row 3
|
|
7679
|
+
// Row 3 - Vivid
|
|
7389
7680
|
"#e03131",
|
|
7390
7681
|
"#f08c00",
|
|
7391
7682
|
"#2f9e44",
|
|
7392
7683
|
"#1971c2",
|
|
7393
7684
|
"#7048e8",
|
|
7394
|
-
// Row 4
|
|
7685
|
+
// Row 4 - Medium
|
|
7395
7686
|
"#ff6b6b",
|
|
7396
7687
|
"#ffd43b",
|
|
7397
7688
|
"#69db7c",
|
|
7398
7689
|
"#4dabf7",
|
|
7399
7690
|
"#9775fa",
|
|
7400
|
-
// Row 5
|
|
7691
|
+
// Row 5 - Dark
|
|
7401
7692
|
"#c92a2a",
|
|
7402
7693
|
"#e67700",
|
|
7403
7694
|
"#2b8a3e",
|
|
@@ -7487,31 +7778,31 @@ var TextColor = Extension.create({
|
|
|
7487
7778
|
}
|
|
7488
7779
|
});
|
|
7489
7780
|
var DEFAULT_HIGHLIGHT_COLORS = [
|
|
7490
|
-
// Row 1
|
|
7781
|
+
// Row 1 - Classic warm highlights
|
|
7491
7782
|
"#fef08a",
|
|
7492
7783
|
"#fde68a",
|
|
7493
7784
|
"#fed7aa",
|
|
7494
7785
|
"#fecaca",
|
|
7495
7786
|
"#fbcfe8",
|
|
7496
|
-
// Row 2
|
|
7787
|
+
// Row 2 - Lighter warm pastels
|
|
7497
7788
|
"#fef9c3",
|
|
7498
7789
|
"#fef3c7",
|
|
7499
7790
|
"#ffedd5",
|
|
7500
7791
|
"#fee2e2",
|
|
7501
7792
|
"#fce7f3",
|
|
7502
|
-
// Row 3
|
|
7793
|
+
// Row 3 - Cool highlights
|
|
7503
7794
|
"#a7f3d0",
|
|
7504
7795
|
"#99f6e4",
|
|
7505
7796
|
"#a5f3fc",
|
|
7506
7797
|
"#bfdbfe",
|
|
7507
7798
|
"#c4b5fd",
|
|
7508
|
-
// Row 4
|
|
7799
|
+
// Row 4 - Lighter cool pastels
|
|
7509
7800
|
"#d1fae5",
|
|
7510
7801
|
"#ccfbf1",
|
|
7511
7802
|
"#cffafe",
|
|
7512
7803
|
"#dbeafe",
|
|
7513
7804
|
"#ede9fe",
|
|
7514
|
-
// Row 5
|
|
7805
|
+
// Row 5 - Neutrals
|
|
7515
7806
|
"#e5e7eb",
|
|
7516
7807
|
"#d1d5db",
|
|
7517
7808
|
"#f3f4f6",
|
|
@@ -7865,11 +8156,13 @@ function linkPopoverPlugin({ editor, markType, protocols }) {
|
|
|
7865
8156
|
applyBtn.type = "button";
|
|
7866
8157
|
applyBtn.className = "dm-link-popover-btn dm-link-popover-apply";
|
|
7867
8158
|
applyBtn.title = "Apply link";
|
|
8159
|
+
applyBtn.setAttribute("aria-label", "Apply link");
|
|
7868
8160
|
applyBtn.innerHTML = defaultIcons["check"] ?? "";
|
|
7869
8161
|
const removeBtn = document.createElement("button");
|
|
7870
8162
|
removeBtn.type = "button";
|
|
7871
8163
|
removeBtn.className = "dm-link-popover-btn dm-link-popover-remove";
|
|
7872
8164
|
removeBtn.title = "Remove link";
|
|
8165
|
+
removeBtn.setAttribute("aria-label", "Remove link");
|
|
7873
8166
|
removeBtn.innerHTML = defaultIcons["linkBreak"] ?? "";
|
|
7874
8167
|
el.appendChild(input);
|
|
7875
8168
|
el.appendChild(applyBtn);
|
|
@@ -8527,6 +8820,6 @@ var StarterKit = Extension.create({
|
|
|
8527
8820
|
// src/index.ts
|
|
8528
8821
|
var VERSION = "0.1.0";
|
|
8529
8822
|
|
|
8530
|
-
export { BaseKeymap, Blockquote, Bold, BubbleMenu, BulletList, CanChecker, ChainBuilder, CharacterCount, ClearFormatting, Code, CodeBlock, CommandManager, DEFAULT_HIGHLIGHT_COLORS, DEFAULT_TEXT_COLORS, Document, Dropcursor, Editor, EventEmitter, Extension, ExtensionManager, FloatingMenu, Focus, FontFamily, FontSize, Gapcursor, HardBreak, Heading, Highlight, History, HorizontalRule, InvisibleChars, Italic, LineHeight, Link, LinkPopover, ListItem, ListKeymap, Mark, Node, OrderedList, Paragraph, Placeholder, Selection3 as Selection, SelectionDecoration, StarterKit, Strike, Subscript, Superscript, TaskItem, TaskList, Text, TextAlign, TextColor, TextStyle, ToolbarController, TrailingNode, Typography, Underline, UniqueID, VERSION, applyInlineStyles, autolinkPlugin, autolinkPluginKey, blur, bubbleMenuPluginKey, buildCommandProps, builtInCommands, callOrReturn, characterCountPluginKey, clearContent, createAccumulatingDispatch, createBubbleMenuPlugin, createCanChecker, createChainBuilder, createDocument, createFloatingMenuPlugin, defaultBlockAt, defaultIcons, deleteSelection, findChildren, findParentNode, floatingMenuPluginKey, focus, focusPluginKey, generateHTML, generateJSON, generateText, getMarkRange, inlineStyles, insertContent, insertText, invisibleCharsPluginKey, isDocumentEmpty, isNodeEmpty, isValidUrl, lift, linkClickPlugin, linkClickPluginKey, linkExitPlugin, linkExitPluginKey, linkPastePlugin, linkPastePluginKey, markInputRule, markInputRulePatterns, placeholderPluginKey, positionFloating, positionFloatingOnce, resetAttributes, selectAll, selectNodeBackward, selectionDecorationPluginKey, setBlockType, setContent, setMark, toggleBlockType, toggleList, toggleMark, toggleWrap, uniqueIDPluginKey, unsetAllMarks, unsetMark, updateAttributes, wrapIn };
|
|
8823
|
+
export { BaseKeymap, Blockquote, Bold, BubbleMenu, BulletList, CanChecker, ChainBuilder, CharacterCount, ClearFormatting, Code, CodeBlock, CommandManager, DEFAULT_HIGHLIGHT_COLORS, DEFAULT_TEXT_COLORS, Document, Dropcursor, Editor, EventEmitter, Extension, ExtensionManager, FloatingMenu, Focus, FontFamily, FontSize, Gapcursor, HardBreak, Heading, Highlight, History, HorizontalRule, InvisibleChars, Italic, LineHeight, Link, LinkPopover, ListItem, ListKeymap, Mark, Node, OrderedList, Paragraph, Placeholder, Selection3 as Selection, SelectionDecoration, StarterKit, Strike, Subscript, Superscript, TaskItem, TaskList, Text, TextAlign, TextColor, TextStyle, ToolbarController, TrailingNode, Typography, Underline, UniqueID, VERSION, applyInlineStyles, autolinkPlugin, autolinkPluginKey, blur, bubbleMenuPluginKey, buildCommandProps, builtInCommands, callOrReturn, characterCountPluginKey, clearContent, createAccumulatingDispatch, createBubbleMenuPlugin, createCanChecker, createChainBuilder, createDocument, createFloatingMenuPlugin, defaultBlockAt, defaultIcons, deleteSelection, findChildren, findParentNode, floatingMenuPluginKey, focus, focusPluginKey, generateHTML, generateJSON, generateText, getMarkRange, inlineStyles, insertContent, insertText, invisibleCharsPluginKey, isDocumentEmpty, isNodeEmpty, isValidUrl, lift, linkClickPlugin, linkClickPluginKey, linkExitPlugin, linkExitPluginKey, linkPastePlugin, linkPastePluginKey, markInputRule, markInputRulePatterns, nodeInputRule, placeholderPluginKey, positionFloating, positionFloatingOnce, resetAttributes, selectAll, selectNodeBackward, selectionDecorationPluginKey, setBlockType, setContent, setMark, textInputRule, textblockTypeInputRule, toggleBlockType, toggleList, toggleMark, toggleWrap, uniqueIDPluginKey, unsetAllMarks, unsetMark, updateAttributes, wrapIn, wrappingInputRule };
|
|
8531
8824
|
//# sourceMappingURL=index.js.map
|
|
8532
8825
|
//# sourceMappingURL=index.js.map
|