@domternal/core 0.8.0 → 0.9.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 +288 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +122 -14
- package/dist/index.d.ts +122 -14
- package/dist/index.js +285 -21
- package/dist/index.js.map +1 -1
- package/package.json +14 -12
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PluginKey, Plugin, TextSelection, Selection, 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
6
|
import { splitBlock, chainCommands, newlineInCode, createParagraphNear, liftEmptyBlock, baseKeymap, selectNodeBackward as selectNodeBackward$1 } from '@domternal/pm/commands';
|
|
7
7
|
import { InputRule } from '@domternal/pm/inputrules';
|
|
8
|
-
import { canJoin, findWrapping, liftTarget } from '@domternal/pm/transform';
|
|
8
|
+
import { canJoin, canSplit, findWrapping, 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';
|
|
@@ -2278,7 +2278,7 @@ function joinListForwards(tr, listType) {
|
|
|
2278
2278
|
}
|
|
2279
2279
|
}
|
|
2280
2280
|
}
|
|
2281
|
-
var toggleList = (listNodeName, listItemNodeName, attributes) => ({ state, tr, dispatch }) => {
|
|
2281
|
+
var toggleList = (listNodeName, listItemNodeName, attributes, options) => ({ state, tr, dispatch }) => {
|
|
2282
2282
|
const listType = state.schema.nodes[listNodeName];
|
|
2283
2283
|
const listItemType = state.schema.nodes[listItemNodeName];
|
|
2284
2284
|
if (!listType || !listItemType) {
|
|
@@ -2410,6 +2410,17 @@ var toggleList = (listNodeName, listItemNodeName, attributes) => ({ state, tr, d
|
|
|
2410
2410
|
const contentBlocks = collectListContext(tr.doc, from, to);
|
|
2411
2411
|
const allInTargetList = contentBlocks.length > 0 && contentBlocks.every((b) => b.inTargetList);
|
|
2412
2412
|
const allInSomeList = contentBlocks.length > 0 && contentBlocks.every((b) => b.inSomeList);
|
|
2413
|
+
if (options?.perItem && from === to && allInSomeList && !allInTargetList) {
|
|
2414
|
+
if (!dispatch) return true;
|
|
2415
|
+
if (liftCurrentListItem(state, tr)) {
|
|
2416
|
+
const blockRange = tr.selection.$from.blockRange();
|
|
2417
|
+
if (blockRange) wrapRangeInList(tr, blockRange, listType, attributes);
|
|
2418
|
+
joinListBackwards(tr, listType);
|
|
2419
|
+
joinListForwards(tr, listType);
|
|
2420
|
+
dispatch(tr.scrollIntoView());
|
|
2421
|
+
return true;
|
|
2422
|
+
}
|
|
2423
|
+
}
|
|
2413
2424
|
if (allInTargetList) {
|
|
2414
2425
|
const first = contentBlocks[0];
|
|
2415
2426
|
const last = contentBlocks[contentBlocks.length - 1];
|
|
@@ -3496,7 +3507,7 @@ var Editor = class extends EventEmitter {
|
|
|
3496
3507
|
* Checks if the editor is editable
|
|
3497
3508
|
*/
|
|
3498
3509
|
get isEditable() {
|
|
3499
|
-
return this.view.editable;
|
|
3510
|
+
return this.view ? this.view.editable : this.options.editable ?? true;
|
|
3500
3511
|
}
|
|
3501
3512
|
/**
|
|
3502
3513
|
* Checks if the editor content is empty
|
|
@@ -3993,10 +4004,11 @@ var Editor = class extends EventEmitter {
|
|
|
3993
4004
|
function positionFloating(reference, floating, options) {
|
|
3994
4005
|
const placementOpt = options?.placement ?? "bottom";
|
|
3995
4006
|
const paddingOpt = options?.padding ?? 10;
|
|
4007
|
+
const overflowOpts = options?.boundary ? { padding: paddingOpt, boundary: options.boundary } : { padding: paddingOpt };
|
|
3996
4008
|
const middleware = [
|
|
3997
4009
|
offset(options?.offsetValue ?? 4),
|
|
3998
|
-
flip(
|
|
3999
|
-
shift(
|
|
4010
|
+
flip(overflowOpts),
|
|
4011
|
+
shift(overflowOpts),
|
|
4000
4012
|
hide()
|
|
4001
4013
|
];
|
|
4002
4014
|
const update = () => {
|
|
@@ -4027,10 +4039,11 @@ function positionFloating(reference, floating, options) {
|
|
|
4027
4039
|
function positionFloatingOnce(reference, floating, options) {
|
|
4028
4040
|
const placementOpt = options?.placement ?? "bottom";
|
|
4029
4041
|
const paddingOpt = options?.padding ?? 10;
|
|
4042
|
+
const overflowOpts = options?.boundary ? { padding: paddingOpt, boundary: options.boundary } : { padding: paddingOpt };
|
|
4030
4043
|
const middleware = [
|
|
4031
4044
|
offset(options?.offsetValue ?? 4),
|
|
4032
|
-
flip(
|
|
4033
|
-
shift(
|
|
4045
|
+
flip(overflowOpts),
|
|
4046
|
+
shift(overflowOpts)
|
|
4034
4047
|
];
|
|
4035
4048
|
const update = () => {
|
|
4036
4049
|
void computePosition(
|
|
@@ -5122,6 +5135,226 @@ var FloatingMenuController = class _FloatingMenuController {
|
|
|
5122
5135
|
if (changed) this.onChange();
|
|
5123
5136
|
}
|
|
5124
5137
|
};
|
|
5138
|
+
var floatingMenuPluginKey = new PluginKey("floatingMenu");
|
|
5139
|
+
function defaultFloatingMenuShouldShow({
|
|
5140
|
+
editor,
|
|
5141
|
+
state
|
|
5142
|
+
}) {
|
|
5143
|
+
if (!editor.isEditable) return false;
|
|
5144
|
+
const { selection } = state;
|
|
5145
|
+
const { $from, empty } = selection;
|
|
5146
|
+
if (!empty) return false;
|
|
5147
|
+
if ($from.parent.type.name !== "paragraph") return false;
|
|
5148
|
+
if ($from.parent.content.size !== 0) return false;
|
|
5149
|
+
if ($from.parentOffset !== 0) return false;
|
|
5150
|
+
return true;
|
|
5151
|
+
}
|
|
5152
|
+
var DEFAULT_ENTER_MENU_SHORTCUTS = ["Alt-F10", "Mod-/"];
|
|
5153
|
+
var FLOATING_MENU_META = "dm:floatingMenuTrigger";
|
|
5154
|
+
function showFloatingMenu(view) {
|
|
5155
|
+
view.dispatch(view.state.tr.setMeta(FLOATING_MENU_META, "show"));
|
|
5156
|
+
}
|
|
5157
|
+
function hideFloatingMenu(view) {
|
|
5158
|
+
view.dispatch(view.state.tr.setMeta(FLOATING_MENU_META, "hide"));
|
|
5159
|
+
}
|
|
5160
|
+
var IS_MAC = typeof navigator !== "undefined" && /Mac|iPhone|iPad|iPod/i.test(navigator.userAgent);
|
|
5161
|
+
function matchShortcut(event, shortcut) {
|
|
5162
|
+
const parts = shortcut.split("-");
|
|
5163
|
+
let keyPart = parts.pop();
|
|
5164
|
+
if (!keyPart) return false;
|
|
5165
|
+
if (keyPart === "Space") keyPart = " ";
|
|
5166
|
+
let needCtrl = false;
|
|
5167
|
+
let needMeta = false;
|
|
5168
|
+
let needAlt = false;
|
|
5169
|
+
let needShift = false;
|
|
5170
|
+
for (const mod of parts) {
|
|
5171
|
+
switch (mod) {
|
|
5172
|
+
case "Mod":
|
|
5173
|
+
case "mod":
|
|
5174
|
+
if (IS_MAC) needMeta = true;
|
|
5175
|
+
else needCtrl = true;
|
|
5176
|
+
break;
|
|
5177
|
+
case "Cmd":
|
|
5178
|
+
case "cmd":
|
|
5179
|
+
case "Meta":
|
|
5180
|
+
case "meta":
|
|
5181
|
+
case "m":
|
|
5182
|
+
needMeta = true;
|
|
5183
|
+
break;
|
|
5184
|
+
case "Ctrl":
|
|
5185
|
+
case "ctrl":
|
|
5186
|
+
case "Control":
|
|
5187
|
+
case "control":
|
|
5188
|
+
case "c":
|
|
5189
|
+
needCtrl = true;
|
|
5190
|
+
break;
|
|
5191
|
+
case "Alt":
|
|
5192
|
+
case "alt":
|
|
5193
|
+
case "a":
|
|
5194
|
+
needAlt = true;
|
|
5195
|
+
break;
|
|
5196
|
+
case "Shift":
|
|
5197
|
+
case "shift":
|
|
5198
|
+
case "s":
|
|
5199
|
+
needShift = true;
|
|
5200
|
+
break;
|
|
5201
|
+
default:
|
|
5202
|
+
return false;
|
|
5203
|
+
}
|
|
5204
|
+
}
|
|
5205
|
+
if (event.altKey !== needAlt) return false;
|
|
5206
|
+
if (event.ctrlKey !== needCtrl) return false;
|
|
5207
|
+
if (event.metaKey !== needMeta) return false;
|
|
5208
|
+
if (keyPart.length > 1 && event.shiftKey !== needShift) return false;
|
|
5209
|
+
return event.key === keyPart || event.key.toLowerCase() === keyPart.toLowerCase();
|
|
5210
|
+
}
|
|
5211
|
+
function createFloatingMenuPlugin(options) {
|
|
5212
|
+
const {
|
|
5213
|
+
pluginKey,
|
|
5214
|
+
editor,
|
|
5215
|
+
element,
|
|
5216
|
+
shouldShow = defaultFloatingMenuShouldShow,
|
|
5217
|
+
offset: offset2 = 0,
|
|
5218
|
+
keymap: keymap4,
|
|
5219
|
+
requireExplicitTrigger = false
|
|
5220
|
+
} = options;
|
|
5221
|
+
const enterShortcuts = keymap4?.enterMenu ?? DEFAULT_ENTER_MENU_SHORTCUTS;
|
|
5222
|
+
if (!element.getAttribute("role")) {
|
|
5223
|
+
element.setAttribute("role", "menu");
|
|
5224
|
+
element.setAttribute("aria-label", "Insert block");
|
|
5225
|
+
}
|
|
5226
|
+
let cleanupFloating = null;
|
|
5227
|
+
let editorEl = null;
|
|
5228
|
+
let clickOutsideHandler = null;
|
|
5229
|
+
let dismissOverlayHandler = null;
|
|
5230
|
+
const isVisible = () => element.hasAttribute("data-show");
|
|
5231
|
+
const updatePosition = (view) => {
|
|
5232
|
+
const { selection } = view.state;
|
|
5233
|
+
const { $from } = selection;
|
|
5234
|
+
const depth = $from.depth;
|
|
5235
|
+
const startPos = $from.start(depth);
|
|
5236
|
+
const domNode = view.nodeDOM(startPos - 1);
|
|
5237
|
+
if (domNode instanceof HTMLElement) {
|
|
5238
|
+
cleanupFloating?.();
|
|
5239
|
+
cleanupFloating = positionFloatingOnce(domNode, element, {
|
|
5240
|
+
placement: "bottom-start",
|
|
5241
|
+
offsetValue: offset2
|
|
5242
|
+
});
|
|
5243
|
+
element.setAttribute("data-show", "");
|
|
5244
|
+
}
|
|
5245
|
+
};
|
|
5246
|
+
const hideMenu = () => {
|
|
5247
|
+
cleanupFloating?.();
|
|
5248
|
+
cleanupFloating = null;
|
|
5249
|
+
element.removeAttribute("data-show");
|
|
5250
|
+
};
|
|
5251
|
+
const clearTriggeredFlag = (view) => {
|
|
5252
|
+
if (!requireExplicitTrigger) return;
|
|
5253
|
+
const triggered = pluginKey.getState(view.state)?.triggered ?? false;
|
|
5254
|
+
if (triggered) view.dispatch(view.state.tr.setMeta(FLOATING_MENU_META, "hide"));
|
|
5255
|
+
};
|
|
5256
|
+
const focusFirstItem = () => {
|
|
5257
|
+
const first = element.querySelector('[data-floating-menu-item]:not([aria-disabled="true"])') ?? element.querySelector('button, [tabindex]:not([tabindex="-1"])');
|
|
5258
|
+
if (!first) return false;
|
|
5259
|
+
first.focus();
|
|
5260
|
+
return true;
|
|
5261
|
+
};
|
|
5262
|
+
hideMenu();
|
|
5263
|
+
const isVisibleNow = (view) => {
|
|
5264
|
+
const wantsShow = shouldShow({ editor, view, state: view.state });
|
|
5265
|
+
if (!requireExplicitTrigger) return wantsShow;
|
|
5266
|
+
const triggered = pluginKey.getState(view.state)?.triggered ?? false;
|
|
5267
|
+
return triggered && wantsShow;
|
|
5268
|
+
};
|
|
5269
|
+
return new Plugin({
|
|
5270
|
+
key: pluginKey,
|
|
5271
|
+
state: {
|
|
5272
|
+
init: () => ({ triggered: false }),
|
|
5273
|
+
apply: (tr, prev) => {
|
|
5274
|
+
const meta = tr.getMeta(FLOATING_MENU_META);
|
|
5275
|
+
if (meta === "show") return { triggered: true };
|
|
5276
|
+
if (meta === "hide") return { triggered: false };
|
|
5277
|
+
return prev;
|
|
5278
|
+
}
|
|
5279
|
+
},
|
|
5280
|
+
props: {
|
|
5281
|
+
// Keyboard entry. handleKeyDown fires before browser defaults; we only
|
|
5282
|
+
// act while the menu is visible.
|
|
5283
|
+
handleKeyDown(_view, event) {
|
|
5284
|
+
if (!isVisible()) return false;
|
|
5285
|
+
for (const shortcut of enterShortcuts) {
|
|
5286
|
+
if (matchShortcut(event, shortcut)) {
|
|
5287
|
+
if (focusFirstItem()) {
|
|
5288
|
+
event.preventDefault();
|
|
5289
|
+
return true;
|
|
5290
|
+
}
|
|
5291
|
+
return false;
|
|
5292
|
+
}
|
|
5293
|
+
}
|
|
5294
|
+
return false;
|
|
5295
|
+
}
|
|
5296
|
+
},
|
|
5297
|
+
view: (editorView) => {
|
|
5298
|
+
editorEl = editorView.dom.closest(".dm-editor");
|
|
5299
|
+
if (editorEl && element.parentElement !== editorEl) {
|
|
5300
|
+
editorEl.appendChild(element);
|
|
5301
|
+
}
|
|
5302
|
+
const dismiss = () => {
|
|
5303
|
+
hideMenu();
|
|
5304
|
+
clearTriggeredFlag(editor.view);
|
|
5305
|
+
};
|
|
5306
|
+
const onFocus = () => {
|
|
5307
|
+
if (isVisibleNow(editor.view)) updatePosition(editor.view);
|
|
5308
|
+
else dismiss();
|
|
5309
|
+
};
|
|
5310
|
+
const onBlur = ({ event }) => {
|
|
5311
|
+
const related = event.relatedTarget;
|
|
5312
|
+
if (related instanceof Node && element.contains(related)) return;
|
|
5313
|
+
dismiss();
|
|
5314
|
+
};
|
|
5315
|
+
clickOutsideHandler = (e) => {
|
|
5316
|
+
if (!isVisible()) return;
|
|
5317
|
+
const target = e.target;
|
|
5318
|
+
if (!(target instanceof Node)) return;
|
|
5319
|
+
if (element.contains(target)) return;
|
|
5320
|
+
if (editor.view.dom.contains(target)) return;
|
|
5321
|
+
dismiss();
|
|
5322
|
+
};
|
|
5323
|
+
document.addEventListener("mousedown", clickOutsideHandler, true);
|
|
5324
|
+
if (editorEl) {
|
|
5325
|
+
dismissOverlayHandler = () => {
|
|
5326
|
+
dismiss();
|
|
5327
|
+
};
|
|
5328
|
+
editorEl.addEventListener("dm:dismiss-overlays", dismissOverlayHandler);
|
|
5329
|
+
}
|
|
5330
|
+
editor.on("focus", onFocus);
|
|
5331
|
+
editor.on("blur", onBlur);
|
|
5332
|
+
return {
|
|
5333
|
+
update: (view) => {
|
|
5334
|
+
if (isVisibleNow(view)) updatePosition(view);
|
|
5335
|
+
else {
|
|
5336
|
+
hideMenu();
|
|
5337
|
+
clearTriggeredFlag(view);
|
|
5338
|
+
}
|
|
5339
|
+
},
|
|
5340
|
+
destroy: () => {
|
|
5341
|
+
hideMenu();
|
|
5342
|
+
editor.off("focus", onFocus);
|
|
5343
|
+
editor.off("blur", onBlur);
|
|
5344
|
+
if (clickOutsideHandler) {
|
|
5345
|
+
document.removeEventListener("mousedown", clickOutsideHandler, true);
|
|
5346
|
+
clickOutsideHandler = null;
|
|
5347
|
+
}
|
|
5348
|
+
if (dismissOverlayHandler && editorEl) {
|
|
5349
|
+
editorEl.removeEventListener("dm:dismiss-overlays", dismissOverlayHandler);
|
|
5350
|
+
dismissOverlayHandler = null;
|
|
5351
|
+
}
|
|
5352
|
+
editorEl = null;
|
|
5353
|
+
}
|
|
5354
|
+
};
|
|
5355
|
+
}
|
|
5356
|
+
});
|
|
5357
|
+
}
|
|
5125
5358
|
|
|
5126
5359
|
// src/icons/phosphor.ts
|
|
5127
5360
|
var defaultIcons = {
|
|
@@ -5892,6 +6125,11 @@ var BulletList = Node2.create({
|
|
|
5892
6125
|
return {
|
|
5893
6126
|
toggleBulletList: () => ({ commands }) => {
|
|
5894
6127
|
return commands.toggleList(name, options.itemTypeName);
|
|
6128
|
+
},
|
|
6129
|
+
// Notion "turn into" (slash menu / block menu): convert only the cursor's
|
|
6130
|
+
// item and split the run, instead of retyping the whole list.
|
|
6131
|
+
turnIntoBulletList: () => ({ commands }) => {
|
|
6132
|
+
return commands.toggleList(name, options.itemTypeName, void 0, { perItem: true });
|
|
5895
6133
|
}
|
|
5896
6134
|
};
|
|
5897
6135
|
},
|
|
@@ -5921,7 +6159,7 @@ var BulletList = Node2.create({
|
|
|
5921
6159
|
priority: 200,
|
|
5922
6160
|
keywords: ["bullet", "list", "unordered", "ul"],
|
|
5923
6161
|
shortcut: "- ",
|
|
5924
|
-
command: "
|
|
6162
|
+
command: "turnIntoBulletList",
|
|
5925
6163
|
// Don't offer "Bulleted list" while cursor is already inside one,
|
|
5926
6164
|
// otherwise picking it lifts the user out of the list.
|
|
5927
6165
|
hideWhenInside: ["bulletList"]
|
|
@@ -5995,6 +6233,11 @@ var OrderedList = Node2.create({
|
|
|
5995
6233
|
return {
|
|
5996
6234
|
toggleOrderedList: () => ({ commands }) => {
|
|
5997
6235
|
return commands.toggleList(name, options.itemTypeName);
|
|
6236
|
+
},
|
|
6237
|
+
// Notion "turn into" (slash menu / block menu): convert only the cursor's
|
|
6238
|
+
// item and split the run, instead of retyping the whole list.
|
|
6239
|
+
turnIntoOrderedList: () => ({ commands }) => {
|
|
6240
|
+
return commands.toggleList(name, options.itemTypeName, void 0, { perItem: true });
|
|
5998
6241
|
}
|
|
5999
6242
|
};
|
|
6000
6243
|
},
|
|
@@ -6024,7 +6267,7 @@ var OrderedList = Node2.create({
|
|
|
6024
6267
|
priority: 190,
|
|
6025
6268
|
keywords: ["ordered", "numbered", "list", "ol", "1."],
|
|
6026
6269
|
shortcut: "1. ",
|
|
6027
|
-
command: "
|
|
6270
|
+
command: "turnIntoOrderedList",
|
|
6028
6271
|
hideWhenInside: ["orderedList"]
|
|
6029
6272
|
}
|
|
6030
6273
|
];
|
|
@@ -6413,6 +6656,17 @@ var TaskItem = Node2.create({
|
|
|
6413
6656
|
if (splitBlock(state, view.dispatch)) return true;
|
|
6414
6657
|
}
|
|
6415
6658
|
}
|
|
6659
|
+
if (!ctx?.isInChildrenZone && $from.node(-1).attrs["checked"] && $from.parentOffset > 0 && $from.parentOffset < $from.parent.content.size) {
|
|
6660
|
+
const tr = state.tr;
|
|
6661
|
+
const types = [
|
|
6662
|
+
{ type: this.nodeType, attrs: { ...$from.node(-1).attrs, checked: false } },
|
|
6663
|
+
{ type: $from.parent.type }
|
|
6664
|
+
];
|
|
6665
|
+
if (canSplit(tr.doc, $from.pos, 2, types)) {
|
|
6666
|
+
view.dispatch(tr.split($from.pos, 2, types).scrollIntoView());
|
|
6667
|
+
return true;
|
|
6668
|
+
}
|
|
6669
|
+
}
|
|
6416
6670
|
if (splitListItem(this.nodeType, { checked: false })(state, view.dispatch)) return true;
|
|
6417
6671
|
if ($from.parent.content.size === 0) {
|
|
6418
6672
|
const listItemType = state.schema.nodes["listItem"];
|
|
@@ -6529,6 +6783,11 @@ var TaskList = Node2.create({
|
|
|
6529
6783
|
return {
|
|
6530
6784
|
toggleTaskList: () => ({ commands }) => {
|
|
6531
6785
|
return commands.toggleList(name, options.itemTypeName);
|
|
6786
|
+
},
|
|
6787
|
+
// Notion "turn into" (slash menu / block menu): convert only the cursor's
|
|
6788
|
+
// item and split the run, instead of retyping the whole list.
|
|
6789
|
+
turnIntoTaskList: () => ({ commands }) => {
|
|
6790
|
+
return commands.toggleList(name, options.itemTypeName, void 0, { perItem: true });
|
|
6532
6791
|
}
|
|
6533
6792
|
};
|
|
6534
6793
|
},
|
|
@@ -6566,7 +6825,7 @@ var TaskList = Node2.create({
|
|
|
6566
6825
|
priority: 180,
|
|
6567
6826
|
keywords: ["todo", "task", "checkbox", "check"],
|
|
6568
6827
|
shortcut: "[ ] ",
|
|
6569
|
-
command: "
|
|
6828
|
+
command: "turnIntoTaskList",
|
|
6570
6829
|
hideWhenInside: ["taskList"]
|
|
6571
6830
|
}
|
|
6572
6831
|
];
|
|
@@ -7732,9 +7991,8 @@ var Placeholder = Extension.create({
|
|
|
7732
7991
|
props: {
|
|
7733
7992
|
decorations: ({ doc, selection }) => {
|
|
7734
7993
|
const editor = this.editor;
|
|
7735
|
-
if (!editor
|
|
7736
|
-
|
|
7737
|
-
if (!isEditable && this.options.showOnlyWhenEditable) {
|
|
7994
|
+
if (!editor) return DecorationSet.empty;
|
|
7995
|
+
if (!editor.isEditable && this.options.showOnlyWhenEditable) {
|
|
7738
7996
|
return DecorationSet.empty;
|
|
7739
7997
|
}
|
|
7740
7998
|
const isDocEmpty = doc.childCount === 1 && doc.firstChild?.isTextblock && doc.firstChild.content.size === 0;
|
|
@@ -7842,7 +8100,7 @@ function outdentBlockFromListItem(state, dispatch) {
|
|
|
7842
8100
|
if (wrapperDepth < 0) return false;
|
|
7843
8101
|
const liIndexInWrapper = $from.index(wrapperDepth);
|
|
7844
8102
|
const wrapper = $from.node(wrapperDepth);
|
|
7845
|
-
|
|
8103
|
+
const isLastItem = liIndexInWrapper === wrapper.childCount - 1;
|
|
7846
8104
|
if (wrapperDepth - 1 < 0) return false;
|
|
7847
8105
|
const wrapperParent = $from.node(wrapperDepth - 1);
|
|
7848
8106
|
const wrapperIndexInParent = $from.index(wrapperDepth - 1);
|
|
@@ -7857,13 +8115,19 @@ function outdentBlockFromListItem(state, dispatch) {
|
|
|
7857
8115
|
if (!dispatch) return true;
|
|
7858
8116
|
const blockStart = $from.before(blockDepth);
|
|
7859
8117
|
const blockEnd = $from.after(blockDepth);
|
|
7860
|
-
const wrapperEnd = $from.after(wrapperDepth);
|
|
7861
|
-
const tr = state.tr;
|
|
7862
8118
|
const blockSize = blockEnd - blockStart;
|
|
8119
|
+
const tr = state.tr;
|
|
7863
8120
|
tr.delete(blockStart, blockEnd);
|
|
7864
|
-
|
|
7865
|
-
|
|
7866
|
-
|
|
8121
|
+
if (isLastItem) {
|
|
8122
|
+
const insertAt = $from.after(wrapperDepth) - blockSize;
|
|
8123
|
+
tr.insert(insertAt, blockNode);
|
|
8124
|
+
tr.setSelection(Selection.near(tr.doc.resolve(insertAt + 1)));
|
|
8125
|
+
} else {
|
|
8126
|
+
const splitPos = $from.after(listItemDepth) - blockSize;
|
|
8127
|
+
tr.split(splitPos, 1);
|
|
8128
|
+
tr.insert(splitPos + 1, blockNode);
|
|
8129
|
+
tr.setSelection(Selection.near(tr.doc.resolve(splitPos + 2)));
|
|
8130
|
+
}
|
|
7867
8131
|
dispatch(tr.scrollIntoView());
|
|
7868
8132
|
return true;
|
|
7869
8133
|
}
|
|
@@ -10099,6 +10363,6 @@ var StarterKit = Extension.create({
|
|
|
10099
10363
|
// src/index.ts
|
|
10100
10364
|
var VERSION = "0.1.0";
|
|
10101
10365
|
|
|
10102
|
-
export { BaseKeymap, BlockColor, Blockquote, Bold, BubbleMenu, BulletList, CanChecker, ChainBuilder, CharacterCount, ClearFormatting, Code, CodeBlock, CommandManager, DEFAULT_BLOCK_COLORS, DEFAULT_BLOCK_COLOR_TYPES, DEFAULT_HIGHLIGHT_COLORS, DEFAULT_NOTION_COLOR_PALETTE, DEFAULT_TEXT_COLORS, Document, Dropcursor, Editor, EventEmitter, Extension, ExtensionManager, FLOATING_MENU_NO_FOCUS, FloatingMenuController, Focus, FontFamily, FontSize, Gapcursor, HardBreak, Heading, Highlight, History, HorizontalRule, InvisibleChars, Italic, LIST_ITEM_TYPE_NAMES, LineHeight, Link, LinkPopover, ListIndent, ListItem, ListKeymap, Mark, Node2 as Node, NotionColorPicker, OrderedList, Paragraph, Placeholder, Selection4 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, copyThemeClass, createAccumulatingDispatch, createBubbleMenuPlugin, createCanChecker, createChainBuilder, createDocument, defaultBlockAt, defaultBubbleContexts, defaultIcons, deleteSelection, findChildren, findListItemAncestorDepth, findParentNode, focus, focusPluginKey, generateHTML, generateJSON, generateText, getListItemCursorContext, getMarkRange, groupFloatingMenuItems, indentBlockAsListChild, inlineStyles, insertAsListItemChild, insertChildrenZoneSibling, insertContent, insertText, invisibleCharsPluginKey, isDocumentEmpty, isInListItemLabel, isInsideListItem, isNodeEmpty, isValidUrl, lift, liftCurrentListItem, liftEmptyChildrenZoneParagraph, linkClickPlugin, linkClickPluginKey, linkExitPlugin, linkExitPluginKey, linkPastePlugin, linkPastePluginKey, markInputRule, markInputRulePatterns, nodeInputRule, outdentBlockFromListItem, placeholderPluginKey, positionFloating, positionFloatingOnce, resetAttributes, selectAll, selectNodeBackward, selectionDecorationPluginKey, setBlockType, setContent, setMark, splitListForInsert, stripInlineColorConflicts, textInputRule, textblockTypeInputRule, toggleBlockType, toggleList, toggleMark, toggleWrap, uniqueIDPluginKey, unsetAllMarks, unsetMark, updateAttributes, wrapIn, wrappingInputRule, writeToClipboard };
|
|
10366
|
+
export { BaseKeymap, BlockColor, Blockquote, Bold, BubbleMenu, BulletList, CanChecker, ChainBuilder, CharacterCount, ClearFormatting, Code, CodeBlock, CommandManager, DEFAULT_BLOCK_COLORS, DEFAULT_BLOCK_COLOR_TYPES, DEFAULT_HIGHLIGHT_COLORS, DEFAULT_NOTION_COLOR_PALETTE, DEFAULT_TEXT_COLORS, Document, Dropcursor, Editor, EventEmitter, Extension, ExtensionManager, FLOATING_MENU_META, FLOATING_MENU_NO_FOCUS, FloatingMenuController, Focus, FontFamily, FontSize, Gapcursor, HardBreak, Heading, Highlight, History, HorizontalRule, InvisibleChars, Italic, LIST_ITEM_TYPE_NAMES, LineHeight, Link, LinkPopover, ListIndent, ListItem, ListKeymap, Mark, Node2 as Node, NotionColorPicker, OrderedList, Paragraph, Placeholder, Selection4 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, copyThemeClass, createAccumulatingDispatch, createBubbleMenuPlugin, createCanChecker, createChainBuilder, createDocument, createFloatingMenuPlugin, defaultBlockAt, defaultBubbleContexts, defaultFloatingMenuShouldShow, defaultIcons, deleteSelection, findChildren, findListItemAncestorDepth, findParentNode, floatingMenuPluginKey, focus, focusPluginKey, generateHTML, generateJSON, generateText, getListItemCursorContext, getMarkRange, groupFloatingMenuItems, hideFloatingMenu, indentBlockAsListChild, inlineStyles, insertAsListItemChild, insertChildrenZoneSibling, insertContent, insertText, invisibleCharsPluginKey, isDocumentEmpty, isInListItemLabel, isInsideListItem, isNodeEmpty, isValidUrl, lift, liftCurrentListItem, liftEmptyChildrenZoneParagraph, linkClickPlugin, linkClickPluginKey, linkExitPlugin, linkExitPluginKey, linkPastePlugin, linkPastePluginKey, markInputRule, markInputRulePatterns, nodeInputRule, outdentBlockFromListItem, placeholderPluginKey, positionFloating, positionFloatingOnce, resetAttributes, selectAll, selectNodeBackward, selectionDecorationPluginKey, setBlockType, setContent, setMark, showFloatingMenu, splitListForInsert, stripInlineColorConflicts, textInputRule, textblockTypeInputRule, toggleBlockType, toggleList, toggleMark, toggleWrap, uniqueIDPluginKey, unsetAllMarks, unsetMark, updateAttributes, wrapIn, wrappingInputRule, writeToClipboard };
|
|
10103
10367
|
//# sourceMappingURL=index.js.map
|
|
10104
10368
|
//# sourceMappingURL=index.js.map
|