@domternal/core 0.12.1 → 0.14.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/dist/index.cjs +165 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +42 -4
- package/dist/index.d.ts +42 -4
- package/dist/index.js +164 -41
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -1379,9 +1379,9 @@ var defaultBlockAt = (match) => {
|
|
|
1379
1379
|
};
|
|
1380
1380
|
|
|
1381
1381
|
// src/commands/contentCommands.ts
|
|
1382
|
-
var setContent = (content, options = {}) => ({ state, tr, dispatch }) => {
|
|
1382
|
+
var setContent = (content, options = {}) => ({ state: state$1, tr, dispatch }) => {
|
|
1383
1383
|
const { emitUpdate = true, parseOptions } = options;
|
|
1384
|
-
const { schema } = state;
|
|
1384
|
+
const { schema } = state$1;
|
|
1385
1385
|
let doc;
|
|
1386
1386
|
try {
|
|
1387
1387
|
doc = createDocument(content, schema, { parseOptions });
|
|
@@ -1392,6 +1392,8 @@ var setContent = (content, options = {}) => ({ state, tr, dispatch }) => {
|
|
|
1392
1392
|
return true;
|
|
1393
1393
|
}
|
|
1394
1394
|
tr.replaceWith(0, tr.doc.content.size, doc.content);
|
|
1395
|
+
const $end = tr.doc.resolve(tr.doc.content.size);
|
|
1396
|
+
tr.setSelection(state.TextSelection.between($end, $end, -1));
|
|
1395
1397
|
if (!emitUpdate) {
|
|
1396
1398
|
tr.setMeta("addToHistory", false);
|
|
1397
1399
|
tr.setMeta("skipUpdate", true);
|
|
@@ -4064,16 +4066,50 @@ var Editor = class _Editor extends EventEmitter {
|
|
|
4064
4066
|
return super.emit(event, ...args);
|
|
4065
4067
|
}
|
|
4066
4068
|
};
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
+
var OPPOSITE_SIDE = {
|
|
4070
|
+
top: "bottom",
|
|
4071
|
+
bottom: "top",
|
|
4072
|
+
left: "right",
|
|
4073
|
+
right: "left"
|
|
4074
|
+
};
|
|
4075
|
+
function oppositePlacement(placement) {
|
|
4076
|
+
const [side = "", alignment] = placement.split("-");
|
|
4077
|
+
const opposite = OPPOSITE_SIDE[side] ?? side;
|
|
4078
|
+
return alignment ? `${opposite}-${alignment}` : opposite;
|
|
4079
|
+
}
|
|
4080
|
+
function buildMiddleware(options, placementOpt) {
|
|
4069
4081
|
const paddingOpt = options?.padding ?? 10;
|
|
4070
4082
|
const overflowOpts = options?.boundary ? { padding: paddingOpt, boundary: options.boundary } : { padding: paddingOpt };
|
|
4071
|
-
const
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4083
|
+
const constrain = options?.constrainHeight;
|
|
4084
|
+
const middleware = [dom.offset(options?.offsetValue ?? 4)];
|
|
4085
|
+
if (constrain) {
|
|
4086
|
+
middleware.push(
|
|
4087
|
+
dom.size({
|
|
4088
|
+
...overflowOpts,
|
|
4089
|
+
apply({ availableHeight, elements }) {
|
|
4090
|
+
elements.floating.style.setProperty(
|
|
4091
|
+
"--dm-available-height",
|
|
4092
|
+
`${String(Math.max(constrain.minHeight, Math.floor(availableHeight)))}px`
|
|
4093
|
+
);
|
|
4094
|
+
}
|
|
4095
|
+
})
|
|
4096
|
+
);
|
|
4097
|
+
middleware.push(
|
|
4098
|
+
dom.flip({
|
|
4099
|
+
...overflowOpts,
|
|
4100
|
+
crossAxis: false,
|
|
4101
|
+
fallbackPlacements: [oppositePlacement(placementOpt)]
|
|
4102
|
+
})
|
|
4103
|
+
);
|
|
4104
|
+
} else {
|
|
4105
|
+
middleware.push(dom.flip(overflowOpts));
|
|
4106
|
+
}
|
|
4107
|
+
middleware.push(dom.shift(overflowOpts));
|
|
4108
|
+
return middleware;
|
|
4109
|
+
}
|
|
4110
|
+
function positionFloating(reference, floating, options) {
|
|
4111
|
+
const placementOpt = options?.placement ?? "bottom";
|
|
4112
|
+
const middleware = [...buildMiddleware(options, placementOpt), dom.hide()];
|
|
4077
4113
|
const update = () => {
|
|
4078
4114
|
void dom.computePosition(
|
|
4079
4115
|
reference,
|
|
@@ -4101,13 +4137,7 @@ function positionFloating(reference, floating, options) {
|
|
|
4101
4137
|
}
|
|
4102
4138
|
function positionFloatingOnce(reference, floating, options) {
|
|
4103
4139
|
const placementOpt = options?.placement ?? "bottom";
|
|
4104
|
-
const
|
|
4105
|
-
const overflowOpts = options?.boundary ? { padding: paddingOpt, boundary: options.boundary } : { padding: paddingOpt };
|
|
4106
|
-
const middleware = [
|
|
4107
|
-
dom.offset(options?.offsetValue ?? 4),
|
|
4108
|
-
dom.flip(overflowOpts),
|
|
4109
|
-
dom.shift(overflowOpts)
|
|
4110
|
-
];
|
|
4140
|
+
const middleware = buildMiddleware(options, placementOpt);
|
|
4111
4141
|
const update = () => {
|
|
4112
4142
|
void dom.computePosition(
|
|
4113
4143
|
reference,
|
|
@@ -4175,6 +4205,23 @@ function copyThemeClass(view, target) {
|
|
|
4175
4205
|
});
|
|
4176
4206
|
}
|
|
4177
4207
|
|
|
4208
|
+
// src/utils/announce.ts
|
|
4209
|
+
function announce(view, message) {
|
|
4210
|
+
const editorEl = view.dom.closest(".dm-editor");
|
|
4211
|
+
if (!(editorEl instanceof HTMLElement)) return;
|
|
4212
|
+
let region = editorEl.querySelector(":scope > .dm-live-region");
|
|
4213
|
+
if (!region) {
|
|
4214
|
+
region = document.createElement("div");
|
|
4215
|
+
region.className = "dm-live-region";
|
|
4216
|
+
region.setAttribute("data-dm-editor-ui", "");
|
|
4217
|
+
region.setAttribute("role", "status");
|
|
4218
|
+
region.setAttribute("aria-live", "polite");
|
|
4219
|
+
region.style.cssText = "position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;";
|
|
4220
|
+
editorEl.appendChild(region);
|
|
4221
|
+
}
|
|
4222
|
+
region.textContent = region.textContent === message ? `${message}\xA0` : message;
|
|
4223
|
+
}
|
|
4224
|
+
|
|
4178
4225
|
// src/utils/refocusEditorAfterCommand.ts
|
|
4179
4226
|
function refocusEditorAfterCommand(view) {
|
|
4180
4227
|
requestAnimationFrame(() => {
|
|
@@ -4193,6 +4240,10 @@ function refocusEditorAfterCommand(view) {
|
|
|
4193
4240
|
// src/utils/defaultBubbleContexts.ts
|
|
4194
4241
|
var NOTION_MODE_CLASS = "dm-notion-mode";
|
|
4195
4242
|
var NOTION_TEXT_CONTEXT = Object.freeze([
|
|
4243
|
+
// `ai` leads (Notion's "Ask AI"); skipped with its leading separator when
|
|
4244
|
+
// the pro extension is absent, exactly like `mathInline`.
|
|
4245
|
+
"ai",
|
|
4246
|
+
"|",
|
|
4196
4247
|
"bold",
|
|
4197
4248
|
"italic",
|
|
4198
4249
|
"underline",
|
|
@@ -4678,6 +4729,7 @@ var ToolbarController = class _ToolbarController {
|
|
|
4678
4729
|
* Executes a toolbar button's command.
|
|
4679
4730
|
*/
|
|
4680
4731
|
executeCommand(item) {
|
|
4732
|
+
if (!this.editor.isEditable && item.allowReadOnly !== true) return;
|
|
4681
4733
|
_ToolbarController.executeItem(this.editor, item);
|
|
4682
4734
|
this.updateActiveStates();
|
|
4683
4735
|
}
|
|
@@ -4920,16 +4972,20 @@ var ToolbarController = class _ToolbarController {
|
|
|
4920
4972
|
checkButtonDisabled(item, canProxy) {
|
|
4921
4973
|
const wasDisabled = this._disabledMap.get(item.name) ?? false;
|
|
4922
4974
|
let nowDisabled = false;
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4975
|
+
if (!this.editor.isEditable && item.allowReadOnly !== true) {
|
|
4976
|
+
nowDisabled = true;
|
|
4977
|
+
} else {
|
|
4978
|
+
try {
|
|
4979
|
+
if (item.emitEvent) {
|
|
4980
|
+
nowDisabled = this.editor.isActive("codeBlock");
|
|
4981
|
+
} else if (canProxy) {
|
|
4982
|
+
const canCmd = canProxy[item.command];
|
|
4983
|
+
if (canCmd) {
|
|
4984
|
+
nowDisabled = item.commandArgs?.length ? !canCmd(...item.commandArgs) : !canCmd();
|
|
4985
|
+
}
|
|
4930
4986
|
}
|
|
4987
|
+
} catch {
|
|
4931
4988
|
}
|
|
4932
|
-
} catch {
|
|
4933
4989
|
}
|
|
4934
4990
|
if (wasDisabled !== nowDisabled) {
|
|
4935
4991
|
this._disabledMap.set(item.name, nowDisabled);
|
|
@@ -5341,6 +5397,7 @@ function createFloatingMenuPlugin(options) {
|
|
|
5341
5397
|
};
|
|
5342
5398
|
hideMenu();
|
|
5343
5399
|
const isVisibleNow = (view) => {
|
|
5400
|
+
if (!editor.isEditable) return false;
|
|
5344
5401
|
const wantsShow = shouldShow({ editor, view, state: view.state });
|
|
5345
5402
|
if (!requireExplicitTrigger) return wantsShow;
|
|
5346
5403
|
const triggered = pluginKey.getState(view.state)?.triggered ?? false;
|
|
@@ -5720,7 +5777,8 @@ var Heading = Node2.create({
|
|
|
5720
5777
|
key: new state.PluginKey("headingKeydownFix"),
|
|
5721
5778
|
props: {
|
|
5722
5779
|
handleDOMEvents: {
|
|
5723
|
-
keydown(
|
|
5780
|
+
keydown(view, event) {
|
|
5781
|
+
if (!view.editable) return false;
|
|
5724
5782
|
if (!event.altKey || !(event.metaKey || event.ctrlKey)) return false;
|
|
5725
5783
|
const level = codeToLevel[event.code];
|
|
5726
5784
|
if (level === void 0) return false;
|
|
@@ -8173,6 +8231,18 @@ var Placeholder = Extension.create({
|
|
|
8173
8231
|
new state.Plugin({
|
|
8174
8232
|
key: placeholderPluginKey,
|
|
8175
8233
|
props: {
|
|
8234
|
+
// Focus and blur repaint the decorations: PM only recomputes
|
|
8235
|
+
// them when a transaction dispatches.
|
|
8236
|
+
handleDOMEvents: {
|
|
8237
|
+
focus: (view) => {
|
|
8238
|
+
view.dispatch(view.state.tr.setMeta(placeholderPluginKey, true));
|
|
8239
|
+
return false;
|
|
8240
|
+
},
|
|
8241
|
+
blur: (view) => {
|
|
8242
|
+
view.dispatch(view.state.tr.setMeta(placeholderPluginKey, false));
|
|
8243
|
+
return false;
|
|
8244
|
+
}
|
|
8245
|
+
},
|
|
8176
8246
|
decorations: ({ doc, selection }) => {
|
|
8177
8247
|
const editor = this.editor;
|
|
8178
8248
|
if (!editor) return view.DecorationSet.empty;
|
|
@@ -8188,6 +8258,10 @@ var Placeholder = Extension.create({
|
|
|
8188
8258
|
"data-placeholder": getPlaceholderText(node, pos)
|
|
8189
8259
|
});
|
|
8190
8260
|
if (showOnlyCurrent) {
|
|
8261
|
+
const view$1 = editor.view;
|
|
8262
|
+
if (!isDocEmpty && view$1?.hasFocus() !== true) {
|
|
8263
|
+
return view.DecorationSet.empty;
|
|
8264
|
+
}
|
|
8191
8265
|
const { $anchor } = selection;
|
|
8192
8266
|
if ($anchor.depth === 0) return view.DecorationSet.empty;
|
|
8193
8267
|
const node = $anchor.parent;
|
|
@@ -8783,7 +8857,13 @@ var UniqueID = Extension.create({
|
|
|
8783
8857
|
"listItem",
|
|
8784
8858
|
"taskItem",
|
|
8785
8859
|
"image",
|
|
8786
|
-
"horizontalRule"
|
|
8860
|
+
"horizontalRule",
|
|
8861
|
+
// Listed even though it lives in a separate package, exactly as
|
|
8862
|
+
// `image` already is: a global attribute only installs on types the
|
|
8863
|
+
// schema actually has, so naming it is inert when the table extension
|
|
8864
|
+
// is not loaded. Without it a table is the one block the block menu
|
|
8865
|
+
// cannot Copy link, and the one an id-anchored feature cannot address.
|
|
8866
|
+
"table"
|
|
8787
8867
|
],
|
|
8788
8868
|
attributeName: "id",
|
|
8789
8869
|
generateID: generateUUID,
|
|
@@ -8811,7 +8891,8 @@ var UniqueID = Extension.create({
|
|
|
8811
8891
|
addProseMirrorPlugins() {
|
|
8812
8892
|
const { types, attributeName, generateID, filterDuplicates } = this.options;
|
|
8813
8893
|
const editor = this.editor;
|
|
8814
|
-
const transformPastedSlice = (slice) => {
|
|
8894
|
+
const transformPastedSlice = (slice, view) => {
|
|
8895
|
+
if (view?.dragging?.move === true) return slice;
|
|
8815
8896
|
const existingIDs = /* @__PURE__ */ new Set();
|
|
8816
8897
|
editor?.state.doc.descendants((node) => {
|
|
8817
8898
|
const id = node.attrs[attributeName];
|
|
@@ -8845,7 +8926,36 @@ var UniqueID = Extension.create({
|
|
|
8845
8926
|
slice.openEnd
|
|
8846
8927
|
);
|
|
8847
8928
|
};
|
|
8848
|
-
const
|
|
8929
|
+
const incumbentPositions = (oldDoc, mapPos) => {
|
|
8930
|
+
const incumbents = /* @__PURE__ */ new Map();
|
|
8931
|
+
oldDoc.descendants((node, pos) => {
|
|
8932
|
+
if (!types.includes(node.type.name)) return;
|
|
8933
|
+
const id = node.attrs[attributeName];
|
|
8934
|
+
if (id && !incumbents.has(id)) incumbents.set(id, mapPos(pos));
|
|
8935
|
+
});
|
|
8936
|
+
return incumbents;
|
|
8937
|
+
};
|
|
8938
|
+
const assignMissingIDs = (doc, tr, incumbents) => {
|
|
8939
|
+
const winners = /* @__PURE__ */ new Map();
|
|
8940
|
+
if (incumbents && incumbents.size > 0) {
|
|
8941
|
+
const occurrences = /* @__PURE__ */ new Map();
|
|
8942
|
+
doc.descendants((node, pos) => {
|
|
8943
|
+
if (!types.includes(node.type.name)) return;
|
|
8944
|
+
const id = node.attrs[attributeName];
|
|
8945
|
+
if (!id) return;
|
|
8946
|
+
const list = occurrences.get(id);
|
|
8947
|
+
if (list) list.push(pos);
|
|
8948
|
+
else occurrences.set(id, [pos]);
|
|
8949
|
+
});
|
|
8950
|
+
for (const [id, positions] of occurrences) {
|
|
8951
|
+
if (positions.length < 2) continue;
|
|
8952
|
+
const incumbentPos = incumbents.get(id);
|
|
8953
|
+
winners.set(
|
|
8954
|
+
id,
|
|
8955
|
+
incumbentPos !== void 0 && positions.includes(incumbentPos) ? incumbentPos : positions[0]
|
|
8956
|
+
);
|
|
8957
|
+
}
|
|
8958
|
+
}
|
|
8849
8959
|
const seen = /* @__PURE__ */ new Set();
|
|
8850
8960
|
doc.descendants((node, pos) => {
|
|
8851
8961
|
if (!types.includes(node.type.name)) return;
|
|
@@ -8860,7 +8970,9 @@ var UniqueID = Extension.create({
|
|
|
8860
8970
|
});
|
|
8861
8971
|
return;
|
|
8862
8972
|
}
|
|
8863
|
-
|
|
8973
|
+
const winner = winners.get(existingID);
|
|
8974
|
+
const yieldsToWinner = winner !== void 0 && winner !== pos;
|
|
8975
|
+
if (seen.has(existingID) || yieldsToWinner) {
|
|
8864
8976
|
let id = generateID();
|
|
8865
8977
|
while (seen.has(id)) id = generateID();
|
|
8866
8978
|
seen.add(id);
|
|
@@ -8882,6 +8994,7 @@ var UniqueID = Extension.create({
|
|
|
8882
8994
|
const tr = editorView.state.tr;
|
|
8883
8995
|
assignMissingIDs(editorView.state.doc, tr);
|
|
8884
8996
|
if (tr.docChanged) {
|
|
8997
|
+
tr.setMeta("addToHistory", false);
|
|
8885
8998
|
editorView.dispatch(tr);
|
|
8886
8999
|
}
|
|
8887
9000
|
}, 0);
|
|
@@ -8892,12 +9005,18 @@ var UniqueID = Extension.create({
|
|
|
8892
9005
|
};
|
|
8893
9006
|
},
|
|
8894
9007
|
// Ensure new nodes get IDs
|
|
8895
|
-
appendTransaction(transactions,
|
|
9008
|
+
appendTransaction(transactions, oldState, newState) {
|
|
8896
9009
|
const docChanged = transactions.some((tr2) => tr2.docChanged);
|
|
8897
9010
|
if (!docChanged) return null;
|
|
9011
|
+
const mapForward = (pos) => transactions.reduce((p, transaction) => transaction.mapping.map(p), pos);
|
|
8898
9012
|
const tr = newState.tr;
|
|
8899
|
-
assignMissingIDs(newState.doc, tr);
|
|
8900
|
-
|
|
9013
|
+
assignMissingIDs(newState.doc, tr, incumbentPositions(oldState.doc, mapForward));
|
|
9014
|
+
if (!tr.docChanged) return null;
|
|
9015
|
+
const ridesAlongWithAnEdit = transactions.some(
|
|
9016
|
+
(transaction) => transaction.docChanged && transaction.getMeta("addToHistory") !== false
|
|
9017
|
+
);
|
|
9018
|
+
if (!ridesAlongWithAnEdit) tr.setMeta("addToHistory", false);
|
|
9019
|
+
return tr;
|
|
8901
9020
|
},
|
|
8902
9021
|
// Handle paste - filter duplicates
|
|
8903
9022
|
props: filterDuplicates ? {
|
|
@@ -9866,14 +9985,14 @@ var FontSize = Extension.create({
|
|
|
9866
9985
|
addToolbarItems() {
|
|
9867
9986
|
if (this.options.fontSizes.length === 0) return [];
|
|
9868
9987
|
const sizes = this.options.fontSizes;
|
|
9869
|
-
const items = sizes.map((
|
|
9988
|
+
const items = sizes.map((size2, i) => ({
|
|
9870
9989
|
type: "button",
|
|
9871
|
-
name: `fontSize-${
|
|
9990
|
+
name: `fontSize-${size2}`,
|
|
9872
9991
|
command: "setFontSize",
|
|
9873
|
-
commandArgs: [
|
|
9874
|
-
isActive: { name: "textStyle", attributes: { fontSize:
|
|
9992
|
+
commandArgs: [size2],
|
|
9993
|
+
isActive: { name: "textStyle", attributes: { fontSize: size2 } },
|
|
9875
9994
|
icon: "textSize",
|
|
9876
|
-
label:
|
|
9995
|
+
label: size2,
|
|
9877
9996
|
priority: 200 - i
|
|
9878
9997
|
}));
|
|
9879
9998
|
if (this.options.showReset) {
|
|
@@ -10337,7 +10456,7 @@ function createBubbleMenuPlugin(options) {
|
|
|
10337
10456
|
if (from !== prevValue.from || to !== prevValue.to) {
|
|
10338
10457
|
suppressed = false;
|
|
10339
10458
|
}
|
|
10340
|
-
const visible = !suppressed && !selection.empty && shouldShow({
|
|
10459
|
+
const visible = !suppressed && !selection.empty && editor.isEditable && shouldShow({
|
|
10341
10460
|
editor,
|
|
10342
10461
|
view: editor.view,
|
|
10343
10462
|
state: newState,
|
|
@@ -10377,7 +10496,7 @@ function createBubbleMenuPlugin(options) {
|
|
|
10377
10496
|
if (mouseDown) return;
|
|
10378
10497
|
const { selection } = editor.view.state;
|
|
10379
10498
|
const { from, to } = selection;
|
|
10380
|
-
const show = !selection.empty && shouldShow({
|
|
10499
|
+
const show = !selection.empty && editor.isEditable && shouldShow({
|
|
10381
10500
|
editor,
|
|
10382
10501
|
view: editor.view,
|
|
10383
10502
|
state: editor.view.state,
|
|
@@ -10413,6 +10532,10 @@ function createBubbleMenuPlugin(options) {
|
|
|
10413
10532
|
return {
|
|
10414
10533
|
update: (view, prevState) => {
|
|
10415
10534
|
if (view.composing) return;
|
|
10535
|
+
if (!view.editable) {
|
|
10536
|
+
hideMenu();
|
|
10537
|
+
return;
|
|
10538
|
+
}
|
|
10416
10539
|
const state = pluginKey.getState(view.state);
|
|
10417
10540
|
const prevPluginState = pluginKey.getState(prevState);
|
|
10418
10541
|
if (state?.visible === prevPluginState?.visible && state?.from === prevPluginState?.from && state?.to === prevPluginState?.to && !(state?.visible && view.state.doc !== prevState.doc)) {
|
|
@@ -10545,7 +10668,7 @@ var StarterKit = Extension.create({
|
|
|
10545
10668
|
});
|
|
10546
10669
|
|
|
10547
10670
|
// src/index.ts
|
|
10548
|
-
var VERSION = "0.
|
|
10671
|
+
var VERSION = "0.14.0";
|
|
10549
10672
|
|
|
10550
10673
|
Object.defineProperty(exports, "PluginKey", {
|
|
10551
10674
|
enumerable: true,
|
|
@@ -10621,6 +10744,7 @@ exports.Typography = Typography;
|
|
|
10621
10744
|
exports.Underline = Underline;
|
|
10622
10745
|
exports.UniqueID = UniqueID;
|
|
10623
10746
|
exports.VERSION = VERSION;
|
|
10747
|
+
exports.announce = announce;
|
|
10624
10748
|
exports.applyInlineStyles = applyInlineStyles;
|
|
10625
10749
|
exports.autolinkPlugin = autolinkPlugin;
|
|
10626
10750
|
exports.autolinkPluginKey = autolinkPluginKey;
|