@domternal/core 0.13.0 → 0.15.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 +41 -0
- package/dist/index.cjs +398 -86
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +177 -9
- package/dist/index.d.ts +177 -9
- package/dist/index.js +399 -88
- package/dist/index.js.map +1 -1
- package/package.json +12 -14
package/dist/index.cjs
CHANGED
|
@@ -1140,7 +1140,8 @@ function markInputRule(options) {
|
|
|
1140
1140
|
return null;
|
|
1141
1141
|
}
|
|
1142
1142
|
const { tr } = state;
|
|
1143
|
-
tr.
|
|
1143
|
+
const marks = tr.storedMarks ?? tr.doc.resolve(start).marksAcross(tr.doc.resolve(end));
|
|
1144
|
+
tr.replaceWith(start, end, state.schema.text(textContent, marks));
|
|
1144
1145
|
tr.addMark(start, start + textContent.length, type.create(attributes ?? void 0));
|
|
1145
1146
|
tr.removeStoredMark(type);
|
|
1146
1147
|
return tr;
|
|
@@ -1232,7 +1233,10 @@ function textInputRule(options) {
|
|
|
1232
1233
|
const { find: find2, replace, undoable } = options;
|
|
1233
1234
|
return new inputrules.InputRule(
|
|
1234
1235
|
find2,
|
|
1235
|
-
|
|
1236
|
+
// insertText inherits the replaced range's marks (stored marks first,
|
|
1237
|
+
// then marksAcross), so a replacement inside marked text keeps the
|
|
1238
|
+
// marks instead of punching an unmarked hole into them.
|
|
1239
|
+
(state, _match, start, end) => state.tr.insertText(replace, start, end),
|
|
1236
1240
|
undoable !== void 0 ? { undoable } : {}
|
|
1237
1241
|
);
|
|
1238
1242
|
}
|
|
@@ -1811,6 +1815,8 @@ var Mark = class _Mark extends Extension {
|
|
|
1811
1815
|
if (this.config.group !== void 0) spec.group = this.config.group;
|
|
1812
1816
|
if (this.config.spanning !== void 0)
|
|
1813
1817
|
spec.spanning = this.config.spanning;
|
|
1818
|
+
if (this.config.keepOnDuplicate !== void 0)
|
|
1819
|
+
spec["keepOnDuplicate"] = this.config.keepOnDuplicate;
|
|
1814
1820
|
const attributeSpecs = callOrReturn(this.config.addAttributes, this);
|
|
1815
1821
|
if (attributeSpecs) {
|
|
1816
1822
|
spec.attrs = buildProseMirrorAttrs(attributeSpecs);
|
|
@@ -1848,9 +1854,9 @@ var Mark = class _Mark extends Extension {
|
|
|
1848
1854
|
const renderFn = this.config.renderHTML;
|
|
1849
1855
|
const attrSpecs = attributeSpecs;
|
|
1850
1856
|
const markInstance = this;
|
|
1851
|
-
spec.toDOM = (
|
|
1852
|
-
const htmlAttrs = attrSpecs ? buildHTMLAttributes(
|
|
1853
|
-
return renderFn.call(markInstance, { mark, HTMLAttributes: htmlAttrs });
|
|
1857
|
+
spec.toDOM = (mark2, _inline) => {
|
|
1858
|
+
const htmlAttrs = attrSpecs ? buildHTMLAttributes(mark2.attrs, attrSpecs) : {};
|
|
1859
|
+
return renderFn.call(markInstance, { mark: mark2, HTMLAttributes: htmlAttrs });
|
|
1854
1860
|
};
|
|
1855
1861
|
}
|
|
1856
1862
|
return spec;
|
|
@@ -1943,8 +1949,8 @@ var setMark = (markName, attributes) => ({ state, tr, dispatch }) => {
|
|
|
1943
1949
|
const from = firstRange.$from.pos;
|
|
1944
1950
|
const existingMark = tr.storedMarks?.find((m) => m.type === markType) ?? state.storedMarks?.find((m) => m.type === markType) ?? tr.doc.resolve(from).marks().find((m) => m.type === markType) ?? null;
|
|
1945
1951
|
const mergedAttrs = existingMark ? { ...existingMark.attrs, ...attributes } : attributes;
|
|
1946
|
-
const
|
|
1947
|
-
tr.addStoredMark(
|
|
1952
|
+
const mark2 = markType.create(mergedAttrs);
|
|
1953
|
+
tr.addStoredMark(mark2);
|
|
1948
1954
|
dispatch(tr);
|
|
1949
1955
|
return true;
|
|
1950
1956
|
}
|
|
@@ -2571,12 +2577,12 @@ var updateAttributes = (typeOrName, attributes) => ({ state, tr, dispatch }) =>
|
|
|
2571
2577
|
const markType = state.schema.marks[typeOrName];
|
|
2572
2578
|
tr.doc.nodesBetween(from, to, (node, pos) => {
|
|
2573
2579
|
if (!node.isInline) return;
|
|
2574
|
-
const
|
|
2575
|
-
if (
|
|
2580
|
+
const mark2 = markType.isInSet(node.marks);
|
|
2581
|
+
if (mark2) {
|
|
2576
2582
|
markChanges.push({
|
|
2577
2583
|
pos,
|
|
2578
2584
|
nodeSize: node.nodeSize,
|
|
2579
|
-
attrs: { ...
|
|
2585
|
+
attrs: { ...mark2.attrs, ...attributes }
|
|
2580
2586
|
});
|
|
2581
2587
|
}
|
|
2582
2588
|
});
|
|
@@ -2622,12 +2628,12 @@ var resetAttributes = (typeOrName, attributeName) => ({ state, tr, dispatch }) =
|
|
|
2622
2628
|
const defaultValue = markType.spec.attrs?.[attributeName]?.default;
|
|
2623
2629
|
tr.doc.nodesBetween(from, to, (node, pos) => {
|
|
2624
2630
|
if (!node.isInline) return;
|
|
2625
|
-
const
|
|
2626
|
-
if (
|
|
2631
|
+
const mark2 = markType.isInSet(node.marks);
|
|
2632
|
+
if (mark2) {
|
|
2627
2633
|
markChanges.push({
|
|
2628
2634
|
pos,
|
|
2629
2635
|
nodeSize: node.nodeSize,
|
|
2630
|
-
attrs: { ...
|
|
2636
|
+
attrs: { ...mark2.attrs, [attributeName]: defaultValue }
|
|
2631
2637
|
});
|
|
2632
2638
|
}
|
|
2633
2639
|
});
|
|
@@ -3510,6 +3516,12 @@ var Editor = class _Editor extends EventEmitter {
|
|
|
3510
3516
|
* True while EditorView's constructor runs; see buildViewDispatch.
|
|
3511
3517
|
*/
|
|
3512
3518
|
_isViewConstructing = false;
|
|
3519
|
+
/**
|
|
3520
|
+
* The `.dm-editor` host this editor painted `dm-notion-mode` onto because
|
|
3521
|
+
* of `preset: 'notion'`. Tracked so destroy() removes only a class the
|
|
3522
|
+
* editor itself added, never one the consumer wrote.
|
|
3523
|
+
*/
|
|
3524
|
+
_presetClassHost = null;
|
|
3513
3525
|
/**
|
|
3514
3526
|
* Creates a new Editor instance
|
|
3515
3527
|
*
|
|
@@ -3554,6 +3566,43 @@ var Editor = class _Editor extends EventEmitter {
|
|
|
3554
3566
|
get isEditable() {
|
|
3555
3567
|
return this.view ? this.view.editable : this.options.editable ?? true;
|
|
3556
3568
|
}
|
|
3569
|
+
/**
|
|
3570
|
+
* The resolved editing-experience preset.
|
|
3571
|
+
*
|
|
3572
|
+
* The `preset` option wins when provided (so an explicit 'classic' can
|
|
3573
|
+
* opt out of everything). Otherwise a `dm-notion-mode` class on or above
|
|
3574
|
+
* the view counts as 'notion': consumers that predate the option declare
|
|
3575
|
+
* Notion mode with the theme class alone, and behavior must follow what
|
|
3576
|
+
* the user actually sees. Resolved on every read, not cached, so a class
|
|
3577
|
+
* toggled at runtime is picked up.
|
|
3578
|
+
*/
|
|
3579
|
+
get preset() {
|
|
3580
|
+
if (this.options.preset) {
|
|
3581
|
+
return this.options.preset;
|
|
3582
|
+
}
|
|
3583
|
+
if (this.view?.dom.closest(".dm-notion-mode")) {
|
|
3584
|
+
return "notion";
|
|
3585
|
+
}
|
|
3586
|
+
return "classic";
|
|
3587
|
+
}
|
|
3588
|
+
/**
|
|
3589
|
+
* Paints `dm-notion-mode` on the `.dm-editor` host when the editor was
|
|
3590
|
+
* created with `preset: 'notion'`. Runs during creation, and framework
|
|
3591
|
+
* wrappers call it again after adopting the view's DOM: they construct
|
|
3592
|
+
* the editor in a detached element, so the creation-time run cannot see
|
|
3593
|
+
* the host yet. Idempotent; a no-op for any other preset. Only a class
|
|
3594
|
+
* added here is removed again on destroy.
|
|
3595
|
+
*/
|
|
3596
|
+
adoptPresetClass() {
|
|
3597
|
+
if (this.options.preset !== "notion" || this._presetClassHost) {
|
|
3598
|
+
return;
|
|
3599
|
+
}
|
|
3600
|
+
const host = this.view.dom.closest(".dm-editor");
|
|
3601
|
+
if (host && !host.classList.contains("dm-notion-mode")) {
|
|
3602
|
+
host.classList.add("dm-notion-mode");
|
|
3603
|
+
this._presetClassHost = host;
|
|
3604
|
+
}
|
|
3605
|
+
}
|
|
3557
3606
|
/**
|
|
3558
3607
|
* Checks if the editor content is empty
|
|
3559
3608
|
*/
|
|
@@ -3639,11 +3688,11 @@ var Editor = class _Editor extends EventEmitter {
|
|
|
3639
3688
|
if (markType) {
|
|
3640
3689
|
if (selection.empty) {
|
|
3641
3690
|
const storedMarks = state.storedMarks ?? $from.marks();
|
|
3642
|
-
const hasMark = storedMarks.some((
|
|
3691
|
+
const hasMark = storedMarks.some((mark2) => mark2.type === markType);
|
|
3643
3692
|
if (!hasMark) return false;
|
|
3644
3693
|
if (attrs) {
|
|
3645
|
-
const
|
|
3646
|
-
return
|
|
3694
|
+
const mark2 = storedMarks.find((m) => m.type === markType);
|
|
3695
|
+
return mark2 ? this.matchAttributes(mark2.attrs, attrs) : false;
|
|
3647
3696
|
}
|
|
3648
3697
|
return true;
|
|
3649
3698
|
}
|
|
@@ -3718,8 +3767,8 @@ var Editor = class _Editor extends EventEmitter {
|
|
|
3718
3767
|
const markType = schema.marks[name];
|
|
3719
3768
|
if (markType) {
|
|
3720
3769
|
const marks = state.storedMarks ?? $from.marks();
|
|
3721
|
-
const
|
|
3722
|
-
return
|
|
3770
|
+
const mark2 = marks.find((m) => m.type === markType);
|
|
3771
|
+
return mark2 ? { ...mark2.attrs } : {};
|
|
3723
3772
|
}
|
|
3724
3773
|
const nodeType = schema.nodes[name];
|
|
3725
3774
|
if (nodeType) {
|
|
@@ -3900,6 +3949,10 @@ var Editor = class _Editor extends EventEmitter {
|
|
|
3900
3949
|
}
|
|
3901
3950
|
this.emit("destroy");
|
|
3902
3951
|
this.options.onDestroy?.();
|
|
3952
|
+
if (this._presetClassHost) {
|
|
3953
|
+
this._presetClassHost.classList.remove("dm-notion-mode");
|
|
3954
|
+
this._presetClassHost = null;
|
|
3955
|
+
}
|
|
3903
3956
|
this.view.destroy();
|
|
3904
3957
|
this._extensionManager.destroy();
|
|
3905
3958
|
this.removeAllListeners();
|
|
@@ -4002,6 +4055,7 @@ var Editor = class _Editor extends EventEmitter {
|
|
|
4002
4055
|
}
|
|
4003
4056
|
});
|
|
4004
4057
|
this._isViewConstructing = false;
|
|
4058
|
+
this.adoptPresetClass();
|
|
4005
4059
|
this.emit("mount", { editor: this, view: this.view });
|
|
4006
4060
|
this.options.onMount?.({ editor: this, view: this.view });
|
|
4007
4061
|
this.commandManager = new CommandManager(this);
|
|
@@ -4066,16 +4120,50 @@ var Editor = class _Editor extends EventEmitter {
|
|
|
4066
4120
|
return super.emit(event, ...args);
|
|
4067
4121
|
}
|
|
4068
4122
|
};
|
|
4069
|
-
|
|
4070
|
-
|
|
4123
|
+
var OPPOSITE_SIDE = {
|
|
4124
|
+
top: "bottom",
|
|
4125
|
+
bottom: "top",
|
|
4126
|
+
left: "right",
|
|
4127
|
+
right: "left"
|
|
4128
|
+
};
|
|
4129
|
+
function oppositePlacement(placement) {
|
|
4130
|
+
const [side = "", alignment] = placement.split("-");
|
|
4131
|
+
const opposite = OPPOSITE_SIDE[side] ?? side;
|
|
4132
|
+
return alignment ? `${opposite}-${alignment}` : opposite;
|
|
4133
|
+
}
|
|
4134
|
+
function buildMiddleware(options, placementOpt) {
|
|
4071
4135
|
const paddingOpt = options?.padding ?? 10;
|
|
4072
4136
|
const overflowOpts = options?.boundary ? { padding: paddingOpt, boundary: options.boundary } : { padding: paddingOpt };
|
|
4073
|
-
const
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4137
|
+
const constrain = options?.constrainHeight;
|
|
4138
|
+
const middleware = [dom.offset(options?.offsetValue ?? 4)];
|
|
4139
|
+
if (constrain) {
|
|
4140
|
+
middleware.push(
|
|
4141
|
+
dom.size({
|
|
4142
|
+
...overflowOpts,
|
|
4143
|
+
apply({ availableHeight, elements }) {
|
|
4144
|
+
elements.floating.style.setProperty(
|
|
4145
|
+
"--dm-available-height",
|
|
4146
|
+
`${String(Math.max(constrain.minHeight, Math.floor(availableHeight)))}px`
|
|
4147
|
+
);
|
|
4148
|
+
}
|
|
4149
|
+
})
|
|
4150
|
+
);
|
|
4151
|
+
middleware.push(
|
|
4152
|
+
dom.flip({
|
|
4153
|
+
...overflowOpts,
|
|
4154
|
+
crossAxis: false,
|
|
4155
|
+
fallbackPlacements: [oppositePlacement(placementOpt)]
|
|
4156
|
+
})
|
|
4157
|
+
);
|
|
4158
|
+
} else {
|
|
4159
|
+
middleware.push(dom.flip(overflowOpts));
|
|
4160
|
+
}
|
|
4161
|
+
middleware.push(dom.shift(overflowOpts));
|
|
4162
|
+
return middleware;
|
|
4163
|
+
}
|
|
4164
|
+
function positionFloating(reference, floating, options) {
|
|
4165
|
+
const placementOpt = options?.placement ?? "bottom";
|
|
4166
|
+
const middleware = [...buildMiddleware(options, placementOpt), dom.hide()];
|
|
4079
4167
|
const update = () => {
|
|
4080
4168
|
void dom.computePosition(
|
|
4081
4169
|
reference,
|
|
@@ -4103,13 +4191,7 @@ function positionFloating(reference, floating, options) {
|
|
|
4103
4191
|
}
|
|
4104
4192
|
function positionFloatingOnce(reference, floating, options) {
|
|
4105
4193
|
const placementOpt = options?.placement ?? "bottom";
|
|
4106
|
-
const
|
|
4107
|
-
const overflowOpts = options?.boundary ? { padding: paddingOpt, boundary: options.boundary } : { padding: paddingOpt };
|
|
4108
|
-
const middleware = [
|
|
4109
|
-
dom.offset(options?.offsetValue ?? 4),
|
|
4110
|
-
dom.flip(overflowOpts),
|
|
4111
|
-
dom.shift(overflowOpts)
|
|
4112
|
-
];
|
|
4194
|
+
const middleware = buildMiddleware(options, placementOpt);
|
|
4113
4195
|
const update = () => {
|
|
4114
4196
|
void dom.computePosition(
|
|
4115
4197
|
reference,
|
|
@@ -4210,7 +4292,6 @@ function refocusEditorAfterCommand(view) {
|
|
|
4210
4292
|
}
|
|
4211
4293
|
|
|
4212
4294
|
// src/utils/defaultBubbleContexts.ts
|
|
4213
|
-
var NOTION_MODE_CLASS = "dm-notion-mode";
|
|
4214
4295
|
var NOTION_TEXT_CONTEXT = Object.freeze([
|
|
4215
4296
|
// `ai` leads (Notion's "Ask AI"); skipped with its leading separator when
|
|
4216
4297
|
// the pro extension is absent, exactly like `mathInline`.
|
|
@@ -4238,8 +4319,7 @@ var STANDARD_TEXT_CONTEXT = Object.freeze([
|
|
|
4238
4319
|
"link"
|
|
4239
4320
|
]);
|
|
4240
4321
|
function defaultBubbleContexts(editor) {
|
|
4241
|
-
const
|
|
4242
|
-
const text = inNotionMode ? NOTION_TEXT_CONTEXT : STANDARD_TEXT_CONTEXT;
|
|
4322
|
+
const text = editor.preset === "notion" ? NOTION_TEXT_CONTEXT : STANDARD_TEXT_CONTEXT;
|
|
4243
4323
|
return { text: [...text] };
|
|
4244
4324
|
}
|
|
4245
4325
|
|
|
@@ -4701,6 +4781,7 @@ var ToolbarController = class _ToolbarController {
|
|
|
4701
4781
|
* Executes a toolbar button's command.
|
|
4702
4782
|
*/
|
|
4703
4783
|
executeCommand(item) {
|
|
4784
|
+
if (!this.editor.isEditable && item.allowReadOnly !== true) return;
|
|
4704
4785
|
_ToolbarController.executeItem(this.editor, item);
|
|
4705
4786
|
this.updateActiveStates();
|
|
4706
4787
|
}
|
|
@@ -4943,16 +5024,20 @@ var ToolbarController = class _ToolbarController {
|
|
|
4943
5024
|
checkButtonDisabled(item, canProxy) {
|
|
4944
5025
|
const wasDisabled = this._disabledMap.get(item.name) ?? false;
|
|
4945
5026
|
let nowDisabled = false;
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
|
|
5027
|
+
if (!this.editor.isEditable && item.allowReadOnly !== true) {
|
|
5028
|
+
nowDisabled = true;
|
|
5029
|
+
} else {
|
|
5030
|
+
try {
|
|
5031
|
+
if (item.emitEvent) {
|
|
5032
|
+
nowDisabled = this.editor.isActive("codeBlock");
|
|
5033
|
+
} else if (canProxy) {
|
|
5034
|
+
const canCmd = canProxy[item.command];
|
|
5035
|
+
if (canCmd) {
|
|
5036
|
+
nowDisabled = item.commandArgs?.length ? !canCmd(...item.commandArgs) : !canCmd();
|
|
5037
|
+
}
|
|
4953
5038
|
}
|
|
5039
|
+
} catch {
|
|
4954
5040
|
}
|
|
4955
|
-
} catch {
|
|
4956
5041
|
}
|
|
4957
5042
|
if (wasDisabled !== nowDisabled) {
|
|
4958
5043
|
this._disabledMap.set(item.name, nowDisabled);
|
|
@@ -4993,7 +5078,8 @@ function groupFloatingMenuItems(items) {
|
|
|
4993
5078
|
if (!list) {
|
|
4994
5079
|
list = [];
|
|
4995
5080
|
map.set(name, list);
|
|
4996
|
-
order.
|
|
5081
|
+
if (name === "") order.unshift(name);
|
|
5082
|
+
else order.push(name);
|
|
4997
5083
|
}
|
|
4998
5084
|
list.push(item);
|
|
4999
5085
|
}
|
|
@@ -5364,6 +5450,7 @@ function createFloatingMenuPlugin(options) {
|
|
|
5364
5450
|
};
|
|
5365
5451
|
hideMenu();
|
|
5366
5452
|
const isVisibleNow = (view) => {
|
|
5453
|
+
if (!editor.isEditable) return false;
|
|
5367
5454
|
const wantsShow = shouldShow({ editor, view, state: view.state });
|
|
5368
5455
|
if (!requireExplicitTrigger) return wantsShow;
|
|
5369
5456
|
const triggered = pluginKey.getState(view.state)?.triggered ?? false;
|
|
@@ -5526,7 +5613,8 @@ var defaultIcons = {
|
|
|
5526
5613
|
plus: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="currentColor"><path d="M224,128a8,8,0,0,1-8,8H136v80a8,8,0,0,1-16,0V136H40a8,8,0,0,1,0-16h80V40a8,8,0,0,1,16,0v80h80A8,8,0,0,1,224,128Z"/></svg>',
|
|
5527
5614
|
dotsSixVertical: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="currentColor"><path d="M108,60A16,16,0,1,1,92,44,16,16,0,0,1,108,60Zm56,16A16,16,0,1,0,148,60,16,16,0,0,0,164,76ZM92,112a16,16,0,1,0,16,16A16,16,0,0,0,92,112Zm72,0a16,16,0,1,0,16,16A16,16,0,0,0,164,112ZM92,180a16,16,0,1,0,16,16A16,16,0,0,0,92,180Zm72,0a16,16,0,1,0,16,16A16,16,0,0,0,164,180Z"/></svg>',
|
|
5528
5615
|
dotsThree: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="currentColor"><path d="M140,128a12,12,0,1,1-12-12A12,12,0,0,1,140,128ZM64,116a12,12,0,1,0,12,12A12,12,0,0,0,64,116Zm128,0a12,12,0,1,0,12,12A12,12,0,0,0,192,116Z"/></svg>',
|
|
5529
|
-
copy: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="currentColor"><path d="M216,32H88a8,8,0,0,0-8,8V80H40a8,8,0,0,0-8,8V216a8,8,0,0,0,8,8H168a8,8,0,0,0,8-8V176h40a8,8,0,0,0,8-8V40A8,8,0,0,0,216,32ZM160,208H48V96H160Zm48-48H176V88a8,8,0,0,0-8-8H96V48H208Z"/></svg>'
|
|
5616
|
+
copy: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="currentColor"><path d="M216,32H88a8,8,0,0,0-8,8V80H40a8,8,0,0,0-8,8V216a8,8,0,0,0,8,8H168a8,8,0,0,0,8-8V176h40a8,8,0,0,0,8-8V40A8,8,0,0,0,216,32ZM160,208H48V96H160Zm48-48H176V88a8,8,0,0,0-8-8H96V48H208Z"/></svg>',
|
|
5617
|
+
printer: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="currentColor"><path d="M214.67,72H200V40a8,8,0,0,0-8-8H64a8,8,0,0,0-8,8V72H41.33C27.36,72,16,82.77,16,96v80a8,8,0,0,0,8,8H56v32a8,8,0,0,0,8,8H192a8,8,0,0,0,8-8V184h32a8,8,0,0,0,8-8V96C240,82.77,228.64,72,214.67,72ZM72,48H184V72H72ZM184,208H72V160H184Zm40-40H200V152a8,8,0,0,0-8-8H64a8,8,0,0,0-8,8v16H32V96c0-4.34,4.28-8,9.33-8H214.67c5.05,0,9.33,3.66,9.33,8Zm-24-52a12,12,0,1,1-12-12A12,12,0,0,1,200,116Z"/></svg>'
|
|
5530
5618
|
};
|
|
5531
5619
|
|
|
5532
5620
|
// src/nodes/Document.ts
|
|
@@ -5743,7 +5831,8 @@ var Heading = Node2.create({
|
|
|
5743
5831
|
key: new state.PluginKey("headingKeydownFix"),
|
|
5744
5832
|
props: {
|
|
5745
5833
|
handleDOMEvents: {
|
|
5746
|
-
keydown(
|
|
5834
|
+
keydown(view, event) {
|
|
5835
|
+
if (!view.editable) return false;
|
|
5747
5836
|
if (!event.altKey || !(event.metaKey || event.ctrlKey)) return false;
|
|
5748
5837
|
const level = codeToLevel[event.code];
|
|
5749
5838
|
if (level === void 0) return false;
|
|
@@ -7057,6 +7146,7 @@ var TaskList = Node2.create({
|
|
|
7057
7146
|
// src/marks/Bold.ts
|
|
7058
7147
|
var Bold = Mark.create({
|
|
7059
7148
|
name: "bold",
|
|
7149
|
+
group: "formatting",
|
|
7060
7150
|
addOptions() {
|
|
7061
7151
|
return {
|
|
7062
7152
|
HTMLAttributes: {}
|
|
@@ -7134,6 +7224,7 @@ var Bold = Mark.create({
|
|
|
7134
7224
|
// src/marks/Italic.ts
|
|
7135
7225
|
var Italic = Mark.create({
|
|
7136
7226
|
name: "italic",
|
|
7227
|
+
group: "formatting",
|
|
7137
7228
|
addOptions() {
|
|
7138
7229
|
return {
|
|
7139
7230
|
HTMLAttributes: {}
|
|
@@ -7213,6 +7304,7 @@ var Italic = Mark.create({
|
|
|
7213
7304
|
// src/marks/Underline.ts
|
|
7214
7305
|
var Underline = Mark.create({
|
|
7215
7306
|
name: "underline",
|
|
7307
|
+
group: "formatting",
|
|
7216
7308
|
addOptions() {
|
|
7217
7309
|
return {
|
|
7218
7310
|
HTMLAttributes: {}
|
|
@@ -7265,6 +7357,7 @@ var Underline = Mark.create({
|
|
|
7265
7357
|
// src/marks/Strike.ts
|
|
7266
7358
|
var Strike = Mark.create({
|
|
7267
7359
|
name: "strike",
|
|
7360
|
+
group: "formatting",
|
|
7268
7361
|
addOptions() {
|
|
7269
7362
|
return {
|
|
7270
7363
|
HTMLAttributes: {}
|
|
@@ -7336,9 +7429,14 @@ var Code = Mark.create({
|
|
|
7336
7429
|
HTMLAttributes: {}
|
|
7337
7430
|
};
|
|
7338
7431
|
},
|
|
7339
|
-
// Code
|
|
7340
|
-
//
|
|
7341
|
-
|
|
7432
|
+
// Code cannot be combined with other FORMATTING marks (bold, italic,
|
|
7433
|
+
// color...), but semantic marks outside the group (link, a comment
|
|
7434
|
+
// thread anchor) survive: code excludes the 'formatting' group instead
|
|
7435
|
+
// of '_' (everything). Third-party formatting marks opt into the same
|
|
7436
|
+
// exclusion by declaring group: 'formatting'. Code is in the group
|
|
7437
|
+
// itself, which also keeps it self-exclusive.
|
|
7438
|
+
group: "formatting",
|
|
7439
|
+
excludes: "formatting",
|
|
7342
7440
|
// Code should not span across multiple nodes
|
|
7343
7441
|
spanning: false,
|
|
7344
7442
|
parseHTML() {
|
|
@@ -7826,6 +7924,7 @@ var Link = Mark.create({
|
|
|
7826
7924
|
// src/marks/Subscript.ts
|
|
7827
7925
|
var Subscript = Mark.create({
|
|
7828
7926
|
name: "subscript",
|
|
7927
|
+
group: "formatting",
|
|
7829
7928
|
// Mutual exclusion handled in toggle commands (not schema)
|
|
7830
7929
|
// so can() dry-run works correctly for toolbar disabled state
|
|
7831
7930
|
excludes: "",
|
|
@@ -7887,6 +7986,7 @@ var Subscript = Mark.create({
|
|
|
7887
7986
|
// src/marks/Superscript.ts
|
|
7888
7987
|
var Superscript = Mark.create({
|
|
7889
7988
|
name: "superscript",
|
|
7989
|
+
group: "formatting",
|
|
7890
7990
|
// Mutual exclusion handled in toggle commands (not schema)
|
|
7891
7991
|
// so can() dry-run works correctly for toolbar disabled state
|
|
7892
7992
|
excludes: "",
|
|
@@ -7948,6 +8048,7 @@ var Superscript = Mark.create({
|
|
|
7948
8048
|
// src/marks/TextStyle.ts
|
|
7949
8049
|
var TextStyle = Mark.create({
|
|
7950
8050
|
name: "textStyle",
|
|
8051
|
+
group: "formatting",
|
|
7951
8052
|
// Lower priority so it renders after other marks
|
|
7952
8053
|
priority: 101,
|
|
7953
8054
|
addOptions() {
|
|
@@ -8004,7 +8105,7 @@ var TextStyle = Mark.create({
|
|
|
8004
8105
|
let hasEmptyTextStyle = false;
|
|
8005
8106
|
tr.doc.nodesBetween(from, to, (node) => {
|
|
8006
8107
|
const textStyleMark = node.marks.find(
|
|
8007
|
-
(
|
|
8108
|
+
(mark2) => mark2.type.name === this.name
|
|
8008
8109
|
);
|
|
8009
8110
|
if (textStyleMark) {
|
|
8010
8111
|
const hasNonNullAttr = Object.values(textStyleMark.attrs).some(
|
|
@@ -8018,9 +8119,9 @@ var TextStyle = Mark.create({
|
|
|
8018
8119
|
if (!hasEmptyTextStyle) return false;
|
|
8019
8120
|
if (dispatch) {
|
|
8020
8121
|
tr.doc.nodesBetween(from, to, (node, pos) => {
|
|
8021
|
-
const
|
|
8022
|
-
if (
|
|
8023
|
-
const hasActiveAttr = Object.values(
|
|
8122
|
+
const mark2 = node.marks.find((m) => m.type === markType);
|
|
8123
|
+
if (mark2) {
|
|
8124
|
+
const hasActiveAttr = Object.values(mark2.attrs).some(
|
|
8024
8125
|
(v) => v !== null && v !== void 0
|
|
8025
8126
|
);
|
|
8026
8127
|
if (!hasActiveAttr) {
|
|
@@ -8525,11 +8626,7 @@ var Typography = Extension.create({
|
|
|
8525
8626
|
rules.push(
|
|
8526
8627
|
new inputrules.InputRule(/"([^"]+)"$/, (state, match, start, end) => {
|
|
8527
8628
|
const text = match[1] ?? "";
|
|
8528
|
-
return state.tr.
|
|
8529
|
-
start,
|
|
8530
|
-
end,
|
|
8531
|
-
state.schema.text(openDoubleQuote + text + closeDoubleQuote)
|
|
8532
|
-
);
|
|
8629
|
+
return state.tr.insertText(openDoubleQuote + text + closeDoubleQuote, start, end);
|
|
8533
8630
|
})
|
|
8534
8631
|
);
|
|
8535
8632
|
rules.push(
|
|
@@ -8537,12 +8634,10 @@ var Typography = Extension.create({
|
|
|
8537
8634
|
const text = match[1] ?? "";
|
|
8538
8635
|
const prefix = match[0].charAt(0);
|
|
8539
8636
|
const hasPrefix = prefix !== "'";
|
|
8540
|
-
return state.tr.
|
|
8637
|
+
return state.tr.insertText(
|
|
8638
|
+
hasPrefix ? prefix + openSingleQuote + text + closeSingleQuote : openSingleQuote + text + closeSingleQuote,
|
|
8541
8639
|
start,
|
|
8542
|
-
end
|
|
8543
|
-
state.schema.text(
|
|
8544
|
-
hasPrefix ? prefix + openSingleQuote + text + closeSingleQuote : openSingleQuote + text + closeSingleQuote
|
|
8545
|
-
)
|
|
8640
|
+
end
|
|
8546
8641
|
);
|
|
8547
8642
|
})
|
|
8548
8643
|
);
|
|
@@ -8807,6 +8902,9 @@ function generateUUID() {
|
|
|
8807
8902
|
});
|
|
8808
8903
|
}
|
|
8809
8904
|
var uniqueIDPluginKey = new state.PluginKey("uniqueID");
|
|
8905
|
+
function isWithin(from, to, ranges) {
|
|
8906
|
+
return ranges.some((range) => from >= range.from && to <= range.to);
|
|
8907
|
+
}
|
|
8810
8908
|
var UniqueID = Extension.create({
|
|
8811
8909
|
name: "uniqueID",
|
|
8812
8910
|
addOptions() {
|
|
@@ -8822,7 +8920,13 @@ var UniqueID = Extension.create({
|
|
|
8822
8920
|
"listItem",
|
|
8823
8921
|
"taskItem",
|
|
8824
8922
|
"image",
|
|
8825
|
-
"horizontalRule"
|
|
8923
|
+
"horizontalRule",
|
|
8924
|
+
// Listed even though it lives in a separate package, exactly as
|
|
8925
|
+
// `image` already is: a global attribute only installs on types the
|
|
8926
|
+
// schema actually has, so naming it is inert when the table extension
|
|
8927
|
+
// is not loaded. Without it a table is the one block the block menu
|
|
8928
|
+
// cannot Copy link, and the one an id-anchored feature cannot address.
|
|
8929
|
+
"table"
|
|
8826
8930
|
],
|
|
8827
8931
|
attributeName: "id",
|
|
8828
8932
|
generateID: generateUUID,
|
|
@@ -8850,11 +8954,27 @@ var UniqueID = Extension.create({
|
|
|
8850
8954
|
addProseMirrorPlugins() {
|
|
8851
8955
|
const { types, attributeName, generateID, filterDuplicates } = this.options;
|
|
8852
8956
|
const editor = this.editor;
|
|
8853
|
-
const
|
|
8957
|
+
const replacedRanges = (view) => {
|
|
8958
|
+
if (view?.dragging) return [];
|
|
8959
|
+
const ranges = view?.state?.selection?.ranges;
|
|
8960
|
+
if (ranges === void 0) return [];
|
|
8961
|
+
const replaced = [];
|
|
8962
|
+
for (const range of ranges) {
|
|
8963
|
+
if (range.$to.pos > range.$from.pos) {
|
|
8964
|
+
replaced.push({ from: range.$from.pos, to: range.$to.pos });
|
|
8965
|
+
}
|
|
8966
|
+
}
|
|
8967
|
+
return replaced;
|
|
8968
|
+
};
|
|
8969
|
+
const transformPastedSlice = (slice, view) => {
|
|
8970
|
+
if (view?.dragging?.move === true) return slice;
|
|
8854
8971
|
const existingIDs = /* @__PURE__ */ new Set();
|
|
8855
|
-
|
|
8972
|
+
const replaced = replacedRanges(view);
|
|
8973
|
+
editor?.state.doc.descendants((node, pos) => {
|
|
8974
|
+
if (isWithin(pos, pos + node.nodeSize, replaced)) return false;
|
|
8856
8975
|
const id = node.attrs[attributeName];
|
|
8857
8976
|
if (id) existingIDs.add(id);
|
|
8977
|
+
return true;
|
|
8858
8978
|
});
|
|
8859
8979
|
const transformNode = (node) => {
|
|
8860
8980
|
if (!types.includes(node.type.name)) {
|
|
@@ -8884,7 +9004,36 @@ var UniqueID = Extension.create({
|
|
|
8884
9004
|
slice.openEnd
|
|
8885
9005
|
);
|
|
8886
9006
|
};
|
|
8887
|
-
const
|
|
9007
|
+
const incumbentPositions = (oldDoc, mapPos) => {
|
|
9008
|
+
const incumbents = /* @__PURE__ */ new Map();
|
|
9009
|
+
oldDoc.descendants((node, pos) => {
|
|
9010
|
+
if (!types.includes(node.type.name)) return;
|
|
9011
|
+
const id = node.attrs[attributeName];
|
|
9012
|
+
if (id && !incumbents.has(id)) incumbents.set(id, mapPos(pos));
|
|
9013
|
+
});
|
|
9014
|
+
return incumbents;
|
|
9015
|
+
};
|
|
9016
|
+
const assignMissingIDs = (doc, tr, incumbents) => {
|
|
9017
|
+
const winners = /* @__PURE__ */ new Map();
|
|
9018
|
+
if (incumbents && incumbents.size > 0) {
|
|
9019
|
+
const occurrences = /* @__PURE__ */ new Map();
|
|
9020
|
+
doc.descendants((node, pos) => {
|
|
9021
|
+
if (!types.includes(node.type.name)) return;
|
|
9022
|
+
const id = node.attrs[attributeName];
|
|
9023
|
+
if (!id) return;
|
|
9024
|
+
const list = occurrences.get(id);
|
|
9025
|
+
if (list) list.push(pos);
|
|
9026
|
+
else occurrences.set(id, [pos]);
|
|
9027
|
+
});
|
|
9028
|
+
for (const [id, positions] of occurrences) {
|
|
9029
|
+
if (positions.length < 2) continue;
|
|
9030
|
+
const incumbentPos = incumbents.get(id);
|
|
9031
|
+
winners.set(
|
|
9032
|
+
id,
|
|
9033
|
+
incumbentPos !== void 0 && positions.includes(incumbentPos) ? incumbentPos : positions[0]
|
|
9034
|
+
);
|
|
9035
|
+
}
|
|
9036
|
+
}
|
|
8888
9037
|
const seen = /* @__PURE__ */ new Set();
|
|
8889
9038
|
doc.descendants((node, pos) => {
|
|
8890
9039
|
if (!types.includes(node.type.name)) return;
|
|
@@ -8899,7 +9048,9 @@ var UniqueID = Extension.create({
|
|
|
8899
9048
|
});
|
|
8900
9049
|
return;
|
|
8901
9050
|
}
|
|
8902
|
-
|
|
9051
|
+
const winner = winners.get(existingID);
|
|
9052
|
+
const yieldsToWinner = winner !== void 0 && winner !== pos;
|
|
9053
|
+
if (seen.has(existingID) || yieldsToWinner) {
|
|
8903
9054
|
let id = generateID();
|
|
8904
9055
|
while (seen.has(id)) id = generateID();
|
|
8905
9056
|
seen.add(id);
|
|
@@ -8921,6 +9072,7 @@ var UniqueID = Extension.create({
|
|
|
8921
9072
|
const tr = editorView.state.tr;
|
|
8922
9073
|
assignMissingIDs(editorView.state.doc, tr);
|
|
8923
9074
|
if (tr.docChanged) {
|
|
9075
|
+
tr.setMeta("addToHistory", false);
|
|
8924
9076
|
editorView.dispatch(tr);
|
|
8925
9077
|
}
|
|
8926
9078
|
}, 0);
|
|
@@ -8931,12 +9083,18 @@ var UniqueID = Extension.create({
|
|
|
8931
9083
|
};
|
|
8932
9084
|
},
|
|
8933
9085
|
// Ensure new nodes get IDs
|
|
8934
|
-
appendTransaction(transactions,
|
|
9086
|
+
appendTransaction(transactions, oldState, newState) {
|
|
8935
9087
|
const docChanged = transactions.some((tr2) => tr2.docChanged);
|
|
8936
9088
|
if (!docChanged) return null;
|
|
9089
|
+
const mapForward = (pos) => transactions.reduce((p, transaction) => transaction.mapping.map(p), pos);
|
|
8937
9090
|
const tr = newState.tr;
|
|
8938
|
-
assignMissingIDs(newState.doc, tr);
|
|
8939
|
-
|
|
9091
|
+
assignMissingIDs(newState.doc, tr, incumbentPositions(oldState.doc, mapForward));
|
|
9092
|
+
if (!tr.docChanged) return null;
|
|
9093
|
+
const ridesAlongWithAnEdit = transactions.some(
|
|
9094
|
+
(transaction) => transaction.docChanged && transaction.getMeta("addToHistory") !== false
|
|
9095
|
+
);
|
|
9096
|
+
if (!ridesAlongWithAnEdit) tr.setMeta("addToHistory", false);
|
|
9097
|
+
return tr;
|
|
8940
9098
|
},
|
|
8941
9099
|
// Handle paste - filter duplicates
|
|
8942
9100
|
props: filterDuplicates ? {
|
|
@@ -9666,13 +9824,13 @@ var Highlight = Extension.create({
|
|
|
9666
9824
|
let hasHighlight = false;
|
|
9667
9825
|
if (empty) {
|
|
9668
9826
|
const marks = state.storedMarks ?? state.doc.resolve(from).marks();
|
|
9669
|
-
const
|
|
9670
|
-
hasHighlight = !!
|
|
9827
|
+
const mark2 = markType.isInSet(marks);
|
|
9828
|
+
hasHighlight = !!mark2?.attrs["backgroundColor"] || !!mark2?.attrs["backgroundColorToken"];
|
|
9671
9829
|
} else {
|
|
9672
9830
|
state.doc.nodesBetween(from, to, (node) => {
|
|
9673
9831
|
if (hasHighlight) return false;
|
|
9674
|
-
const
|
|
9675
|
-
if (
|
|
9832
|
+
const mark2 = markType.isInSet(node.marks);
|
|
9833
|
+
if (mark2?.attrs["backgroundColor"] || mark2?.attrs["backgroundColorToken"]) {
|
|
9676
9834
|
hasHighlight = true;
|
|
9677
9835
|
return false;
|
|
9678
9836
|
}
|
|
@@ -9719,7 +9877,8 @@ var Highlight = Extension.create({
|
|
|
9719
9877
|
const content = match[1];
|
|
9720
9878
|
if (!content) return null;
|
|
9721
9879
|
const { tr } = state;
|
|
9722
|
-
tr.
|
|
9880
|
+
const marks = tr.storedMarks ?? tr.doc.resolve(start).marksAcross(tr.doc.resolve(end));
|
|
9881
|
+
tr.replaceWith(start, end, state.schema.text(content, marks));
|
|
9723
9882
|
tr.addMark(
|
|
9724
9883
|
start,
|
|
9725
9884
|
start + content.length,
|
|
@@ -9905,14 +10064,14 @@ var FontSize = Extension.create({
|
|
|
9905
10064
|
addToolbarItems() {
|
|
9906
10065
|
if (this.options.fontSizes.length === 0) return [];
|
|
9907
10066
|
const sizes = this.options.fontSizes;
|
|
9908
|
-
const items = sizes.map((
|
|
10067
|
+
const items = sizes.map((size2, i) => ({
|
|
9909
10068
|
type: "button",
|
|
9910
|
-
name: `fontSize-${
|
|
10069
|
+
name: `fontSize-${size2}`,
|
|
9911
10070
|
command: "setFontSize",
|
|
9912
|
-
commandArgs: [
|
|
9913
|
-
isActive: { name: "textStyle", attributes: { fontSize:
|
|
10071
|
+
commandArgs: [size2],
|
|
10072
|
+
isActive: { name: "textStyle", attributes: { fontSize: size2 } },
|
|
9914
10073
|
icon: "textSize",
|
|
9915
|
-
label:
|
|
10074
|
+
label: size2,
|
|
9916
10075
|
priority: 200 - i
|
|
9917
10076
|
}));
|
|
9918
10077
|
if (this.options.showReset) {
|
|
@@ -10015,6 +10174,153 @@ var ClearFormatting = Extension.create({
|
|
|
10015
10174
|
];
|
|
10016
10175
|
}
|
|
10017
10176
|
});
|
|
10177
|
+
|
|
10178
|
+
// src/extensions/Print.ts
|
|
10179
|
+
var ROOT_CLASS = "dm-print-root";
|
|
10180
|
+
var ANCESTOR_CLASS = "dm-print-ancestor";
|
|
10181
|
+
var PRINTING_CLASS = "dm-printing";
|
|
10182
|
+
var marked = /* @__PURE__ */ new Set();
|
|
10183
|
+
var printing = false;
|
|
10184
|
+
var Print = Extension.create({
|
|
10185
|
+
name: "print",
|
|
10186
|
+
addOptions() {
|
|
10187
|
+
return {
|
|
10188
|
+
toolbar: true,
|
|
10189
|
+
root: null,
|
|
10190
|
+
isolateNativePrint: false
|
|
10191
|
+
};
|
|
10192
|
+
},
|
|
10193
|
+
addStorage() {
|
|
10194
|
+
return { cleanup: null };
|
|
10195
|
+
},
|
|
10196
|
+
addCommands() {
|
|
10197
|
+
return {
|
|
10198
|
+
printDocument: () => ({ dispatch }) => {
|
|
10199
|
+
if (!dispatch) return true;
|
|
10200
|
+
const editor = this.editor;
|
|
10201
|
+
if (!editor || typeof window === "undefined") return false;
|
|
10202
|
+
const root = resolveRoot(editor, this.options.root);
|
|
10203
|
+
if (!root) return false;
|
|
10204
|
+
mark(root);
|
|
10205
|
+
try {
|
|
10206
|
+
emit(editor, "beforePrint", { root });
|
|
10207
|
+
window.print();
|
|
10208
|
+
} finally {
|
|
10209
|
+
unmark();
|
|
10210
|
+
emit(editor, "afterPrint", void 0);
|
|
10211
|
+
}
|
|
10212
|
+
return true;
|
|
10213
|
+
}
|
|
10214
|
+
};
|
|
10215
|
+
},
|
|
10216
|
+
addToolbarItems() {
|
|
10217
|
+
if (!this.options.toolbar) return [];
|
|
10218
|
+
return [
|
|
10219
|
+
{
|
|
10220
|
+
type: "button",
|
|
10221
|
+
name: "print",
|
|
10222
|
+
command: "printDocument",
|
|
10223
|
+
icon: "printer",
|
|
10224
|
+
label: "Print",
|
|
10225
|
+
shortcut: "Mod-P",
|
|
10226
|
+
group: "document",
|
|
10227
|
+
priority: 100,
|
|
10228
|
+
// Reading a document out to paper is not editing it, so the button
|
|
10229
|
+
// stays live in a read-only editor.
|
|
10230
|
+
allowReadOnly: true
|
|
10231
|
+
}
|
|
10232
|
+
];
|
|
10233
|
+
},
|
|
10234
|
+
addKeyboardShortcuts() {
|
|
10235
|
+
return {
|
|
10236
|
+
// Only bound while the caret is in the editor, which is exactly when
|
|
10237
|
+
// the reader means "print this document" rather than "print this
|
|
10238
|
+
// page". Everywhere else the browser's own Ctrl/Cmd+P is untouched.
|
|
10239
|
+
"Mod-p": () => this.editor?.commands.printDocument() ?? false
|
|
10240
|
+
};
|
|
10241
|
+
},
|
|
10242
|
+
onCreate() {
|
|
10243
|
+
if (!this.options.isolateNativePrint) return;
|
|
10244
|
+
if (typeof window === "undefined") return;
|
|
10245
|
+
const editor = this.editor;
|
|
10246
|
+
if (!editor) return;
|
|
10247
|
+
const resolve = this.options.root;
|
|
10248
|
+
const before = () => {
|
|
10249
|
+
if (printing) return;
|
|
10250
|
+
const root = resolveRoot(editor, resolve);
|
|
10251
|
+
if (!root) return;
|
|
10252
|
+
mark(root);
|
|
10253
|
+
emit(editor, "beforePrint", { root });
|
|
10254
|
+
};
|
|
10255
|
+
const after = () => {
|
|
10256
|
+
if (!printing) return;
|
|
10257
|
+
unmark();
|
|
10258
|
+
emit(editor, "afterPrint", void 0);
|
|
10259
|
+
};
|
|
10260
|
+
window.addEventListener("beforeprint", before);
|
|
10261
|
+
window.addEventListener("afterprint", after);
|
|
10262
|
+
let detachMedia = null;
|
|
10263
|
+
const onMediaChange = (event) => {
|
|
10264
|
+
if (event.matches) before();
|
|
10265
|
+
else after();
|
|
10266
|
+
};
|
|
10267
|
+
if (typeof window.matchMedia === "function") {
|
|
10268
|
+
const media = window.matchMedia("print");
|
|
10269
|
+
if (typeof media.addEventListener === "function") {
|
|
10270
|
+
media.addEventListener("change", onMediaChange);
|
|
10271
|
+
detachMedia = () => {
|
|
10272
|
+
media.removeEventListener("change", onMediaChange);
|
|
10273
|
+
};
|
|
10274
|
+
}
|
|
10275
|
+
}
|
|
10276
|
+
this.storage.cleanup = () => {
|
|
10277
|
+
window.removeEventListener("beforeprint", before);
|
|
10278
|
+
window.removeEventListener("afterprint", after);
|
|
10279
|
+
detachMedia?.();
|
|
10280
|
+
};
|
|
10281
|
+
},
|
|
10282
|
+
onDestroy() {
|
|
10283
|
+
this.storage.cleanup?.();
|
|
10284
|
+
this.storage.cleanup = null;
|
|
10285
|
+
unmark();
|
|
10286
|
+
}
|
|
10287
|
+
});
|
|
10288
|
+
function resolveRoot(editor, resolve) {
|
|
10289
|
+
if (resolve) return resolve(editor);
|
|
10290
|
+
const dom = editor.view.dom;
|
|
10291
|
+
return dom.closest(".dm-editor") ?? dom;
|
|
10292
|
+
}
|
|
10293
|
+
function mark(root) {
|
|
10294
|
+
root.classList.add(ROOT_CLASS);
|
|
10295
|
+
marked.add(root);
|
|
10296
|
+
let node = parentOf(root);
|
|
10297
|
+
while (node) {
|
|
10298
|
+
node.classList.add(ANCESTOR_CLASS);
|
|
10299
|
+
marked.add(node);
|
|
10300
|
+
node = parentOf(node);
|
|
10301
|
+
}
|
|
10302
|
+
document.body.classList.add(PRINTING_CLASS);
|
|
10303
|
+
printing = true;
|
|
10304
|
+
}
|
|
10305
|
+
function parentOf(node) {
|
|
10306
|
+
if (node.parentElement) return node.parentElement;
|
|
10307
|
+
if (typeof ShadowRoot === "undefined") return null;
|
|
10308
|
+
const root = node.getRootNode();
|
|
10309
|
+
return root instanceof ShadowRoot ? root.host : null;
|
|
10310
|
+
}
|
|
10311
|
+
function unmark() {
|
|
10312
|
+
printing = false;
|
|
10313
|
+
if (typeof document === "undefined") return;
|
|
10314
|
+
document.body.classList.remove(PRINTING_CLASS);
|
|
10315
|
+
for (const el of marked) {
|
|
10316
|
+
el.classList.remove(ROOT_CLASS, ANCESTOR_CLASS);
|
|
10317
|
+
}
|
|
10318
|
+
marked.clear();
|
|
10319
|
+
}
|
|
10320
|
+
function emit(editor, name, payload) {
|
|
10321
|
+
const bus = editor;
|
|
10322
|
+
bus.emit?.(name, payload);
|
|
10323
|
+
}
|
|
10018
10324
|
var linkPopoverPluginKey = new state.PluginKey("linkPopover");
|
|
10019
10325
|
function linkPopoverPlugin({ editor, markType, protocols }) {
|
|
10020
10326
|
const el = document.createElement("div");
|
|
@@ -10352,9 +10658,10 @@ function createBubbleMenuPlugin(options) {
|
|
|
10352
10658
|
const onDocumentMousedown = (e) => {
|
|
10353
10659
|
const target = e.target;
|
|
10354
10660
|
if (!target) return;
|
|
10661
|
+
if (!target.isConnected) return;
|
|
10355
10662
|
if (element.contains(target)) return;
|
|
10356
10663
|
if (editor.view.dom.contains(target)) return;
|
|
10357
|
-
if (target instanceof
|
|
10664
|
+
if (target instanceof Element && target.closest("[data-dm-editor-ui]")) return;
|
|
10358
10665
|
hideMenu();
|
|
10359
10666
|
suppressed = true;
|
|
10360
10667
|
};
|
|
@@ -10376,7 +10683,7 @@ function createBubbleMenuPlugin(options) {
|
|
|
10376
10683
|
if (from !== prevValue.from || to !== prevValue.to) {
|
|
10377
10684
|
suppressed = false;
|
|
10378
10685
|
}
|
|
10379
|
-
const visible = !suppressed && !selection.empty && shouldShow({
|
|
10686
|
+
const visible = !suppressed && !selection.empty && editor.isEditable && shouldShow({
|
|
10380
10687
|
editor,
|
|
10381
10688
|
view: editor.view,
|
|
10382
10689
|
state: newState,
|
|
@@ -10416,7 +10723,7 @@ function createBubbleMenuPlugin(options) {
|
|
|
10416
10723
|
if (mouseDown) return;
|
|
10417
10724
|
const { selection } = editor.view.state;
|
|
10418
10725
|
const { from, to } = selection;
|
|
10419
|
-
const show = !selection.empty && shouldShow({
|
|
10726
|
+
const show = !selection.empty && editor.isEditable && shouldShow({
|
|
10420
10727
|
editor,
|
|
10421
10728
|
view: editor.view,
|
|
10422
10729
|
state: editor.view.state,
|
|
@@ -10452,6 +10759,10 @@ function createBubbleMenuPlugin(options) {
|
|
|
10452
10759
|
return {
|
|
10453
10760
|
update: (view, prevState) => {
|
|
10454
10761
|
if (view.composing) return;
|
|
10762
|
+
if (!view.editable) {
|
|
10763
|
+
hideMenu();
|
|
10764
|
+
return;
|
|
10765
|
+
}
|
|
10455
10766
|
const state = pluginKey.getState(view.state);
|
|
10456
10767
|
const prevPluginState = pluginKey.getState(prevState);
|
|
10457
10768
|
if (state?.visible === prevPluginState?.visible && state?.from === prevPluginState?.from && state?.to === prevPluginState?.to && !(state?.visible && view.state.doc !== prevState.doc)) {
|
|
@@ -10584,7 +10895,7 @@ var StarterKit = Extension.create({
|
|
|
10584
10895
|
});
|
|
10585
10896
|
|
|
10586
10897
|
// src/index.ts
|
|
10587
|
-
var VERSION = "0.
|
|
10898
|
+
var VERSION = "0.15.0";
|
|
10588
10899
|
|
|
10589
10900
|
Object.defineProperty(exports, "PluginKey", {
|
|
10590
10901
|
enumerable: true,
|
|
@@ -10642,6 +10953,7 @@ exports.NotionColorPicker = NotionColorPicker;
|
|
|
10642
10953
|
exports.OrderedList = OrderedList;
|
|
10643
10954
|
exports.Paragraph = Paragraph;
|
|
10644
10955
|
exports.Placeholder = Placeholder;
|
|
10956
|
+
exports.Print = Print;
|
|
10645
10957
|
exports.Selection = Selection5;
|
|
10646
10958
|
exports.SelectionDecoration = SelectionDecoration;
|
|
10647
10959
|
exports.StarterKit = StarterKit;
|