@threadlabs/looma 0.26.14 → 0.26.15
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.
|
@@ -3,7 +3,7 @@ import { Extension, Mark, Node as Node$1, callOrReturn, canInsertNode, combineTr
|
|
|
3
3
|
import { NodeSelection, Plugin, PluginKey, Selection, TextSelection } from "@tiptap/pm/state";
|
|
4
4
|
import { Decoration, DecorationSet } from "@tiptap/pm/view";
|
|
5
5
|
import { DOMParser, DOMSerializer, Fragment, Node as Node$2, Slice } from "@tiptap/pm/model";
|
|
6
|
-
import { history, redo, undo } from "@tiptap/pm/history";
|
|
6
|
+
import { closeHistory, history, redo, undo } from "@tiptap/pm/history";
|
|
7
7
|
import { dropCursor } from "@tiptap/pm/dropcursor";
|
|
8
8
|
import { gapCursor } from "@tiptap/pm/gapcursor";
|
|
9
9
|
import { createLowlight } from "lowlight";
|
|
@@ -662,6 +662,50 @@ var LoomaTableOfContents = Node$1.create({
|
|
|
662
662
|
}
|
|
663
663
|
});
|
|
664
664
|
//#endregion
|
|
665
|
+
//#region src/editor/extensions/input-rule-history.ts
|
|
666
|
+
/**
|
|
667
|
+
* Keep the literal trigger in typing history before converting it. Tiptap's
|
|
668
|
+
* usual input rule consumes the final character, so simply closing history
|
|
669
|
+
* would restore an incomplete Markdown delimiter on Undo.
|
|
670
|
+
* @invariant Conversion and subsequent typing are separate history events.
|
|
671
|
+
* @lifecycle Tiptap clears its undoable input rule on typing or caret movement.
|
|
672
|
+
*/
|
|
673
|
+
var LoomaInputRuleHistory = Extension.create({
|
|
674
|
+
name: "loomaInputRuleHistory",
|
|
675
|
+
priority: 50,
|
|
676
|
+
onBeforeCreate() {
|
|
677
|
+
const props = this.editor.options.editorProps;
|
|
678
|
+
this.editor.setOptions({ editorProps: {
|
|
679
|
+
...props,
|
|
680
|
+
handleTextInput(view, from, to, text, defaultTransaction) {
|
|
681
|
+
if (props.handleTextInput?.call(props, view, from, to, text, defaultTransaction)) return true;
|
|
682
|
+
if (view.composing) return false;
|
|
683
|
+
const rules = view.state.plugins.find((plugin) => plugin.spec.isInputRules);
|
|
684
|
+
if (!rules?.props.handleTextInput) return false;
|
|
685
|
+
view.dispatch((defaultTransaction?.() ?? view.state.tr.insertText(text, from, to)).scrollIntoView());
|
|
686
|
+
const position = view.state.selection.from;
|
|
687
|
+
rules.props.handleTextInput.call(rules, view, position, position, "", defaultTransaction);
|
|
688
|
+
return true;
|
|
689
|
+
}
|
|
690
|
+
} });
|
|
691
|
+
},
|
|
692
|
+
addKeyboardShortcuts() {
|
|
693
|
+
return { Escape: () => this.editor.commands.undoInputRule() };
|
|
694
|
+
},
|
|
695
|
+
addProseMirrorPlugins() {
|
|
696
|
+
return [new Plugin({
|
|
697
|
+
filterTransaction(tr, state) {
|
|
698
|
+
if (state.plugins.some((plugin) => plugin.spec.isInputRules && tr.getMeta(plugin))) closeHistory(tr);
|
|
699
|
+
return true;
|
|
700
|
+
},
|
|
701
|
+
appendTransaction(transactions, _old, state) {
|
|
702
|
+
if (transactions.some((tr) => state.plugins.some((plugin) => plugin.spec.isInputRules && tr.getMeta(plugin)))) return closeHistory(state.tr);
|
|
703
|
+
return null;
|
|
704
|
+
}
|
|
705
|
+
})];
|
|
706
|
+
}
|
|
707
|
+
});
|
|
708
|
+
//#endregion
|
|
665
709
|
//#region ../../node_modules/.pnpm/@tiptap+extension-document@2.27.2_@tiptap+core@2.27.2_@tiptap+pm@2.27.2_/node_modules/@tiptap/extension-document/dist/index.js
|
|
666
710
|
/**
|
|
667
711
|
* The default document node which represents the top level node of the editor.
|
|
@@ -9822,6 +9866,7 @@ function getDefaultEditorExtensions(options = {}) {
|
|
|
9822
9866
|
dividerNodeView ? HorizontalRule.extend({ addNodeView: () => dividerNodeView }) : HorizontalRule,
|
|
9823
9867
|
HardBreak,
|
|
9824
9868
|
History,
|
|
9869
|
+
LoomaInputRuleHistory,
|
|
9825
9870
|
Dropcursor,
|
|
9826
9871
|
Gapcursor,
|
|
9827
9872
|
Link.configure({
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Extension } from "@tiptap/core";
|
|
2
|
+
/**
|
|
3
|
+
* Keep the literal trigger in typing history before converting it. Tiptap's
|
|
4
|
+
* usual input rule consumes the final character, so simply closing history
|
|
5
|
+
* would restore an incomplete Markdown delimiter on Undo.
|
|
6
|
+
* @invariant Conversion and subsequent typing are separate history events.
|
|
7
|
+
* @lifecycle Tiptap clears its undoable input rule on typing or caret movement.
|
|
8
|
+
*/
|
|
9
|
+
export declare const LoomaInputRuleHistory: Extension<any, any>;
|
package/package.json
CHANGED
|
@@ -370,13 +370,13 @@ export declare const LoomaEditor: import("vue").DefineComponent<import("vue").Ex
|
|
|
370
370
|
}>, {
|
|
371
371
|
label: string;
|
|
372
372
|
placeholder: string;
|
|
373
|
+
extensions: AnyExtension[];
|
|
374
|
+
editable: boolean;
|
|
373
375
|
linkBaseUrl: string;
|
|
374
376
|
disableHighlight: boolean;
|
|
375
377
|
codeLanguages: Readonly<Record<string, import("highlight.js").LanguageFn>> | null;
|
|
376
378
|
modelValue: JSONContent;
|
|
377
|
-
editable: boolean;
|
|
378
379
|
contentDensity: "compact" | "comfortable";
|
|
379
|
-
extensions: AnyExtension[];
|
|
380
380
|
slashCommands: LoomaEditorSlashCommands;
|
|
381
381
|
mentionItems: LoomaMentionItem[];
|
|
382
382
|
mentionProvider: LoomaMentionProvider | undefined;
|
|
@@ -64,9 +64,9 @@ export declare const LoomaCompactEditor: import("vue").DefineComponent<import("v
|
|
|
64
64
|
}>, {
|
|
65
65
|
label: string;
|
|
66
66
|
id: string;
|
|
67
|
-
modelValue: JSONContent;
|
|
68
|
-
editable: boolean;
|
|
69
67
|
extensions: AnyExtension[];
|
|
68
|
+
editable: boolean;
|
|
69
|
+
modelValue: JSONContent;
|
|
70
70
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
71
71
|
/** Renders basic compact JSON as escaped Vue nodes, including during SSR. */
|
|
72
72
|
export declare const LoomaCompactContent: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { defineComponent, h, onBeforeUnmount, onMounted, shallowRef, watch } from "vue";
|
|
2
2
|
import { Extension, Mark, Node, markInputRule, markPasteRule, mergeAttributes } from "@tiptap/core";
|
|
3
3
|
import { Editor, EditorContent } from "@tiptap/vue-3";
|
|
4
|
-
import { history, redo, undo } from "@tiptap/pm/history";
|
|
4
|
+
import { closeHistory, history, redo, undo } from "@tiptap/pm/history";
|
|
5
|
+
import { Plugin } from "@tiptap/pm/state";
|
|
5
6
|
//#region ../../node_modules/.pnpm/@tiptap+extension-document@2.27.2_@tiptap+core@2.27.2_@tiptap+pm@2.27.2_/node_modules/@tiptap/extension-document/dist/index.js
|
|
6
7
|
/**
|
|
7
8
|
* The default document node which represents the top level node of the editor.
|
|
@@ -392,6 +393,50 @@ var History = Extension.create({
|
|
|
392
393
|
}
|
|
393
394
|
});
|
|
394
395
|
//#endregion
|
|
396
|
+
//#region src/editor/extensions/input-rule-history.ts
|
|
397
|
+
/**
|
|
398
|
+
* Keep the literal trigger in typing history before converting it. Tiptap's
|
|
399
|
+
* usual input rule consumes the final character, so simply closing history
|
|
400
|
+
* would restore an incomplete Markdown delimiter on Undo.
|
|
401
|
+
* @invariant Conversion and subsequent typing are separate history events.
|
|
402
|
+
* @lifecycle Tiptap clears its undoable input rule on typing or caret movement.
|
|
403
|
+
*/
|
|
404
|
+
var LoomaInputRuleHistory = Extension.create({
|
|
405
|
+
name: "loomaInputRuleHistory",
|
|
406
|
+
priority: 50,
|
|
407
|
+
onBeforeCreate() {
|
|
408
|
+
const props = this.editor.options.editorProps;
|
|
409
|
+
this.editor.setOptions({ editorProps: {
|
|
410
|
+
...props,
|
|
411
|
+
handleTextInput(view, from, to, text, defaultTransaction) {
|
|
412
|
+
if (props.handleTextInput?.call(props, view, from, to, text, defaultTransaction)) return true;
|
|
413
|
+
if (view.composing) return false;
|
|
414
|
+
const rules = view.state.plugins.find((plugin) => plugin.spec.isInputRules);
|
|
415
|
+
if (!rules?.props.handleTextInput) return false;
|
|
416
|
+
view.dispatch((defaultTransaction?.() ?? view.state.tr.insertText(text, from, to)).scrollIntoView());
|
|
417
|
+
const position = view.state.selection.from;
|
|
418
|
+
rules.props.handleTextInput.call(rules, view, position, position, "", defaultTransaction);
|
|
419
|
+
return true;
|
|
420
|
+
}
|
|
421
|
+
} });
|
|
422
|
+
},
|
|
423
|
+
addKeyboardShortcuts() {
|
|
424
|
+
return { Escape: () => this.editor.commands.undoInputRule() };
|
|
425
|
+
},
|
|
426
|
+
addProseMirrorPlugins() {
|
|
427
|
+
return [new Plugin({
|
|
428
|
+
filterTransaction(tr, state) {
|
|
429
|
+
if (state.plugins.some((plugin) => plugin.spec.isInputRules && tr.getMeta(plugin))) closeHistory(tr);
|
|
430
|
+
return true;
|
|
431
|
+
},
|
|
432
|
+
appendTransaction(transactions, _old, state) {
|
|
433
|
+
if (transactions.some((tr) => state.plugins.some((plugin) => plugin.spec.isInputRules && tr.getMeta(plugin)))) return closeHistory(state.tr);
|
|
434
|
+
return null;
|
|
435
|
+
}
|
|
436
|
+
})];
|
|
437
|
+
}
|
|
438
|
+
});
|
|
439
|
+
//#endregion
|
|
395
440
|
//#region src/vue/editor/compact/extensions.ts
|
|
396
441
|
/** Minimal short-form schema; additional consumer extensions are opt-in. */
|
|
397
442
|
function getCompactEditorExtensions() {
|
|
@@ -403,7 +448,8 @@ function getCompactEditorExtensions() {
|
|
|
403
448
|
Italic,
|
|
404
449
|
Code,
|
|
405
450
|
HardBreak,
|
|
406
|
-
History
|
|
451
|
+
History,
|
|
452
|
+
LoomaInputRuleHistory
|
|
407
453
|
];
|
|
408
454
|
}
|
|
409
455
|
//#endregion
|
package/vue/editor/index.js
CHANGED
|
@@ -2026,11 +2026,14 @@ var LoomaEditor = defineComponent({
|
|
|
2026
2026
|
],
|
|
2027
2027
|
content: props.modelValue,
|
|
2028
2028
|
editable: props.editable,
|
|
2029
|
-
editorProps: {
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2029
|
+
editorProps: {
|
|
2030
|
+
attributes: {
|
|
2031
|
+
role: "textbox",
|
|
2032
|
+
"aria-multiline": "true",
|
|
2033
|
+
"aria-label": props.label
|
|
2034
|
+
},
|
|
2035
|
+
handleKeyDown: (_view, event) => onFormattingKeyDown(event)
|
|
2036
|
+
},
|
|
2034
2037
|
onCreate: ({ editor: instance }) => {
|
|
2035
2038
|
emit("ready", instance);
|
|
2036
2039
|
instance.state.doc.descendants((node) => {
|
|
@@ -2782,13 +2785,14 @@ var LoomaEditor = defineComponent({
|
|
|
2782
2785
|
};
|
|
2783
2786
|
const onFormattingKeyDown = (event) => {
|
|
2784
2787
|
cancelHeldPress();
|
|
2785
|
-
if (event.key !== "Escape" || !floatingFormattingMode() || !(event.target instanceof Node) || !(root.value?.contains(event.target) || formattingPopup?.popper.contains(event.target))) return;
|
|
2788
|
+
if (event.key !== "Escape" || !floatingFormattingMode() || !(event.target instanceof Node) || !(root.value?.contains(event.target) || formattingPopup?.popper.contains(event.target)) || !(formatOpen.value || formattingPopup?.popper.style.visibility === "visible")) return false;
|
|
2786
2789
|
const selection = editor.value?.state.selection;
|
|
2787
2790
|
dismissedFormattingSelection = selection instanceof TextSelection || selection instanceof AllSelection ? selection : null;
|
|
2788
2791
|
heldFormattingSelection = null;
|
|
2789
2792
|
formatOpen.value = false;
|
|
2790
2793
|
formattingPopup?.hide();
|
|
2791
2794
|
hideTool();
|
|
2795
|
+
return true;
|
|
2792
2796
|
};
|
|
2793
2797
|
const onResizePointerDown = (event) => {
|
|
2794
2798
|
tableResizeActive = event.target instanceof HTMLElement && event.target.classList.contains("column-resize-handle");
|