@harbour-enterprises/superdoc 0.8.10 → 0.8.12
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/chunks/{super-editor.es-CnpejCPC.js → super-editor.es-D8IC7SPE.js} +719 -375
- package/dist/chunks/super-editor.es-D8IC7SPE.js.map +1 -0
- package/dist/super-editor/chunks/{converter-B5SRaBp5.js → converter-vMwuPcFT.js} +28 -27
- package/dist/super-editor/chunks/converter-vMwuPcFT.js.map +1 -0
- package/dist/super-editor/chunks/{docx-zipper-fdMcchlI.js → docx-zipper-CNguQWs9.js} +2 -2
- package/dist/super-editor/chunks/{docx-zipper-fdMcchlI.js.map → docx-zipper-CNguQWs9.js.map} +1 -1
- package/dist/super-editor/chunks/{editor-nlt5JeOJ.js → editor-aREw3zbp.js} +764 -420
- package/dist/super-editor/chunks/editor-aREw3zbp.js.map +1 -0
- package/dist/super-editor/chunks/{toolbar-COfngBDY.js → toolbar-BQJNZhd8.js} +3 -3
- package/dist/super-editor/chunks/{toolbar-COfngBDY.js.map → toolbar-BQJNZhd8.js.map} +1 -1
- package/dist/super-editor/converter.es.js +2 -2
- package/dist/super-editor/core/Editor.d.ts +1 -0
- package/dist/super-editor/core/Editor.d.ts.map +1 -1
- package/dist/super-editor/core/ExtensionService.d.ts.map +1 -1
- package/dist/super-editor/core/InputRule.d.ts +11 -0
- package/dist/super-editor/core/InputRule.d.ts.map +1 -0
- package/dist/super-editor/core/commands/index.d.ts +1 -0
- package/dist/super-editor/core/commands/undoInputRule.d.ts +5 -0
- package/dist/super-editor/core/commands/undoInputRule.d.ts.map +1 -0
- package/dist/super-editor/core/extensions/keymap.d.ts.map +1 -1
- package/dist/super-editor/core/helpers/getHTMLFromFragment.d.ts +2 -0
- package/dist/super-editor/core/helpers/getHTMLFromFragment.d.ts.map +1 -0
- package/dist/super-editor/core/helpers/getTextContentFromNodes.d.ts +2 -0
- package/dist/super-editor/core/helpers/getTextContentFromNodes.d.ts.map +1 -0
- package/dist/super-editor/core/helpers/isExtentionRulesEnabled.d.ts +2 -0
- package/dist/super-editor/core/helpers/isExtentionRulesEnabled.d.ts.map +1 -0
- package/dist/super-editor/core/inputRules/wrappingInputRule.d.ts +9 -0
- package/dist/super-editor/core/inputRules/wrappingInputRule.d.ts.map +1 -0
- package/dist/super-editor/core/utilities/isRegExp.d.ts +2 -0
- package/dist/super-editor/core/utilities/isRegExp.d.ts.map +1 -0
- package/dist/super-editor/core/utilities/objectIncludes.d.ts.map +1 -1
- package/dist/super-editor/docx-zipper.es.js +2 -2
- package/dist/super-editor/editor.es.js +3 -3
- package/dist/super-editor/extensions/bullet-list/bullet-list.d.ts.map +1 -1
- package/dist/super-editor/extensions/comment/comments-plugin.d.ts.map +1 -1
- package/dist/super-editor/extensions/ordered-list/ordered-list.d.ts.map +1 -1
- package/dist/super-editor/extensions/track-changes/trackChangesHelpers/addMarkStep.d.ts.map +1 -1
- package/dist/super-editor/extensions/track-changes/trackChangesHelpers/removeMarkStep.d.ts.map +1 -1
- package/dist/super-editor/extensions/track-changes/trackChangesHelpers/replaceStep.d.ts.map +1 -1
- package/dist/super-editor/file-zipper.es.js +1 -1
- package/dist/super-editor/super-editor.es.js +7 -7
- package/dist/super-editor/toolbar.es.js +2 -2
- package/dist/super-editor.es.js +1 -1
- package/dist/superdoc.es.js +3 -3
- package/dist/superdoc.umd.js +730 -386
- package/dist/superdoc.umd.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunks/super-editor.es-CnpejCPC.js.map +0 -1
- package/dist/super-editor/chunks/converter-B5SRaBp5.js.map +0 -1
- package/dist/super-editor/chunks/editor-nlt5JeOJ.js.map +0 -1
|
@@ -12,9 +12,9 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
|
|
|
12
12
|
var _events, _Attribute_static, getGlobalAttributes_fn, getNodeAndMarksAttributes_fn, _Schema_static, createNodesSchema_fn, createMarksSchema_fn, _ExtensionService_instances, setupExtensions_fn, attachEditorEvents_fn, _commandService, _css, _Editor_instances, init_fn, initRichText_fn, onFocus_fn, checkHeadless_fn, insertNewFileData_fn, registerPluginByNameIfNotExists_fn, createExtensionService_fn, createCommandService_fn, createConverter_fn, initMedia_fn, createSchema_fn, generatePmData_fn, createView_fn, onCollaborationReady_fn, initComments_fn, initPagination_fn, dispatchTransaction_fn, prepareDocumentForImport_fn, prepareDocumentForExport_fn, endCollaboration_fn, _FieldAnnotationView_instances, createAnnotation_fn;
|
|
13
13
|
import * as Y from "yjs";
|
|
14
14
|
import { UndoManager, Item as Item$1, ContentType, Text as Text$1, XmlElement } from "yjs";
|
|
15
|
-
import { P as PluginKey, a as Plugin, M as Mapping, N as NodeSelection, S as Selection, T as TextSelection, b as Slice, D as DOMSerializer, F as Fragment, c as DOMParser$1, d as Mark$1, e as dropPoint, A as AllSelection, p as process$1, f as Schema$1, g as canSplit, l as liftTarget, h as canJoin, j as joinPoint, r as replaceStep$1, R as ReplaceAroundStep, o as objectIncludes,
|
|
15
|
+
import { P as PluginKey, a as Plugin, M as Mapping, N as NodeSelection, S as Selection, T as TextSelection, b as Slice, D as DOMSerializer, F as Fragment, c as DOMParser$1, d as Mark$1, e as dropPoint, A as AllSelection, p as process$1, f as Schema$1, i as isRegExp, g as canSplit, l as liftTarget, h as canJoin, j as joinPoint, r as replaceStep$1, R as ReplaceAroundStep, o as objectIncludes, k as ReplaceStep, m as NodeRange, n as findWrapping, q as TrackDeleteMarkName, s as TrackInsertMarkName, v as v4, t as generateDocxRandomId, u as generateRandom32BitHex, w as TrackFormatMarkName, x as comments_module_events, y as AddMarkStep, z as RemoveMarkStep, B as twipsToLines, C as pixelsToTwips, E as SuperConverter, G as EditorState, H as toKebabCase, I as kebabCase, J as SelectionRange, K as Transform } from "./converter-vMwuPcFT.js";
|
|
16
16
|
import { ref, computed, createElementBlock, openBlock, withModifiers, Fragment as Fragment$1, renderList, normalizeClass, createCommentVNode, toDisplayString, createElementVNode, createApp } from "vue";
|
|
17
|
-
import { D as DocxZipper } from "./docx-zipper-
|
|
17
|
+
import { D as DocxZipper } from "./docx-zipper-CNguQWs9.js";
|
|
18
18
|
function getMarksFromSelection(state) {
|
|
19
19
|
const { from: from2, to, empty: empty2 } = state.selection;
|
|
20
20
|
const marks = [];
|
|
@@ -7961,206 +7961,15 @@ let Schema = _Schema;
|
|
|
7961
7961
|
function getSchemaTypeByName(name, schema) {
|
|
7962
7962
|
return schema.nodes[name] || schema.marks[name] || null;
|
|
7963
7963
|
}
|
|
7964
|
-
|
|
7965
|
-
|
|
7966
|
-
|
|
7967
|
-
|
|
7968
|
-
|
|
7969
|
-
__publicField(this, "extensions");
|
|
7970
|
-
__publicField(this, "externalExtensions", []);
|
|
7971
|
-
__publicField(this, "splittableMarks", []);
|
|
7972
|
-
this.editor = editor;
|
|
7973
|
-
this.externalExtensions = userExtensions || [];
|
|
7974
|
-
this.extensions = _ExtensionService.getResolvedExtensions([...extensions, ...this.externalExtensions]);
|
|
7975
|
-
this.schema = Schema.createSchemaByExtensions(this.extensions, editor);
|
|
7976
|
-
__privateMethod(this, _ExtensionService_instances, setupExtensions_fn).call(this);
|
|
7977
|
-
}
|
|
7978
|
-
/**
|
|
7979
|
-
* Static method for creating ExtensionService.
|
|
7980
|
-
* @param args Arguments for the constructor.
|
|
7981
|
-
*/
|
|
7982
|
-
static create(...args) {
|
|
7983
|
-
return new _ExtensionService(...args);
|
|
7984
|
-
}
|
|
7985
|
-
/**
|
|
7986
|
-
* Get an array of resolved extensions (e.g. sorted by priority).
|
|
7987
|
-
* @param extensions Array of extensions.
|
|
7988
|
-
* @returns Array of resolved extensions.
|
|
7989
|
-
*/
|
|
7990
|
-
static getResolvedExtensions(extensions) {
|
|
7991
|
-
const resolvedExtensions = _ExtensionService.sortByPriority(extensions);
|
|
7992
|
-
return resolvedExtensions;
|
|
7993
|
-
}
|
|
7994
|
-
/**
|
|
7995
|
-
* Sort extensions by priority.
|
|
7996
|
-
* @param extensions Array of extensions.
|
|
7997
|
-
* @returns Array of sorted extensions by priority.
|
|
7998
|
-
*/
|
|
7999
|
-
static sortByPriority(extensions) {
|
|
8000
|
-
const defaultValue = 100;
|
|
8001
|
-
return extensions.sort((a, b) => {
|
|
8002
|
-
const priorityA = getExtensionConfigField(a, "priority") || defaultValue;
|
|
8003
|
-
const priorityB = getExtensionConfigField(b, "priority") || defaultValue;
|
|
8004
|
-
if (priorityA > priorityB) return -1;
|
|
8005
|
-
if (priorityA < priorityB) return 1;
|
|
8006
|
-
return 0;
|
|
8007
|
-
});
|
|
8008
|
-
}
|
|
8009
|
-
/**
|
|
8010
|
-
* Get all attributes defined in the extensions.
|
|
8011
|
-
* @returns Array of attributes.
|
|
8012
|
-
*/
|
|
8013
|
-
get attributes() {
|
|
8014
|
-
return Attribute.getAttributesFromExtensions(this.extensions);
|
|
8015
|
-
}
|
|
8016
|
-
/**
|
|
8017
|
-
* Get all commands defined in the extensions.
|
|
8018
|
-
* @returns Object with commands (key - command name, value - function).
|
|
8019
|
-
*/
|
|
8020
|
-
get commands() {
|
|
8021
|
-
let commandsObject = {};
|
|
8022
|
-
for (const extension of this.extensions) {
|
|
8023
|
-
const context = {
|
|
8024
|
-
name: extension.name,
|
|
8025
|
-
options: extension.options,
|
|
8026
|
-
storage: extension.storage,
|
|
8027
|
-
editor: this.editor,
|
|
8028
|
-
type: getSchemaTypeByName(extension.name, this.schema)
|
|
8029
|
-
};
|
|
8030
|
-
const addCommands = getExtensionConfigField(extension, "addCommands", context);
|
|
8031
|
-
if (addCommands) {
|
|
8032
|
-
commandsObject = {
|
|
8033
|
-
...commandsObject,
|
|
8034
|
-
...addCommands()
|
|
8035
|
-
};
|
|
8036
|
-
}
|
|
8037
|
-
}
|
|
8038
|
-
return commandsObject;
|
|
8039
|
-
}
|
|
8040
|
-
/**
|
|
8041
|
-
* Get all PM plugins defined in the extensions.
|
|
8042
|
-
* And also keyboard shortcuts.
|
|
8043
|
-
* @returns Array of PM plugins.
|
|
8044
|
-
*/
|
|
8045
|
-
get plugins() {
|
|
8046
|
-
const editor = this.editor;
|
|
8047
|
-
const extensions = _ExtensionService.sortByPriority([...this.extensions].reverse());
|
|
8048
|
-
const allPlugins = extensions.map((extension) => {
|
|
8049
|
-
const context = {
|
|
8050
|
-
name: extension.name,
|
|
8051
|
-
options: extension.options,
|
|
8052
|
-
storage: extension.storage,
|
|
8053
|
-
editor,
|
|
8054
|
-
type: getSchemaTypeByName(extension.name, this.schema)
|
|
8055
|
-
};
|
|
8056
|
-
const plugins = [];
|
|
8057
|
-
const addShortcuts = getExtensionConfigField(extension, "addShortcuts", context);
|
|
8058
|
-
let bindingsObject = {};
|
|
8059
|
-
if (addShortcuts) {
|
|
8060
|
-
const entries = Object.entries(addShortcuts()).map(([shortcut, method]) => {
|
|
8061
|
-
return [shortcut, (...args) => method({ editor, keymapArgs: args })];
|
|
8062
|
-
});
|
|
8063
|
-
bindingsObject = { ...Object.fromEntries(entries) };
|
|
8064
|
-
}
|
|
8065
|
-
plugins.push(keymap(bindingsObject));
|
|
8066
|
-
const addPmPlugins = getExtensionConfigField(extension, "addPmPlugins", context);
|
|
8067
|
-
if (addPmPlugins) {
|
|
8068
|
-
const pmPlugins = addPmPlugins();
|
|
8069
|
-
plugins.push(...pmPlugins);
|
|
8070
|
-
}
|
|
8071
|
-
return plugins;
|
|
8072
|
-
}).flat();
|
|
8073
|
-
return [...allPlugins];
|
|
8074
|
-
}
|
|
8075
|
-
/**
|
|
8076
|
-
* Get all node views from the extensions.
|
|
8077
|
-
* @returns An object with all node views.
|
|
8078
|
-
*/
|
|
8079
|
-
get nodeViews() {
|
|
8080
|
-
const { editor } = this;
|
|
8081
|
-
const nodeExtensions = this.extensions.filter((e) => e.type === "node");
|
|
8082
|
-
const entries = nodeExtensions.filter((extension) => !!getExtensionConfigField(extension, "addNodeView")).map((extension) => {
|
|
8083
|
-
const extensionAttrs = this.attributes.filter((a) => a.type === extension.name);
|
|
8084
|
-
const context = {
|
|
8085
|
-
name: extension.name,
|
|
8086
|
-
options: extension.options,
|
|
8087
|
-
storage: extension.storage,
|
|
8088
|
-
editor,
|
|
8089
|
-
type: getNodeType(extension.name, this.schema)
|
|
8090
|
-
};
|
|
8091
|
-
const addNodeView = getExtensionConfigField(extension, "addNodeView", context);
|
|
8092
|
-
if (!addNodeView) return [];
|
|
8093
|
-
const nodeview = (node, _view, getPos, decorations) => {
|
|
8094
|
-
const htmlAttributes = Attribute.getAttributesToRender(node, extensionAttrs);
|
|
8095
|
-
return addNodeView()({
|
|
8096
|
-
editor,
|
|
8097
|
-
node,
|
|
8098
|
-
getPos,
|
|
8099
|
-
decorations,
|
|
8100
|
-
htmlAttributes,
|
|
8101
|
-
extension
|
|
8102
|
-
});
|
|
8103
|
-
};
|
|
8104
|
-
return [extension.name, nodeview];
|
|
7964
|
+
function isExtensionRulesEnabled(extension, enabled) {
|
|
7965
|
+
if (Array.isArray(enabled)) {
|
|
7966
|
+
return enabled.some((enabledExtension) => {
|
|
7967
|
+
const name = typeof enabledExtension === "string" ? enabledExtension : enabledExtension.name;
|
|
7968
|
+
return name === extension.name;
|
|
8105
7969
|
});
|
|
8106
|
-
return Object.fromEntries(entries);
|
|
8107
|
-
}
|
|
8108
|
-
};
|
|
8109
|
-
_ExtensionService_instances = new WeakSet();
|
|
8110
|
-
/**
|
|
8111
|
-
* Install all extensions.
|
|
8112
|
-
* Create extension storage in the editor, attach editor events.
|
|
8113
|
-
*/
|
|
8114
|
-
setupExtensions_fn = function() {
|
|
8115
|
-
for (const extension of this.extensions) {
|
|
8116
|
-
this.editor.extensionStorage[extension.name] = extension.storage;
|
|
8117
|
-
const context = {
|
|
8118
|
-
name: extension.name,
|
|
8119
|
-
options: extension.options,
|
|
8120
|
-
storage: extension.storage,
|
|
8121
|
-
editor: this.editor,
|
|
8122
|
-
type: getSchemaTypeByName(extension.name, this.schema)
|
|
8123
|
-
};
|
|
8124
|
-
if (extension.type === "mark") {
|
|
8125
|
-
const keepOnSplit = callOrGet(getExtensionConfigField(extension, "keepOnSplit", context)) ?? true;
|
|
8126
|
-
if (keepOnSplit) {
|
|
8127
|
-
this.splittableMarks.push(extension.name);
|
|
8128
|
-
}
|
|
8129
|
-
}
|
|
8130
|
-
__privateMethod(this, _ExtensionService_instances, attachEditorEvents_fn).call(this, extension);
|
|
8131
7970
|
}
|
|
8132
|
-
|
|
8133
|
-
|
|
8134
|
-
* Attach editor events to extension
|
|
8135
|
-
* if callbacks are defined in the extension config.
|
|
8136
|
-
* @param extension Extension.
|
|
8137
|
-
*/
|
|
8138
|
-
attachEditorEvents_fn = function(extension) {
|
|
8139
|
-
const context = {
|
|
8140
|
-
name: extension.name,
|
|
8141
|
-
options: extension.options,
|
|
8142
|
-
storage: extension.storage,
|
|
8143
|
-
editor: this.editor,
|
|
8144
|
-
type: getSchemaTypeByName(extension.name, this.schema)
|
|
8145
|
-
};
|
|
8146
|
-
const onBeforeCreate = getExtensionConfigField(extension, "onBeforeCreate", context);
|
|
8147
|
-
const onCreate2 = getExtensionConfigField(extension, "onCreate", context);
|
|
8148
|
-
const onUpdate = getExtensionConfigField(extension, "onUpdate", context);
|
|
8149
|
-
const onSelectionUpdate = getExtensionConfigField(extension, "onSelectionUpdate", context);
|
|
8150
|
-
const onTransaction = getExtensionConfigField(extension, "onTransaction", context);
|
|
8151
|
-
const onFocus = getExtensionConfigField(extension, "onFocus", context);
|
|
8152
|
-
const onBlur = getExtensionConfigField(extension, "onBlur", context);
|
|
8153
|
-
const onDestroy2 = getExtensionConfigField(extension, "onDestroy", context);
|
|
8154
|
-
if (onBeforeCreate) this.editor.on("beforeCreate", onBeforeCreate);
|
|
8155
|
-
if (onCreate2) this.editor.on("create", onCreate2);
|
|
8156
|
-
if (onUpdate) this.editor.on("update", onUpdate);
|
|
8157
|
-
if (onSelectionUpdate) this.editor.on("selectionUpdate", onSelectionUpdate);
|
|
8158
|
-
if (onTransaction) this.editor.on("transaction", onTransaction);
|
|
8159
|
-
if (onFocus) this.editor.on("focus", onFocus);
|
|
8160
|
-
if (onBlur) this.editor.on("blur", onBlur);
|
|
8161
|
-
if (onDestroy2) this.editor.on("destroy", onDestroy2);
|
|
8162
|
-
};
|
|
8163
|
-
let ExtensionService = _ExtensionService;
|
|
7971
|
+
return enabled;
|
|
7972
|
+
}
|
|
8164
7973
|
function chainableEditorState(transaction, state) {
|
|
8165
7974
|
let { selection, doc: doc2, storedMarks } = transaction;
|
|
8166
7975
|
return {
|
|
@@ -8251,7 +8060,7 @@ class CommandService {
|
|
|
8251
8060
|
const callbacks = [];
|
|
8252
8061
|
const hasStartTr = !!startTr;
|
|
8253
8062
|
const tr = startTr || state.tr;
|
|
8254
|
-
const
|
|
8063
|
+
const run2 = () => {
|
|
8255
8064
|
if (!hasStartTr && shouldDispatch && !tr.getMeta("preventDispatch")) {
|
|
8256
8065
|
view.dispatch(tr);
|
|
8257
8066
|
}
|
|
@@ -8268,7 +8077,7 @@ class CommandService {
|
|
|
8268
8077
|
});
|
|
8269
8078
|
const chain = {
|
|
8270
8079
|
...Object.fromEntries(entries),
|
|
8271
|
-
run
|
|
8080
|
+
run: run2
|
|
8272
8081
|
};
|
|
8273
8082
|
return chain;
|
|
8274
8083
|
}
|
|
@@ -8316,9 +8125,404 @@ class CommandService {
|
|
|
8316
8125
|
);
|
|
8317
8126
|
}
|
|
8318
8127
|
};
|
|
8319
|
-
return props;
|
|
8128
|
+
return props;
|
|
8129
|
+
}
|
|
8130
|
+
}
|
|
8131
|
+
function getHTMLFromFragment(fragment, schema) {
|
|
8132
|
+
const documentFragment = DOMSerializer.fromSchema(schema).serializeFragment(fragment);
|
|
8133
|
+
const temporaryDocument = document.implementation.createHTMLDocument();
|
|
8134
|
+
const container = temporaryDocument.createElement("div");
|
|
8135
|
+
container.appendChild(documentFragment);
|
|
8136
|
+
return container.innerHTML;
|
|
8137
|
+
}
|
|
8138
|
+
const getTextContentFromNodes = ($from, maxMatch = 500) => {
|
|
8139
|
+
let textBefore = "";
|
|
8140
|
+
const sliceEndPos = $from.parentOffset;
|
|
8141
|
+
$from.parent.nodesBetween(
|
|
8142
|
+
Math.max(0, sliceEndPos - maxMatch),
|
|
8143
|
+
sliceEndPos,
|
|
8144
|
+
(node, pos, parent, index2) => {
|
|
8145
|
+
const chunk = node.type.spec.toText?.({
|
|
8146
|
+
node,
|
|
8147
|
+
pos,
|
|
8148
|
+
parent,
|
|
8149
|
+
index: index2
|
|
8150
|
+
}) || node.textContent || "%leaf%";
|
|
8151
|
+
textBefore += node.isAtom && !node.isText ? chunk : chunk.slice(0, Math.max(0, sliceEndPos - pos));
|
|
8152
|
+
}
|
|
8153
|
+
);
|
|
8154
|
+
return textBefore;
|
|
8155
|
+
};
|
|
8156
|
+
class InputRule {
|
|
8157
|
+
constructor(config) {
|
|
8158
|
+
__publicField(this, "match");
|
|
8159
|
+
__publicField(this, "handler");
|
|
8160
|
+
this.match = config.match;
|
|
8161
|
+
this.handler = config.handler;
|
|
8162
|
+
}
|
|
8163
|
+
}
|
|
8164
|
+
const inputRuleMatcherHandler = (text, match) => {
|
|
8165
|
+
if (isRegExp(match)) {
|
|
8166
|
+
return match.exec(text);
|
|
8167
|
+
}
|
|
8168
|
+
const inputRuleMatch = match(text);
|
|
8169
|
+
if (!inputRuleMatch) {
|
|
8170
|
+
return null;
|
|
8171
|
+
}
|
|
8172
|
+
const result = [inputRuleMatch.text];
|
|
8173
|
+
result.index = inputRuleMatch.index;
|
|
8174
|
+
result.input = text;
|
|
8175
|
+
result.data = inputRuleMatch.data;
|
|
8176
|
+
if (inputRuleMatch.replaceWith) {
|
|
8177
|
+
if (!inputRuleMatch.text.includes(inputRuleMatch.replaceWith)) {
|
|
8178
|
+
console.warn(
|
|
8179
|
+
'[super-editor warn]: "inputRuleMatch.replaceWith" must be part of "inputRuleMatch.text".'
|
|
8180
|
+
);
|
|
8181
|
+
}
|
|
8182
|
+
result.push(inputRuleMatch.replaceWith);
|
|
8183
|
+
}
|
|
8184
|
+
return result;
|
|
8185
|
+
};
|
|
8186
|
+
const run = (config) => {
|
|
8187
|
+
const {
|
|
8188
|
+
editor,
|
|
8189
|
+
from: from2,
|
|
8190
|
+
to,
|
|
8191
|
+
text,
|
|
8192
|
+
rules,
|
|
8193
|
+
plugin
|
|
8194
|
+
} = config;
|
|
8195
|
+
const { view } = editor;
|
|
8196
|
+
if (view.composing) {
|
|
8197
|
+
return false;
|
|
8198
|
+
}
|
|
8199
|
+
const $from = view.state.doc.resolve(from2);
|
|
8200
|
+
if ($from.parent.type.spec.code || !!($from.nodeBefore || $from.nodeAfter)?.marks.find((mark) => mark.type.spec.code)) {
|
|
8201
|
+
return false;
|
|
8202
|
+
}
|
|
8203
|
+
let matched = false;
|
|
8204
|
+
const textBefore = getTextContentFromNodes($from) + text;
|
|
8205
|
+
rules.forEach((rule) => {
|
|
8206
|
+
if (matched) {
|
|
8207
|
+
return;
|
|
8208
|
+
}
|
|
8209
|
+
const match = inputRuleMatcherHandler(textBefore, rule.match);
|
|
8210
|
+
if (!match) {
|
|
8211
|
+
return;
|
|
8212
|
+
}
|
|
8213
|
+
const tr = view.state.tr;
|
|
8214
|
+
const state = chainableEditorState(tr, view.state);
|
|
8215
|
+
const range = {
|
|
8216
|
+
from: from2 - (match[0].length - text.length),
|
|
8217
|
+
to
|
|
8218
|
+
};
|
|
8219
|
+
const { commands: commands2, chain, can } = new CommandService({
|
|
8220
|
+
editor,
|
|
8221
|
+
state
|
|
8222
|
+
});
|
|
8223
|
+
const handler = rule.handler({
|
|
8224
|
+
state,
|
|
8225
|
+
range,
|
|
8226
|
+
match,
|
|
8227
|
+
commands: commands2,
|
|
8228
|
+
chain,
|
|
8229
|
+
can
|
|
8230
|
+
});
|
|
8231
|
+
if (handler === null || !tr.steps.length) {
|
|
8232
|
+
return;
|
|
8233
|
+
}
|
|
8234
|
+
tr.setMeta(plugin, {
|
|
8235
|
+
transform: tr,
|
|
8236
|
+
from: from2,
|
|
8237
|
+
to,
|
|
8238
|
+
text
|
|
8239
|
+
});
|
|
8240
|
+
view.dispatch(tr);
|
|
8241
|
+
matched = true;
|
|
8242
|
+
});
|
|
8243
|
+
return matched;
|
|
8244
|
+
};
|
|
8245
|
+
const inputRulesPlugin = ({ editor, rules }) => {
|
|
8246
|
+
const plugin = new Plugin({
|
|
8247
|
+
key: new PluginKey("inputRulesPlugin"),
|
|
8248
|
+
state: {
|
|
8249
|
+
init() {
|
|
8250
|
+
return null;
|
|
8251
|
+
},
|
|
8252
|
+
apply(tr, prev, state) {
|
|
8253
|
+
const stored = tr.getMeta(plugin);
|
|
8254
|
+
if (stored) {
|
|
8255
|
+
return stored;
|
|
8256
|
+
}
|
|
8257
|
+
const simulatedInputMeta = tr.getMeta("applyInputRules");
|
|
8258
|
+
const isSimulatedInput = !!simulatedInputMeta;
|
|
8259
|
+
if (isSimulatedInput) {
|
|
8260
|
+
setTimeout(() => {
|
|
8261
|
+
let { text } = simulatedInputMeta;
|
|
8262
|
+
if (typeof text !== "string") {
|
|
8263
|
+
text = getHTMLFromFragment(Fragment.from(text), state.schema);
|
|
8264
|
+
}
|
|
8265
|
+
const { from: from2 } = simulatedInputMeta;
|
|
8266
|
+
const to = from2 + text.length;
|
|
8267
|
+
run({
|
|
8268
|
+
editor,
|
|
8269
|
+
from: from2,
|
|
8270
|
+
to,
|
|
8271
|
+
text,
|
|
8272
|
+
rules,
|
|
8273
|
+
plugin
|
|
8274
|
+
});
|
|
8275
|
+
});
|
|
8276
|
+
}
|
|
8277
|
+
return tr.selectionSet || tr.docChanged ? null : prev;
|
|
8278
|
+
}
|
|
8279
|
+
},
|
|
8280
|
+
props: {
|
|
8281
|
+
handleTextInput(view, from2, to, text) {
|
|
8282
|
+
return run({
|
|
8283
|
+
editor,
|
|
8284
|
+
from: from2,
|
|
8285
|
+
to,
|
|
8286
|
+
text,
|
|
8287
|
+
rules,
|
|
8288
|
+
plugin
|
|
8289
|
+
});
|
|
8290
|
+
},
|
|
8291
|
+
// add support for input rules to trigger on enter
|
|
8292
|
+
// this is useful for example for code blocks
|
|
8293
|
+
handleKeyDown(view, event) {
|
|
8294
|
+
if (event.key !== "Enter") {
|
|
8295
|
+
return false;
|
|
8296
|
+
}
|
|
8297
|
+
const { $cursor } = view.state.selection;
|
|
8298
|
+
if ($cursor) {
|
|
8299
|
+
return run({
|
|
8300
|
+
editor,
|
|
8301
|
+
from: $cursor.pos,
|
|
8302
|
+
to: $cursor.pos,
|
|
8303
|
+
text: "\n",
|
|
8304
|
+
rules,
|
|
8305
|
+
plugin
|
|
8306
|
+
});
|
|
8307
|
+
}
|
|
8308
|
+
return false;
|
|
8309
|
+
}
|
|
8310
|
+
},
|
|
8311
|
+
isInputRules: true
|
|
8312
|
+
});
|
|
8313
|
+
return plugin;
|
|
8314
|
+
};
|
|
8315
|
+
const _ExtensionService = class _ExtensionService {
|
|
8316
|
+
constructor(extensions, userExtensions, editor) {
|
|
8317
|
+
__privateAdd(this, _ExtensionService_instances);
|
|
8318
|
+
__publicField(this, "editor");
|
|
8319
|
+
__publicField(this, "schema");
|
|
8320
|
+
__publicField(this, "extensions");
|
|
8321
|
+
__publicField(this, "externalExtensions", []);
|
|
8322
|
+
__publicField(this, "splittableMarks", []);
|
|
8323
|
+
this.editor = editor;
|
|
8324
|
+
this.externalExtensions = userExtensions || [];
|
|
8325
|
+
this.extensions = _ExtensionService.getResolvedExtensions([...extensions, ...this.externalExtensions]);
|
|
8326
|
+
this.schema = Schema.createSchemaByExtensions(this.extensions, editor);
|
|
8327
|
+
__privateMethod(this, _ExtensionService_instances, setupExtensions_fn).call(this);
|
|
8328
|
+
}
|
|
8329
|
+
/**
|
|
8330
|
+
* Static method for creating ExtensionService.
|
|
8331
|
+
* @param args Arguments for the constructor.
|
|
8332
|
+
*/
|
|
8333
|
+
static create(...args) {
|
|
8334
|
+
return new _ExtensionService(...args);
|
|
8335
|
+
}
|
|
8336
|
+
/**
|
|
8337
|
+
* Get an array of resolved extensions (e.g. sorted by priority).
|
|
8338
|
+
* @param extensions Array of extensions.
|
|
8339
|
+
* @returns Array of resolved extensions.
|
|
8340
|
+
*/
|
|
8341
|
+
static getResolvedExtensions(extensions) {
|
|
8342
|
+
const resolvedExtensions = _ExtensionService.sortByPriority(extensions);
|
|
8343
|
+
return resolvedExtensions;
|
|
8344
|
+
}
|
|
8345
|
+
/**
|
|
8346
|
+
* Sort extensions by priority.
|
|
8347
|
+
* @param extensions Array of extensions.
|
|
8348
|
+
* @returns Array of sorted extensions by priority.
|
|
8349
|
+
*/
|
|
8350
|
+
static sortByPriority(extensions) {
|
|
8351
|
+
const defaultValue = 100;
|
|
8352
|
+
return extensions.sort((a, b) => {
|
|
8353
|
+
const priorityA = getExtensionConfigField(a, "priority") || defaultValue;
|
|
8354
|
+
const priorityB = getExtensionConfigField(b, "priority") || defaultValue;
|
|
8355
|
+
if (priorityA > priorityB) return -1;
|
|
8356
|
+
if (priorityA < priorityB) return 1;
|
|
8357
|
+
return 0;
|
|
8358
|
+
});
|
|
8359
|
+
}
|
|
8360
|
+
/**
|
|
8361
|
+
* Get all attributes defined in the extensions.
|
|
8362
|
+
* @returns Array of attributes.
|
|
8363
|
+
*/
|
|
8364
|
+
get attributes() {
|
|
8365
|
+
return Attribute.getAttributesFromExtensions(this.extensions);
|
|
8366
|
+
}
|
|
8367
|
+
/**
|
|
8368
|
+
* Get all commands defined in the extensions.
|
|
8369
|
+
* @returns Object with commands (key - command name, value - function).
|
|
8370
|
+
*/
|
|
8371
|
+
get commands() {
|
|
8372
|
+
let commandsObject = {};
|
|
8373
|
+
for (const extension of this.extensions) {
|
|
8374
|
+
const context = {
|
|
8375
|
+
name: extension.name,
|
|
8376
|
+
options: extension.options,
|
|
8377
|
+
storage: extension.storage,
|
|
8378
|
+
editor: this.editor,
|
|
8379
|
+
type: getSchemaTypeByName(extension.name, this.schema)
|
|
8380
|
+
};
|
|
8381
|
+
const addCommands = getExtensionConfigField(extension, "addCommands", context);
|
|
8382
|
+
if (addCommands) {
|
|
8383
|
+
commandsObject = {
|
|
8384
|
+
...commandsObject,
|
|
8385
|
+
...addCommands()
|
|
8386
|
+
};
|
|
8387
|
+
}
|
|
8388
|
+
}
|
|
8389
|
+
return commandsObject;
|
|
8390
|
+
}
|
|
8391
|
+
/**
|
|
8392
|
+
* Get all PM plugins defined in the extensions.
|
|
8393
|
+
* And also keyboard shortcuts.
|
|
8394
|
+
* @returns Array of PM plugins.
|
|
8395
|
+
*/
|
|
8396
|
+
get plugins() {
|
|
8397
|
+
const editor = this.editor;
|
|
8398
|
+
const extensions = _ExtensionService.sortByPriority([...this.extensions].reverse());
|
|
8399
|
+
const inputRules = [];
|
|
8400
|
+
const allPlugins = extensions.map((extension) => {
|
|
8401
|
+
const context = {
|
|
8402
|
+
name: extension.name,
|
|
8403
|
+
options: extension.options,
|
|
8404
|
+
storage: extension.storage,
|
|
8405
|
+
editor,
|
|
8406
|
+
type: getSchemaTypeByName(extension.name, this.schema)
|
|
8407
|
+
};
|
|
8408
|
+
const plugins = [];
|
|
8409
|
+
const addShortcuts = getExtensionConfigField(extension, "addShortcuts", context);
|
|
8410
|
+
let bindingsObject = {};
|
|
8411
|
+
if (addShortcuts) {
|
|
8412
|
+
const entries = Object.entries(addShortcuts()).map(([shortcut, method]) => {
|
|
8413
|
+
return [shortcut, (...args) => method({ editor, keymapArgs: args })];
|
|
8414
|
+
});
|
|
8415
|
+
bindingsObject = { ...Object.fromEntries(entries) };
|
|
8416
|
+
}
|
|
8417
|
+
plugins.push(keymap(bindingsObject));
|
|
8418
|
+
const addInputRules = getExtensionConfigField(extension, "addInputRules", context);
|
|
8419
|
+
if (isExtensionRulesEnabled(extension, editor.options.enableInputRules) && addInputRules) {
|
|
8420
|
+
inputRules.push(...addInputRules());
|
|
8421
|
+
}
|
|
8422
|
+
const addPmPlugins = getExtensionConfigField(extension, "addPmPlugins", context);
|
|
8423
|
+
if (addPmPlugins) {
|
|
8424
|
+
const pmPlugins = addPmPlugins();
|
|
8425
|
+
plugins.push(...pmPlugins);
|
|
8426
|
+
}
|
|
8427
|
+
return plugins;
|
|
8428
|
+
}).flat();
|
|
8429
|
+
return [
|
|
8430
|
+
inputRulesPlugin({
|
|
8431
|
+
editor,
|
|
8432
|
+
rules: inputRules
|
|
8433
|
+
}),
|
|
8434
|
+
...allPlugins
|
|
8435
|
+
];
|
|
8436
|
+
}
|
|
8437
|
+
/**
|
|
8438
|
+
* Get all node views from the extensions.
|
|
8439
|
+
* @returns An object with all node views.
|
|
8440
|
+
*/
|
|
8441
|
+
get nodeViews() {
|
|
8442
|
+
const { editor } = this;
|
|
8443
|
+
const nodeExtensions = this.extensions.filter((e) => e.type === "node");
|
|
8444
|
+
const entries = nodeExtensions.filter((extension) => !!getExtensionConfigField(extension, "addNodeView")).map((extension) => {
|
|
8445
|
+
const extensionAttrs = this.attributes.filter((a) => a.type === extension.name);
|
|
8446
|
+
const context = {
|
|
8447
|
+
name: extension.name,
|
|
8448
|
+
options: extension.options,
|
|
8449
|
+
storage: extension.storage,
|
|
8450
|
+
editor,
|
|
8451
|
+
type: getNodeType(extension.name, this.schema)
|
|
8452
|
+
};
|
|
8453
|
+
const addNodeView = getExtensionConfigField(extension, "addNodeView", context);
|
|
8454
|
+
if (!addNodeView) return [];
|
|
8455
|
+
const nodeview = (node, _view, getPos, decorations) => {
|
|
8456
|
+
const htmlAttributes = Attribute.getAttributesToRender(node, extensionAttrs);
|
|
8457
|
+
return addNodeView()({
|
|
8458
|
+
editor,
|
|
8459
|
+
node,
|
|
8460
|
+
getPos,
|
|
8461
|
+
decorations,
|
|
8462
|
+
htmlAttributes,
|
|
8463
|
+
extension
|
|
8464
|
+
});
|
|
8465
|
+
};
|
|
8466
|
+
return [extension.name, nodeview];
|
|
8467
|
+
});
|
|
8468
|
+
return Object.fromEntries(entries);
|
|
8469
|
+
}
|
|
8470
|
+
};
|
|
8471
|
+
_ExtensionService_instances = new WeakSet();
|
|
8472
|
+
/**
|
|
8473
|
+
* Install all extensions.
|
|
8474
|
+
* Create extension storage in the editor, attach editor events.
|
|
8475
|
+
*/
|
|
8476
|
+
setupExtensions_fn = function() {
|
|
8477
|
+
for (const extension of this.extensions) {
|
|
8478
|
+
this.editor.extensionStorage[extension.name] = extension.storage;
|
|
8479
|
+
const context = {
|
|
8480
|
+
name: extension.name,
|
|
8481
|
+
options: extension.options,
|
|
8482
|
+
storage: extension.storage,
|
|
8483
|
+
editor: this.editor,
|
|
8484
|
+
type: getSchemaTypeByName(extension.name, this.schema)
|
|
8485
|
+
};
|
|
8486
|
+
if (extension.type === "mark") {
|
|
8487
|
+
const keepOnSplit = callOrGet(getExtensionConfigField(extension, "keepOnSplit", context)) ?? true;
|
|
8488
|
+
if (keepOnSplit) {
|
|
8489
|
+
this.splittableMarks.push(extension.name);
|
|
8490
|
+
}
|
|
8491
|
+
}
|
|
8492
|
+
__privateMethod(this, _ExtensionService_instances, attachEditorEvents_fn).call(this, extension);
|
|
8320
8493
|
}
|
|
8321
|
-
}
|
|
8494
|
+
};
|
|
8495
|
+
/**
|
|
8496
|
+
* Attach editor events to extension
|
|
8497
|
+
* if callbacks are defined in the extension config.
|
|
8498
|
+
* @param extension Extension.
|
|
8499
|
+
*/
|
|
8500
|
+
attachEditorEvents_fn = function(extension) {
|
|
8501
|
+
const context = {
|
|
8502
|
+
name: extension.name,
|
|
8503
|
+
options: extension.options,
|
|
8504
|
+
storage: extension.storage,
|
|
8505
|
+
editor: this.editor,
|
|
8506
|
+
type: getSchemaTypeByName(extension.name, this.schema)
|
|
8507
|
+
};
|
|
8508
|
+
const onBeforeCreate = getExtensionConfigField(extension, "onBeforeCreate", context);
|
|
8509
|
+
const onCreate2 = getExtensionConfigField(extension, "onCreate", context);
|
|
8510
|
+
const onUpdate = getExtensionConfigField(extension, "onUpdate", context);
|
|
8511
|
+
const onSelectionUpdate = getExtensionConfigField(extension, "onSelectionUpdate", context);
|
|
8512
|
+
const onTransaction = getExtensionConfigField(extension, "onTransaction", context);
|
|
8513
|
+
const onFocus = getExtensionConfigField(extension, "onFocus", context);
|
|
8514
|
+
const onBlur = getExtensionConfigField(extension, "onBlur", context);
|
|
8515
|
+
const onDestroy2 = getExtensionConfigField(extension, "onDestroy", context);
|
|
8516
|
+
if (onBeforeCreate) this.editor.on("beforeCreate", onBeforeCreate);
|
|
8517
|
+
if (onCreate2) this.editor.on("create", onCreate2);
|
|
8518
|
+
if (onUpdate) this.editor.on("update", onUpdate);
|
|
8519
|
+
if (onSelectionUpdate) this.editor.on("selectionUpdate", onSelectionUpdate);
|
|
8520
|
+
if (onTransaction) this.editor.on("transaction", onTransaction);
|
|
8521
|
+
if (onFocus) this.editor.on("focus", onFocus);
|
|
8522
|
+
if (onBlur) this.editor.on("blur", onBlur);
|
|
8523
|
+
if (onDestroy2) this.editor.on("destroy", onDestroy2);
|
|
8524
|
+
};
|
|
8525
|
+
let ExtensionService = _ExtensionService;
|
|
8322
8526
|
const first = (commands2) => (props) => {
|
|
8323
8527
|
const items = typeof commands2 === "function" ? commands2(props) : commands2;
|
|
8324
8528
|
for (let i = 0; i < items.length; i += 1) {
|
|
@@ -9355,6 +9559,30 @@ const insertContentAt = (position, value, options) => ({ tr, dispatch, editor })
|
|
|
9355
9559
|
}
|
|
9356
9560
|
return true;
|
|
9357
9561
|
};
|
|
9562
|
+
const undoInputRule = () => ({ state, dispatch }) => {
|
|
9563
|
+
const plugins = state.plugins;
|
|
9564
|
+
for (let i = 0; i < plugins.length; i += 1) {
|
|
9565
|
+
const plugin = plugins[i];
|
|
9566
|
+
let undoable;
|
|
9567
|
+
if (plugin.spec.isInputRules && (undoable = plugin.getState(state))) {
|
|
9568
|
+
if (dispatch) {
|
|
9569
|
+
const tr = state.tr;
|
|
9570
|
+
const toUndo = undoable.transform;
|
|
9571
|
+
for (let j = toUndo.steps.length - 1; j >= 0; j -= 1) {
|
|
9572
|
+
tr.step(toUndo.steps[j].invert(toUndo.docs[j]));
|
|
9573
|
+
}
|
|
9574
|
+
if (undoable.text) {
|
|
9575
|
+
const marks = tr.doc.resolve(undoable.from).marks();
|
|
9576
|
+
tr.replaceWith(undoable.from, undoable.to, state.schema.text(undoable.text, marks));
|
|
9577
|
+
} else {
|
|
9578
|
+
tr.delete(undoable.from, undoable.to);
|
|
9579
|
+
}
|
|
9580
|
+
}
|
|
9581
|
+
return true;
|
|
9582
|
+
}
|
|
9583
|
+
}
|
|
9584
|
+
return false;
|
|
9585
|
+
};
|
|
9358
9586
|
function wrapInList$1(listType, attrs = null) {
|
|
9359
9587
|
return function(state, dispatch) {
|
|
9360
9588
|
let { $from, $to } = state.selection;
|
|
@@ -9684,6 +9912,7 @@ const commands = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProp
|
|
|
9684
9912
|
toggleList,
|
|
9685
9913
|
toggleMark,
|
|
9686
9914
|
toggleNode,
|
|
9915
|
+
undoInputRule,
|
|
9687
9916
|
unsetAllMarks,
|
|
9688
9917
|
unsetMark,
|
|
9689
9918
|
updateAttributes,
|
|
@@ -9713,6 +9942,7 @@ const Keymap = Extension.create({
|
|
|
9713
9942
|
() => commands2.splitBlock()
|
|
9714
9943
|
]);
|
|
9715
9944
|
const handleBackspace = () => this.editor.commands.first(({ commands: commands2, tr }) => [
|
|
9945
|
+
() => commands2.undoInputRule(),
|
|
9716
9946
|
() => {
|
|
9717
9947
|
tr.setMeta("inputType", "deleteContentBackward");
|
|
9718
9948
|
return false;
|
|
@@ -10318,208 +10548,15 @@ const getTrackChangesDecorations = (state, onlyOriginalShown, onlyModifiedShown)
|
|
|
10318
10548
|
class: "track-format-dec normal"
|
|
10319
10549
|
});
|
|
10320
10550
|
decorations.push(decoration);
|
|
10321
|
-
} else {
|
|
10322
|
-
const decoration = Decoration.inline(from2, to, {
|
|
10323
|
-
class: "track-format-dec highlighted"
|
|
10324
|
-
});
|
|
10325
|
-
decorations.push(decoration);
|
|
10326
|
-
}
|
|
10327
|
-
}
|
|
10328
|
-
});
|
|
10329
|
-
return DecorationSet.create(state.doc, decorations);
|
|
10330
|
-
};
|
|
10331
|
-
const replaceStep = ({ state, tr, step, newTr, map: map2, doc: doc2, user, date, originalStep, originalStepIndex }) => {
|
|
10332
|
-
const deletionMarkSchema = state.schema.marks[TrackDeleteMarkName];
|
|
10333
|
-
const deletionMark = findMark(state, deletionMarkSchema, false);
|
|
10334
|
-
const positionTo = deletionMark ? deletionMark.to : step.to;
|
|
10335
|
-
const newStep = new ReplaceStep(
|
|
10336
|
-
positionTo,
|
|
10337
|
-
// We insert all the same steps, but with "from"/"to" both set to "to" in order not to delete content. Mapped as needed.
|
|
10338
|
-
positionTo,
|
|
10339
|
-
step.slice,
|
|
10340
|
-
step.structure
|
|
10341
|
-
);
|
|
10342
|
-
const invertStep = originalStep.invert(tr.docs[originalStepIndex]).map(map2);
|
|
10343
|
-
map2.appendMap(invertStep.getMap());
|
|
10344
|
-
const meta = {};
|
|
10345
|
-
if (newStep) {
|
|
10346
|
-
const trTemp = state.apply(newTr).tr;
|
|
10347
|
-
if (trTemp.maybeStep(newStep).failed) {
|
|
10348
|
-
return;
|
|
10349
|
-
}
|
|
10350
|
-
const mappedNewStepTo = newStep.getMap().map(newStep.to);
|
|
10351
|
-
const insertedMark = markInsertion({
|
|
10352
|
-
tr: trTemp,
|
|
10353
|
-
from: newStep.from,
|
|
10354
|
-
to: mappedNewStepTo,
|
|
10355
|
-
user,
|
|
10356
|
-
date
|
|
10357
|
-
});
|
|
10358
|
-
const condensedStep = new ReplaceStep(newStep.from, newStep.to, trTemp.doc.slice(newStep.from, mappedNewStepTo));
|
|
10359
|
-
newTr.step(condensedStep);
|
|
10360
|
-
const mirrorIndex = map2.maps.length - 1;
|
|
10361
|
-
map2.appendMap(condensedStep.getMap(), mirrorIndex);
|
|
10362
|
-
if (newStep.from !== mappedNewStepTo) {
|
|
10363
|
-
meta.insertedMark = insertedMark;
|
|
10364
|
-
meta.step = condensedStep;
|
|
10365
|
-
}
|
|
10366
|
-
if (!newTr.selection.eq(trTemp.selection)) {
|
|
10367
|
-
newTr.setSelection(trTemp.selection);
|
|
10368
|
-
}
|
|
10369
|
-
}
|
|
10370
|
-
if (step.from !== step.to) {
|
|
10371
|
-
const { deletionMark: deletionMark2, deletionMap, nodes: deletionNodes } = markDeletion({
|
|
10372
|
-
tr: newTr,
|
|
10373
|
-
from: step.from,
|
|
10374
|
-
to: step.to,
|
|
10375
|
-
user,
|
|
10376
|
-
date
|
|
10377
|
-
});
|
|
10378
|
-
meta.deletionNodes = deletionNodes;
|
|
10379
|
-
meta.deletionMark = deletionMark2;
|
|
10380
|
-
map2.appendMapping(deletionMap);
|
|
10381
|
-
}
|
|
10382
|
-
newTr.setMeta(TrackChangesBasePluginKey, meta);
|
|
10383
|
-
};
|
|
10384
|
-
const markWrapping = () => {
|
|
10385
|
-
};
|
|
10386
|
-
const replaceAroundStep = () => {
|
|
10387
|
-
};
|
|
10388
|
-
const addMarkStep = ({ state, tr, step, newTr, map: map2, doc: doc2, user, date }) => {
|
|
10389
|
-
const meta = {};
|
|
10390
|
-
doc2.nodesBetween(step.from, step.to, (node, pos) => {
|
|
10391
|
-
if (!node.isInline) {
|
|
10392
|
-
return;
|
|
10393
|
-
}
|
|
10394
|
-
if (node.marks.find((mark) => mark.type.name === TrackDeleteMarkName)) {
|
|
10395
|
-
return false;
|
|
10396
|
-
}
|
|
10397
|
-
const existingChangeMark = node.marks.find((mark) => [TrackDeleteMarkName, TrackFormatMarkName].includes(mark.type.name));
|
|
10398
|
-
const wid = existingChangeMark ? existingChangeMark.attrs.id : v4();
|
|
10399
|
-
newTr.addMark(Math.max(step.from, pos), Math.min(step.to, pos + node.nodeSize), step.mark);
|
|
10400
|
-
const allowedMarks = ["bold", "italic", "strike", "underline", "textStyle"];
|
|
10401
|
-
if (allowedMarks.includes(step.mark.type.name) && !node.marks.find((mark) => mark.type === step.mark.type)) {
|
|
10402
|
-
const formatChangeMark = node.marks.find((mark) => mark.type.name === TrackFormatMarkName);
|
|
10403
|
-
let after = [];
|
|
10404
|
-
let before = [];
|
|
10405
|
-
if (formatChangeMark) {
|
|
10406
|
-
let foundBefore = formatChangeMark.attrs.before.find((mark) => {
|
|
10407
|
-
if (mark.type === "textStyle") {
|
|
10408
|
-
return mark.type === step.mark.type.name && objectIncludes(mark.attrs, step.mark.attrs);
|
|
10409
|
-
}
|
|
10410
|
-
return mark.type === step.mark.type.name;
|
|
10411
|
-
});
|
|
10412
|
-
if (foundBefore) {
|
|
10413
|
-
before = [...formatChangeMark.attrs.before.filter((mark) => mark.type !== step.mark.type.name)];
|
|
10414
|
-
after = [...formatChangeMark.attrs.after];
|
|
10415
|
-
} else {
|
|
10416
|
-
before = [...formatChangeMark.attrs.before];
|
|
10417
|
-
after = [
|
|
10418
|
-
...formatChangeMark.attrs.after,
|
|
10419
|
-
{
|
|
10420
|
-
type: step.mark.type.name,
|
|
10421
|
-
attrs: { ...step.mark.attrs }
|
|
10422
|
-
}
|
|
10423
|
-
];
|
|
10424
|
-
}
|
|
10425
|
-
} else {
|
|
10426
|
-
before = node.marks.map((mark) => ({
|
|
10427
|
-
type: mark.type.name,
|
|
10428
|
-
attrs: { ...mark.attrs }
|
|
10429
|
-
}));
|
|
10430
|
-
after = [
|
|
10431
|
-
{
|
|
10432
|
-
type: step.mark.type.name,
|
|
10433
|
-
attrs: { ...step.mark.attrs }
|
|
10434
|
-
}
|
|
10435
|
-
];
|
|
10436
|
-
}
|
|
10437
|
-
if (after.length || before.length) {
|
|
10438
|
-
const newFormatMark = state.schema.marks[TrackFormatMarkName].create({
|
|
10439
|
-
id: wid,
|
|
10440
|
-
author: user.name,
|
|
10441
|
-
authorEmail: user.email,
|
|
10442
|
-
date,
|
|
10443
|
-
before,
|
|
10444
|
-
after
|
|
10445
|
-
});
|
|
10446
|
-
newTr.addMark(
|
|
10447
|
-
step.from,
|
|
10448
|
-
// Math.max(step.from, pos)
|
|
10449
|
-
step.to,
|
|
10450
|
-
// Math.min(step.to, pos + node.nodeSize),
|
|
10451
|
-
newFormatMark
|
|
10452
|
-
);
|
|
10453
|
-
meta.formatMark = newFormatMark;
|
|
10454
|
-
meta.step = step;
|
|
10455
|
-
newTr.setMeta(TrackChangesBasePluginKey, meta);
|
|
10456
|
-
} else if (formatChangeMark) {
|
|
10457
|
-
newTr.removeMark(Math.max(step.from, pos), Math.min(step.to, pos + node.nodeSize), formatChangeMark);
|
|
10458
|
-
}
|
|
10459
|
-
}
|
|
10460
|
-
});
|
|
10461
|
-
};
|
|
10462
|
-
const removeMarkStep = ({ state, tr, step, newTr, map: map2, doc: doc2, user, date }) => {
|
|
10463
|
-
const meta = {};
|
|
10464
|
-
doc2.nodesBetween(step.from, step.to, (node, pos) => {
|
|
10465
|
-
if (!node.isInline) {
|
|
10466
|
-
return true;
|
|
10467
|
-
}
|
|
10468
|
-
if (node.marks.find((mark) => mark.type.name === TrackDeleteMarkName)) {
|
|
10469
|
-
return false;
|
|
10470
|
-
}
|
|
10471
|
-
newTr.removeMark(Math.max(step.from, pos), Math.min(step.to, pos + node.nodeSize), step.mark);
|
|
10472
|
-
const allowedMarks = ["bold", "italic", "strike", "underline", "textStyle"];
|
|
10473
|
-
if (allowedMarks.includes(step.mark.type.name) && node.marks.find((mark) => mark.type === step.mark.type)) {
|
|
10474
|
-
const formatChangeMark = node.marks.find((mark) => mark.type.name === TrackFormatMarkName);
|
|
10475
|
-
let after = [];
|
|
10476
|
-
let before = [];
|
|
10477
|
-
if (formatChangeMark) {
|
|
10478
|
-
let foundAfter = formatChangeMark.attrs.after.find((mark) => mark.type === step.mark.type.name);
|
|
10479
|
-
if (foundAfter) {
|
|
10480
|
-
after = [...formatChangeMark.attrs.after.filter((mark) => mark.type !== step.mark.type.name)];
|
|
10481
|
-
before = [...formatChangeMark.attrs.before];
|
|
10482
|
-
} else {
|
|
10483
|
-
after = [...formatChangeMark.attrs.after];
|
|
10484
|
-
before = [
|
|
10485
|
-
...formatChangeMark.attrs.before,
|
|
10486
|
-
{
|
|
10487
|
-
type: step.mark.type.name,
|
|
10488
|
-
attrs: { ...step.mark.attrs }
|
|
10489
|
-
}
|
|
10490
|
-
];
|
|
10491
|
-
}
|
|
10492
|
-
} else {
|
|
10493
|
-
after = [];
|
|
10494
|
-
before = [
|
|
10495
|
-
{
|
|
10496
|
-
type: step.mark.type.name,
|
|
10497
|
-
attrs: { ...step.mark.attrs }
|
|
10498
|
-
}
|
|
10499
|
-
];
|
|
10500
|
-
}
|
|
10501
|
-
if (after.length || before.length) {
|
|
10502
|
-
const newFormatMark = state.schema.marks[TrackFormatMarkName].create({
|
|
10503
|
-
id: v4(),
|
|
10504
|
-
author: user.name,
|
|
10505
|
-
authorEmail: user.email,
|
|
10506
|
-
date,
|
|
10507
|
-
before,
|
|
10508
|
-
after
|
|
10551
|
+
} else {
|
|
10552
|
+
const decoration = Decoration.inline(from2, to, {
|
|
10553
|
+
class: "track-format-dec highlighted"
|
|
10509
10554
|
});
|
|
10510
|
-
|
|
10511
|
-
Math.max(step.from, pos),
|
|
10512
|
-
Math.min(step.to, pos + node.nodeSize),
|
|
10513
|
-
newFormatMark
|
|
10514
|
-
);
|
|
10515
|
-
meta.formatMark = newFormatMark;
|
|
10516
|
-
meta.step = step;
|
|
10517
|
-
newTr.setMeta(TrackChangesBasePluginKey, meta);
|
|
10518
|
-
} else if (formatChangeMark) {
|
|
10519
|
-
newTr.removeMark(Math.max(step.from, pos), Math.min(step.to, pos + node.nodeSize), formatChangeMark);
|
|
10555
|
+
decorations.push(decoration);
|
|
10520
10556
|
}
|
|
10521
10557
|
}
|
|
10522
10558
|
});
|
|
10559
|
+
return DecorationSet.create(state.doc, decorations);
|
|
10523
10560
|
};
|
|
10524
10561
|
const CommentMarkName = "commentMark";
|
|
10525
10562
|
const removeCommentsById = ({ commentId, state, tr, dispatch }) => {
|
|
@@ -10927,7 +10964,7 @@ const CommentsPlugin = Extension.create({
|
|
|
10927
10964
|
update(view, prevState) {
|
|
10928
10965
|
const { state } = view;
|
|
10929
10966
|
const { doc: doc2, tr } = state;
|
|
10930
|
-
if (prevDoc && prevDoc.eq(doc2)) shouldUpdate = true;
|
|
10967
|
+
if (prevDoc && !prevDoc.eq(doc2)) shouldUpdate = true;
|
|
10931
10968
|
if (!shouldUpdate) return;
|
|
10932
10969
|
prevDoc = doc2;
|
|
10933
10970
|
shouldUpdate = false;
|
|
@@ -10961,10 +10998,14 @@ const CommentsPlugin = Extension.create({
|
|
|
10961
10998
|
if (hasActive && activeThreadId !== threadId) return;
|
|
10962
10999
|
decorations.push(deco);
|
|
10963
11000
|
});
|
|
10964
|
-
const
|
|
10965
|
-
|
|
11001
|
+
const trackedChangeMark = findTrackedMark({
|
|
11002
|
+
doc: doc2,
|
|
11003
|
+
from: pos,
|
|
11004
|
+
to: pos + node.nodeSize
|
|
11005
|
+
});
|
|
11006
|
+
if (trackedChangeMark) {
|
|
10966
11007
|
const currentBounds = view.coordsAtPos(pos);
|
|
10967
|
-
const { id } =
|
|
11008
|
+
const { id } = trackedChangeMark.mark.attrs;
|
|
10968
11009
|
updatePosition({
|
|
10969
11010
|
allCommentPositions,
|
|
10970
11011
|
threadId: id,
|
|
@@ -11032,9 +11073,13 @@ const getActiveCommentId = (doc2, selection) => {
|
|
|
11032
11073
|
if ($from.pos !== $to.pos) return;
|
|
11033
11074
|
const nodeAtPos = doc2.nodeAt($from.pos);
|
|
11034
11075
|
if (!nodeAtPos) return;
|
|
11035
|
-
const
|
|
11036
|
-
|
|
11037
|
-
|
|
11076
|
+
const trackedChangeMark = findTrackedMark({
|
|
11077
|
+
doc: doc2,
|
|
11078
|
+
from: $from.pos,
|
|
11079
|
+
to: $to.pos
|
|
11080
|
+
});
|
|
11081
|
+
if (trackedChangeMark) {
|
|
11082
|
+
return trackedChangeMark.mark.attrs.id;
|
|
11038
11083
|
}
|
|
11039
11084
|
const overlaps = [];
|
|
11040
11085
|
let found = false;
|
|
@@ -11071,13 +11116,30 @@ const getActiveCommentId = (doc2, selection) => {
|
|
|
11071
11116
|
const closestCommentMark = closestMarks.find((mark) => mark.type.name === CommentMarkName);
|
|
11072
11117
|
return closestCommentMark?.attrs?.commentId || closestCommentMark?.attrs?.importedId;
|
|
11073
11118
|
};
|
|
11074
|
-
const
|
|
11075
|
-
|
|
11076
|
-
|
|
11077
|
-
|
|
11078
|
-
|
|
11079
|
-
|
|
11080
|
-
|
|
11119
|
+
const findTrackedMark = ({
|
|
11120
|
+
doc: doc2,
|
|
11121
|
+
from: from2,
|
|
11122
|
+
to,
|
|
11123
|
+
offset: offset2 = 1
|
|
11124
|
+
// To get non-inclusive marks.
|
|
11125
|
+
}) => {
|
|
11126
|
+
const startPos = Math.max(from2 - offset2, 0);
|
|
11127
|
+
const endPos = Math.min(to + offset2, doc2.content.size);
|
|
11128
|
+
let markFound;
|
|
11129
|
+
doc2.nodesBetween(startPos, endPos, (node, pos) => {
|
|
11130
|
+
if (!node || node?.nodeSize === void 0) {
|
|
11131
|
+
return;
|
|
11132
|
+
}
|
|
11133
|
+
const mark = node.marks.find((mark2) => TRACK_CHANGE_MARKS.includes(mark2.type.name));
|
|
11134
|
+
if (mark && !markFound) {
|
|
11135
|
+
markFound = {
|
|
11136
|
+
from: pos,
|
|
11137
|
+
to: pos + node.nodeSize,
|
|
11138
|
+
mark
|
|
11139
|
+
};
|
|
11140
|
+
}
|
|
11141
|
+
});
|
|
11142
|
+
return markFound;
|
|
11081
11143
|
};
|
|
11082
11144
|
const handleTrackedChangeTransaction = (trackedChangeMeta, trackedChanges, newEditorState, editor) => {
|
|
11083
11145
|
const {
|
|
@@ -11217,6 +11279,202 @@ function findNode$1(node, predicate) {
|
|
|
11217
11279
|
});
|
|
11218
11280
|
return found;
|
|
11219
11281
|
}
|
|
11282
|
+
const replaceStep = ({ state, tr, step, newTr, map: map2, doc: doc2, user, date, originalStep, originalStepIndex }) => {
|
|
11283
|
+
const deletionMarkSchema = state.schema.marks[TrackDeleteMarkName];
|
|
11284
|
+
const deletionMark = findMark(state, deletionMarkSchema, false);
|
|
11285
|
+
const positionTo = deletionMark ? deletionMark.to : step.to;
|
|
11286
|
+
const newStep = new ReplaceStep(
|
|
11287
|
+
positionTo,
|
|
11288
|
+
// We insert all the same steps, but with "from"/"to" both set to "to" in order not to delete content. Mapped as needed.
|
|
11289
|
+
positionTo,
|
|
11290
|
+
step.slice,
|
|
11291
|
+
step.structure
|
|
11292
|
+
);
|
|
11293
|
+
const invertStep = originalStep.invert(tr.docs[originalStepIndex]).map(map2);
|
|
11294
|
+
map2.appendMap(invertStep.getMap());
|
|
11295
|
+
const meta = {};
|
|
11296
|
+
if (newStep) {
|
|
11297
|
+
const trTemp = state.apply(newTr).tr;
|
|
11298
|
+
if (trTemp.maybeStep(newStep).failed) {
|
|
11299
|
+
return;
|
|
11300
|
+
}
|
|
11301
|
+
const mappedNewStepTo = newStep.getMap().map(newStep.to);
|
|
11302
|
+
const insertedMark = markInsertion({
|
|
11303
|
+
tr: trTemp,
|
|
11304
|
+
from: newStep.from,
|
|
11305
|
+
to: mappedNewStepTo,
|
|
11306
|
+
user,
|
|
11307
|
+
date
|
|
11308
|
+
});
|
|
11309
|
+
const condensedStep = new ReplaceStep(newStep.from, newStep.to, trTemp.doc.slice(newStep.from, mappedNewStepTo));
|
|
11310
|
+
newTr.step(condensedStep);
|
|
11311
|
+
const mirrorIndex = map2.maps.length - 1;
|
|
11312
|
+
map2.appendMap(condensedStep.getMap(), mirrorIndex);
|
|
11313
|
+
if (newStep.from !== mappedNewStepTo) {
|
|
11314
|
+
meta.insertedMark = insertedMark;
|
|
11315
|
+
meta.step = condensedStep;
|
|
11316
|
+
}
|
|
11317
|
+
if (!newTr.selection.eq(trTemp.selection)) {
|
|
11318
|
+
newTr.setSelection(trTemp.selection);
|
|
11319
|
+
}
|
|
11320
|
+
}
|
|
11321
|
+
if (step.from !== step.to) {
|
|
11322
|
+
const { deletionMark: deletionMark2, deletionMap, nodes: deletionNodes } = markDeletion({
|
|
11323
|
+
tr: newTr,
|
|
11324
|
+
from: step.from,
|
|
11325
|
+
to: step.to,
|
|
11326
|
+
user,
|
|
11327
|
+
date
|
|
11328
|
+
});
|
|
11329
|
+
meta.deletionNodes = deletionNodes;
|
|
11330
|
+
meta.deletionMark = deletionMark2;
|
|
11331
|
+
map2.appendMapping(deletionMap);
|
|
11332
|
+
}
|
|
11333
|
+
newTr.setMeta(TrackChangesBasePluginKey, meta);
|
|
11334
|
+
newTr.setMeta(CommentsPluginKey, { type: "force" });
|
|
11335
|
+
};
|
|
11336
|
+
const markWrapping = () => {
|
|
11337
|
+
};
|
|
11338
|
+
const replaceAroundStep = () => {
|
|
11339
|
+
};
|
|
11340
|
+
const addMarkStep = ({ state, tr, step, newTr, map: map2, doc: doc2, user, date }) => {
|
|
11341
|
+
const meta = {};
|
|
11342
|
+
doc2.nodesBetween(step.from, step.to, (node, pos) => {
|
|
11343
|
+
if (!node.isInline) {
|
|
11344
|
+
return;
|
|
11345
|
+
}
|
|
11346
|
+
if (node.marks.find((mark) => mark.type.name === TrackDeleteMarkName)) {
|
|
11347
|
+
return false;
|
|
11348
|
+
}
|
|
11349
|
+
const existingChangeMark = node.marks.find((mark) => [TrackDeleteMarkName, TrackFormatMarkName].includes(mark.type.name));
|
|
11350
|
+
const wid = existingChangeMark ? existingChangeMark.attrs.id : v4();
|
|
11351
|
+
newTr.addMark(Math.max(step.from, pos), Math.min(step.to, pos + node.nodeSize), step.mark);
|
|
11352
|
+
const allowedMarks = ["bold", "italic", "strike", "underline", "textStyle"];
|
|
11353
|
+
if (allowedMarks.includes(step.mark.type.name) && !node.marks.find((mark) => mark.type === step.mark.type)) {
|
|
11354
|
+
const formatChangeMark = node.marks.find((mark) => mark.type.name === TrackFormatMarkName);
|
|
11355
|
+
let after = [];
|
|
11356
|
+
let before = [];
|
|
11357
|
+
if (formatChangeMark) {
|
|
11358
|
+
let foundBefore = formatChangeMark.attrs.before.find((mark) => {
|
|
11359
|
+
if (mark.type === "textStyle") {
|
|
11360
|
+
return mark.type === step.mark.type.name && objectIncludes(mark.attrs, step.mark.attrs);
|
|
11361
|
+
}
|
|
11362
|
+
return mark.type === step.mark.type.name;
|
|
11363
|
+
});
|
|
11364
|
+
if (foundBefore) {
|
|
11365
|
+
before = [...formatChangeMark.attrs.before.filter((mark) => mark.type !== step.mark.type.name)];
|
|
11366
|
+
after = [...formatChangeMark.attrs.after];
|
|
11367
|
+
} else {
|
|
11368
|
+
before = [...formatChangeMark.attrs.before];
|
|
11369
|
+
after = [
|
|
11370
|
+
...formatChangeMark.attrs.after,
|
|
11371
|
+
{
|
|
11372
|
+
type: step.mark.type.name,
|
|
11373
|
+
attrs: { ...step.mark.attrs }
|
|
11374
|
+
}
|
|
11375
|
+
];
|
|
11376
|
+
}
|
|
11377
|
+
} else {
|
|
11378
|
+
before = node.marks.map((mark) => ({
|
|
11379
|
+
type: mark.type.name,
|
|
11380
|
+
attrs: { ...mark.attrs }
|
|
11381
|
+
}));
|
|
11382
|
+
after = [
|
|
11383
|
+
{
|
|
11384
|
+
type: step.mark.type.name,
|
|
11385
|
+
attrs: { ...step.mark.attrs }
|
|
11386
|
+
}
|
|
11387
|
+
];
|
|
11388
|
+
}
|
|
11389
|
+
if (after.length || before.length) {
|
|
11390
|
+
const newFormatMark = state.schema.marks[TrackFormatMarkName].create({
|
|
11391
|
+
id: wid,
|
|
11392
|
+
author: user.name,
|
|
11393
|
+
authorEmail: user.email,
|
|
11394
|
+
date,
|
|
11395
|
+
before,
|
|
11396
|
+
after
|
|
11397
|
+
});
|
|
11398
|
+
newTr.addMark(
|
|
11399
|
+
step.from,
|
|
11400
|
+
// Math.max(step.from, pos)
|
|
11401
|
+
step.to,
|
|
11402
|
+
// Math.min(step.to, pos + node.nodeSize),
|
|
11403
|
+
newFormatMark
|
|
11404
|
+
);
|
|
11405
|
+
meta.formatMark = newFormatMark;
|
|
11406
|
+
meta.step = step;
|
|
11407
|
+
newTr.setMeta(TrackChangesBasePluginKey, meta);
|
|
11408
|
+
newTr.setMeta(CommentsPluginKey, { type: "force" });
|
|
11409
|
+
} else if (formatChangeMark) {
|
|
11410
|
+
newTr.removeMark(Math.max(step.from, pos), Math.min(step.to, pos + node.nodeSize), formatChangeMark);
|
|
11411
|
+
}
|
|
11412
|
+
}
|
|
11413
|
+
});
|
|
11414
|
+
};
|
|
11415
|
+
const removeMarkStep = ({ state, tr, step, newTr, map: map2, doc: doc2, user, date }) => {
|
|
11416
|
+
const meta = {};
|
|
11417
|
+
doc2.nodesBetween(step.from, step.to, (node, pos) => {
|
|
11418
|
+
if (!node.isInline) {
|
|
11419
|
+
return true;
|
|
11420
|
+
}
|
|
11421
|
+
if (node.marks.find((mark) => mark.type.name === TrackDeleteMarkName)) {
|
|
11422
|
+
return false;
|
|
11423
|
+
}
|
|
11424
|
+
newTr.removeMark(Math.max(step.from, pos), Math.min(step.to, pos + node.nodeSize), step.mark);
|
|
11425
|
+
const allowedMarks = ["bold", "italic", "strike", "underline", "textStyle"];
|
|
11426
|
+
if (allowedMarks.includes(step.mark.type.name) && node.marks.find((mark) => mark.type === step.mark.type)) {
|
|
11427
|
+
const formatChangeMark = node.marks.find((mark) => mark.type.name === TrackFormatMarkName);
|
|
11428
|
+
let after = [];
|
|
11429
|
+
let before = [];
|
|
11430
|
+
if (formatChangeMark) {
|
|
11431
|
+
let foundAfter = formatChangeMark.attrs.after.find((mark) => mark.type === step.mark.type.name);
|
|
11432
|
+
if (foundAfter) {
|
|
11433
|
+
after = [...formatChangeMark.attrs.after.filter((mark) => mark.type !== step.mark.type.name)];
|
|
11434
|
+
before = [...formatChangeMark.attrs.before];
|
|
11435
|
+
} else {
|
|
11436
|
+
after = [...formatChangeMark.attrs.after];
|
|
11437
|
+
before = [
|
|
11438
|
+
...formatChangeMark.attrs.before,
|
|
11439
|
+
{
|
|
11440
|
+
type: step.mark.type.name,
|
|
11441
|
+
attrs: { ...step.mark.attrs }
|
|
11442
|
+
}
|
|
11443
|
+
];
|
|
11444
|
+
}
|
|
11445
|
+
} else {
|
|
11446
|
+
after = [];
|
|
11447
|
+
before = [
|
|
11448
|
+
{
|
|
11449
|
+
type: step.mark.type.name,
|
|
11450
|
+
attrs: { ...step.mark.attrs }
|
|
11451
|
+
}
|
|
11452
|
+
];
|
|
11453
|
+
}
|
|
11454
|
+
if (after.length || before.length) {
|
|
11455
|
+
const newFormatMark = state.schema.marks[TrackFormatMarkName].create({
|
|
11456
|
+
id: v4(),
|
|
11457
|
+
author: user.name,
|
|
11458
|
+
authorEmail: user.email,
|
|
11459
|
+
date,
|
|
11460
|
+
before,
|
|
11461
|
+
after
|
|
11462
|
+
});
|
|
11463
|
+
newTr.addMark(
|
|
11464
|
+
Math.max(step.from, pos),
|
|
11465
|
+
Math.min(step.to, pos + node.nodeSize),
|
|
11466
|
+
newFormatMark
|
|
11467
|
+
);
|
|
11468
|
+
meta.formatMark = newFormatMark;
|
|
11469
|
+
meta.step = step;
|
|
11470
|
+
newTr.setMeta(TrackChangesBasePluginKey, meta);
|
|
11471
|
+
newTr.setMeta(CommentsPluginKey, { type: "force" });
|
|
11472
|
+
} else if (formatChangeMark) {
|
|
11473
|
+
newTr.removeMark(Math.max(step.from, pos), Math.min(step.to, pos + node.nodeSize), formatChangeMark);
|
|
11474
|
+
}
|
|
11475
|
+
}
|
|
11476
|
+
});
|
|
11477
|
+
};
|
|
11220
11478
|
const trackedTransaction = ({ tr, state, user }) => {
|
|
11221
11479
|
const onlyInputTypeMeta = ["inputType", "uiEvent", "paste", "pointer"];
|
|
11222
11480
|
const notAllowedMeta = ["historyUndo", "historyRedo", "acceptReject"];
|
|
@@ -11375,6 +11633,7 @@ const _Editor = class _Editor extends EventEmitter {
|
|
|
11375
11633
|
editorProps: {},
|
|
11376
11634
|
parseOptions: {},
|
|
11377
11635
|
coreExtensionOptions: {},
|
|
11636
|
+
enableInputRules: true,
|
|
11378
11637
|
isCommentsEnabled: false,
|
|
11379
11638
|
isNewFile: false,
|
|
11380
11639
|
scale: 1,
|
|
@@ -11813,7 +12072,7 @@ const _Editor = class _Editor extends EventEmitter {
|
|
|
11813
12072
|
* @returns {Y.Doc | undefined} Updated Y.Doc if any, otherwise undefined
|
|
11814
12073
|
*/
|
|
11815
12074
|
processCollaborationMigrations() {
|
|
11816
|
-
console.debug("[checkVersionMigrations] Current editor version", "0.8.
|
|
12075
|
+
console.debug("[checkVersionMigrations] Current editor version", "0.8.12");
|
|
11817
12076
|
if (!this.options.ydoc) return;
|
|
11818
12077
|
const metaMap = this.options.ydoc.getMap("meta");
|
|
11819
12078
|
let docVersion = metaMap.get("version");
|
|
@@ -13206,6 +13465,45 @@ const RunItem = Node.create({
|
|
|
13206
13465
|
};
|
|
13207
13466
|
}
|
|
13208
13467
|
});
|
|
13468
|
+
function wrappingInputRule(config) {
|
|
13469
|
+
return new InputRule({
|
|
13470
|
+
match: config.match,
|
|
13471
|
+
handler: ({
|
|
13472
|
+
state,
|
|
13473
|
+
range,
|
|
13474
|
+
match,
|
|
13475
|
+
chain
|
|
13476
|
+
}) => {
|
|
13477
|
+
const attributes = callOrGet(config.getAttributes, null, match) || {};
|
|
13478
|
+
const tr = state.tr.delete(range.from, range.to);
|
|
13479
|
+
const $start = tr.doc.resolve(range.from);
|
|
13480
|
+
const blockRange = $start.blockRange();
|
|
13481
|
+
const wrapping = blockRange && findWrapping(blockRange, config.type, attributes);
|
|
13482
|
+
if (!wrapping) {
|
|
13483
|
+
return null;
|
|
13484
|
+
}
|
|
13485
|
+
tr.wrap(blockRange, wrapping);
|
|
13486
|
+
if (config.keepMarks && config.editor) {
|
|
13487
|
+
const { selection, storedMarks } = state;
|
|
13488
|
+
const { splittableMarks } = config.editor.extensionService;
|
|
13489
|
+
const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks();
|
|
13490
|
+
if (marks) {
|
|
13491
|
+
const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name));
|
|
13492
|
+
tr.ensureMarks(filteredMarks);
|
|
13493
|
+
}
|
|
13494
|
+
}
|
|
13495
|
+
if (config.keepAttributes) {
|
|
13496
|
+
const nodeType = config.type.name === "bulletList" || config.type.name === "orderedList" ? "listItem" : config.type.name;
|
|
13497
|
+
chain().updateAttributes(nodeType, attributes).run();
|
|
13498
|
+
}
|
|
13499
|
+
const before = tr.doc.resolve(range.from - 1).nodeBefore;
|
|
13500
|
+
if (before && before.type === config.type && canJoin(tr.doc, range.from - 1) && (!config.joinPredicate || config.joinPredicate(match, before))) {
|
|
13501
|
+
tr.join(range.from - 1);
|
|
13502
|
+
}
|
|
13503
|
+
}
|
|
13504
|
+
});
|
|
13505
|
+
}
|
|
13506
|
+
const inputRegex$1 = /^\s*([-+*])\s$/;
|
|
13209
13507
|
const BulletList = Node.create({
|
|
13210
13508
|
name: "bulletList",
|
|
13211
13509
|
group: "block list",
|
|
@@ -13216,7 +13514,8 @@ const BulletList = Node.create({
|
|
|
13216
13514
|
return {
|
|
13217
13515
|
itemTypeName: "listItem",
|
|
13218
13516
|
htmlAttributes: {},
|
|
13219
|
-
keepMarks: true
|
|
13517
|
+
keepMarks: true,
|
|
13518
|
+
keepAttributes: false
|
|
13220
13519
|
};
|
|
13221
13520
|
},
|
|
13222
13521
|
parseDOM() {
|
|
@@ -13254,8 +13553,29 @@ const BulletList = Node.create({
|
|
|
13254
13553
|
return this.editor.commands.toggleBulletList();
|
|
13255
13554
|
}
|
|
13256
13555
|
};
|
|
13257
|
-
}
|
|
13556
|
+
},
|
|
13258
13557
|
// Input rules.
|
|
13558
|
+
addInputRules() {
|
|
13559
|
+
let inputRule = wrappingInputRule({
|
|
13560
|
+
match: inputRegex$1,
|
|
13561
|
+
type: this.type
|
|
13562
|
+
});
|
|
13563
|
+
if (this.options.keepMarks || this.options.keepAttributes) {
|
|
13564
|
+
inputRule = wrappingInputRule({
|
|
13565
|
+
match: inputRegex$1,
|
|
13566
|
+
type: this.type,
|
|
13567
|
+
keepMarks: this.options.keepMarks,
|
|
13568
|
+
keepAttributes: this.options.keepAttributes,
|
|
13569
|
+
getAttributes: () => {
|
|
13570
|
+
return this.editor.getAttributes("textStyle");
|
|
13571
|
+
},
|
|
13572
|
+
editor: this.editor
|
|
13573
|
+
});
|
|
13574
|
+
}
|
|
13575
|
+
return [
|
|
13576
|
+
inputRule
|
|
13577
|
+
];
|
|
13578
|
+
}
|
|
13259
13579
|
});
|
|
13260
13580
|
function orderedListSync(options = {}) {
|
|
13261
13581
|
return new Plugin({
|
|
@@ -13466,6 +13786,7 @@ function buildFirstListItemAttrs({ state, listItems }) {
|
|
|
13466
13786
|
listNumberingType
|
|
13467
13787
|
};
|
|
13468
13788
|
}
|
|
13789
|
+
const inputRegex = /^(\d+)\.\s$/;
|
|
13469
13790
|
const OrderedList = Node.create({
|
|
13470
13791
|
name: "orderedList",
|
|
13471
13792
|
group: "block list",
|
|
@@ -13477,6 +13798,7 @@ const OrderedList = Node.create({
|
|
|
13477
13798
|
itemTypeName: "listItem",
|
|
13478
13799
|
htmlAttributes: {},
|
|
13479
13800
|
keepMarks: true,
|
|
13801
|
+
keepAttributes: false,
|
|
13480
13802
|
listStyleTypes: ["decimal", "lowerAlpha", "lowerRoman"]
|
|
13481
13803
|
};
|
|
13482
13804
|
},
|
|
@@ -13634,6 +13956,28 @@ const OrderedList = Node.create({
|
|
|
13634
13956
|
},
|
|
13635
13957
|
addPmPlugins() {
|
|
13636
13958
|
return [orderedListMarker(), orderedListSync()];
|
|
13959
|
+
},
|
|
13960
|
+
addInputRules() {
|
|
13961
|
+
let inputRule = wrappingInputRule({
|
|
13962
|
+
match: inputRegex,
|
|
13963
|
+
type: this.type,
|
|
13964
|
+
getAttributes: (match) => ({ start: +match[1] }),
|
|
13965
|
+
joinPredicate: (match, node) => node.childCount + node.attrs.start === +match[1]
|
|
13966
|
+
});
|
|
13967
|
+
if (this.options.keepMarks || this.options.keepAttributes) {
|
|
13968
|
+
inputRule = wrappingInputRule({
|
|
13969
|
+
match: inputRegex,
|
|
13970
|
+
type: this.type,
|
|
13971
|
+
keepMarks: this.options.keepMarks,
|
|
13972
|
+
keepAttributes: this.options.keepAttributes,
|
|
13973
|
+
getAttributes: (match) => ({ start: +match[1], ...this.editor.getAttributes("textStyle") }),
|
|
13974
|
+
joinPredicate: (match, node) => node.childCount + node.attrs.start === +match[1],
|
|
13975
|
+
editor: this.editor
|
|
13976
|
+
});
|
|
13977
|
+
}
|
|
13978
|
+
return [
|
|
13979
|
+
inputRule
|
|
13980
|
+
];
|
|
13637
13981
|
}
|
|
13638
13982
|
});
|
|
13639
13983
|
function randomId() {
|
|
@@ -22752,4 +23096,4 @@ export {
|
|
|
22752
23096
|
redoDepth as r,
|
|
22753
23097
|
undoDepth as u
|
|
22754
23098
|
};
|
|
22755
|
-
//# sourceMappingURL=editor-
|
|
23099
|
+
//# sourceMappingURL=editor-aREw3zbp.js.map
|