@harbour-enterprises/superdoc 0.8.9 → 0.8.11

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.
Files changed (47) hide show
  1. package/dist/chunks/{super-editor.es-BMGP0OlF.js → super-editor.es-DIeHC3Si.js} +487 -168
  2. package/dist/chunks/super-editor.es-DIeHC3Si.js.map +1 -0
  3. package/dist/super-editor/chunks/{converter-Bn0H50Ks.js → converter-CVSaF15S.js} +28 -27
  4. package/dist/super-editor/chunks/converter-CVSaF15S.js.map +1 -0
  5. package/dist/super-editor/chunks/{docx-zipper-_duxMt64.js → docx-zipper-BHwY_rz6.js} +2 -2
  6. package/dist/super-editor/chunks/{docx-zipper-_duxMt64.js.map → docx-zipper-BHwY_rz6.js.map} +1 -1
  7. package/dist/super-editor/chunks/{editor-BChxC9A0.js → editor-H6Apbtdi.js} +484 -165
  8. package/dist/super-editor/chunks/editor-H6Apbtdi.js.map +1 -0
  9. package/dist/super-editor/chunks/{toolbar-ypDjwkXK.js → toolbar-D9ELD8Tt.js} +3 -3
  10. package/dist/super-editor/chunks/{toolbar-ypDjwkXK.js.map → toolbar-D9ELD8Tt.js.map} +1 -1
  11. package/dist/super-editor/converter.es.js +2 -2
  12. package/dist/super-editor/core/Editor.d.ts +1 -0
  13. package/dist/super-editor/core/Editor.d.ts.map +1 -1
  14. package/dist/super-editor/core/ExtensionService.d.ts.map +1 -1
  15. package/dist/super-editor/core/InputRule.d.ts +11 -0
  16. package/dist/super-editor/core/InputRule.d.ts.map +1 -0
  17. package/dist/super-editor/core/commands/index.d.ts +1 -0
  18. package/dist/super-editor/core/commands/undoInputRule.d.ts +5 -0
  19. package/dist/super-editor/core/commands/undoInputRule.d.ts.map +1 -0
  20. package/dist/super-editor/core/extensions/keymap.d.ts.map +1 -1
  21. package/dist/super-editor/core/helpers/getHTMLFromFragment.d.ts +2 -0
  22. package/dist/super-editor/core/helpers/getHTMLFromFragment.d.ts.map +1 -0
  23. package/dist/super-editor/core/helpers/getTextContentFromNodes.d.ts +2 -0
  24. package/dist/super-editor/core/helpers/getTextContentFromNodes.d.ts.map +1 -0
  25. package/dist/super-editor/core/helpers/isExtentionRulesEnabled.d.ts +2 -0
  26. package/dist/super-editor/core/helpers/isExtentionRulesEnabled.d.ts.map +1 -0
  27. package/dist/super-editor/core/inputRules/wrappingInputRule.d.ts +9 -0
  28. package/dist/super-editor/core/inputRules/wrappingInputRule.d.ts.map +1 -0
  29. package/dist/super-editor/core/utilities/isRegExp.d.ts +2 -0
  30. package/dist/super-editor/core/utilities/isRegExp.d.ts.map +1 -0
  31. package/dist/super-editor/core/utilities/objectIncludes.d.ts.map +1 -1
  32. package/dist/super-editor/docx-zipper.es.js +2 -2
  33. package/dist/super-editor/editor.es.js +3 -3
  34. package/dist/super-editor/extensions/bullet-list/bullet-list.d.ts.map +1 -1
  35. package/dist/super-editor/extensions/index.d.ts.map +1 -1
  36. package/dist/super-editor/extensions/ordered-list/ordered-list.d.ts.map +1 -1
  37. package/dist/super-editor/file-zipper.es.js +1 -1
  38. package/dist/super-editor/super-editor.es.js +7 -7
  39. package/dist/super-editor/toolbar.es.js +2 -2
  40. package/dist/super-editor.es.js +1 -1
  41. package/dist/superdoc.es.js +3 -3
  42. package/dist/superdoc.umd.js +498 -179
  43. package/dist/superdoc.umd.js.map +1 -1
  44. package/package.json +1 -1
  45. package/dist/chunks/super-editor.es-BMGP0OlF.js.map +0 -1
  46. package/dist/super-editor/chunks/converter-Bn0H50Ks.js.map +0 -1
  47. package/dist/super-editor/chunks/editor-BChxC9A0.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, i as ReplaceStep, k as NodeRange, m as findWrapping, n as TrackDeleteMarkName, q as TrackInsertMarkName, v as v4, s as generateDocxRandomId, t as generateRandom32BitHex, u as TrackFormatMarkName, w as comments_module_events, x as AddMarkStep, y as RemoveMarkStep, z as twipsToLines, B as pixelsToTwips, C as SuperConverter, E as EditorState, G as toKebabCase, H as kebabCase, I as SelectionRange, J as Transform } from "./converter-Bn0H50Ks.js";
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-CVSaF15S.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-_duxMt64.js";
17
+ import { D as DocxZipper } from "./docx-zipper-BHwY_rz6.js";
18
18
  function getMarksFromSelection(state) {
19
19
  const { from: from2, to, empty: empty2 } = state.selection;
20
20
  const marks = [];
@@ -7961,6 +7961,357 @@ let Schema = _Schema;
7961
7961
  function getSchemaTypeByName(name, schema) {
7962
7962
  return schema.nodes[name] || schema.marks[name] || null;
7963
7963
  }
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;
7969
+ });
7970
+ }
7971
+ return enabled;
7972
+ }
7973
+ function chainableEditorState(transaction, state) {
7974
+ let { selection, doc: doc2, storedMarks } = transaction;
7975
+ return {
7976
+ ...state,
7977
+ apply: state.apply.bind(state),
7978
+ applyTransaction: state.applyTransaction.bind(state),
7979
+ plugins: state.plugins,
7980
+ schema: state.schema,
7981
+ reconfigure: state.reconfigure.bind(state),
7982
+ toJSON: state.toJSON.bind(state),
7983
+ get storedMarks() {
7984
+ return storedMarks;
7985
+ },
7986
+ get selection() {
7987
+ return selection;
7988
+ },
7989
+ get doc() {
7990
+ return doc2;
7991
+ },
7992
+ get tr() {
7993
+ selection = transaction.selection;
7994
+ doc2 = transaction.doc;
7995
+ storedMarks = transaction.storedMarks;
7996
+ return transaction;
7997
+ }
7998
+ };
7999
+ }
8000
+ class CommandService {
8001
+ constructor(props) {
8002
+ __publicField(this, "editor");
8003
+ __publicField(this, "rawCommands");
8004
+ this.editor = props.editor;
8005
+ this.rawCommands = this.editor.extensionService.commands;
8006
+ }
8007
+ /**
8008
+ * Static method for creating a service.
8009
+ * @param args Arguments for the constructor.
8010
+ */
8011
+ static create(...args) {
8012
+ return new CommandService(...args);
8013
+ }
8014
+ /**
8015
+ * Get editor state.
8016
+ */
8017
+ get state() {
8018
+ return this.editor.state;
8019
+ }
8020
+ /**
8021
+ * Get all commands with wrapped command method.
8022
+ */
8023
+ get commands() {
8024
+ const { editor, state } = this;
8025
+ const { view } = editor;
8026
+ const { tr } = state;
8027
+ const props = this.createProps(tr);
8028
+ const entries = Object.entries(this.rawCommands).map(([name, command2]) => {
8029
+ const method = (...args) => {
8030
+ const fn2 = command2(...args)(props);
8031
+ if (!tr.getMeta("preventDispatch")) {
8032
+ view.dispatch(tr);
8033
+ }
8034
+ return fn2;
8035
+ };
8036
+ return [name, method];
8037
+ });
8038
+ return Object.fromEntries(entries);
8039
+ }
8040
+ /**
8041
+ * Create a chain of commands to call multiple commands at once.
8042
+ */
8043
+ get chain() {
8044
+ return () => this.createChain();
8045
+ }
8046
+ /**
8047
+ * Check if a command or a chain of commands can be executed. Without executing it.
8048
+ */
8049
+ get can() {
8050
+ return () => this.createCan();
8051
+ }
8052
+ /**
8053
+ * Creates a chain of commands.
8054
+ * @param startTr Start transaction.
8055
+ * @param shouldDispatch Should dispatch or not.
8056
+ */
8057
+ createChain(startTr, shouldDispatch = true) {
8058
+ const { editor, state, rawCommands } = this;
8059
+ const { view } = editor;
8060
+ const callbacks = [];
8061
+ const hasStartTr = !!startTr;
8062
+ const tr = startTr || state.tr;
8063
+ const run2 = () => {
8064
+ if (!hasStartTr && shouldDispatch && !tr.getMeta("preventDispatch")) {
8065
+ view.dispatch(tr);
8066
+ }
8067
+ return callbacks.every((cb) => cb === true);
8068
+ };
8069
+ const entries = Object.entries(rawCommands).map(([name, command2]) => {
8070
+ const chainedCommand = (...args) => {
8071
+ const props = this.createProps(tr, shouldDispatch);
8072
+ const callback = command2(...args)(props);
8073
+ callbacks.push(callback);
8074
+ return chain;
8075
+ };
8076
+ return [name, chainedCommand];
8077
+ });
8078
+ const chain = {
8079
+ ...Object.fromEntries(entries),
8080
+ run: run2
8081
+ };
8082
+ return chain;
8083
+ }
8084
+ /**
8085
+ * Creates a can check for commands.
8086
+ * @param startTr Start transaction.
8087
+ */
8088
+ createCan(startTr) {
8089
+ const { rawCommands, state } = this;
8090
+ const dispatch = false;
8091
+ const tr = startTr || state.tr;
8092
+ const props = this.createProps(tr, dispatch);
8093
+ const commands2 = Object.fromEntries(
8094
+ Object.entries(rawCommands).map(([name, command2]) => {
8095
+ return [name, (...args) => command2(...args)({ ...props, dispatch: void 0 })];
8096
+ })
8097
+ );
8098
+ return {
8099
+ ...commands2,
8100
+ chain: () => this.createChain(tr, dispatch)
8101
+ };
8102
+ }
8103
+ /**
8104
+ * Creates default props for the command method.
8105
+ * @param {*} tr Transaction.
8106
+ * @param {*} shouldDispatch Check if should dispatch.
8107
+ * @returns Object with props.
8108
+ */
8109
+ createProps(tr, shouldDispatch = true) {
8110
+ const { editor, state, rawCommands } = this;
8111
+ const { view } = editor;
8112
+ const props = {
8113
+ tr,
8114
+ editor,
8115
+ view,
8116
+ state: chainableEditorState(tr, state),
8117
+ dispatch: shouldDispatch ? () => void 0 : void 0,
8118
+ chain: () => this.createChain(tr, shouldDispatch),
8119
+ can: () => this.createCan(tr),
8120
+ get commands() {
8121
+ return Object.fromEntries(
8122
+ Object.entries(rawCommands).map(([name, command2]) => {
8123
+ return [name, (...args) => command2(...args)(props)];
8124
+ })
8125
+ );
8126
+ }
8127
+ };
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
+ };
7964
8315
  const _ExtensionService = class _ExtensionService {
7965
8316
  constructor(extensions, userExtensions, editor) {
7966
8317
  __privateAdd(this, _ExtensionService_instances);
@@ -8045,6 +8396,7 @@ const _ExtensionService = class _ExtensionService {
8045
8396
  get plugins() {
8046
8397
  const editor = this.editor;
8047
8398
  const extensions = _ExtensionService.sortByPriority([...this.extensions].reverse());
8399
+ const inputRules = [];
8048
8400
  const allPlugins = extensions.map((extension) => {
8049
8401
  const context = {
8050
8402
  name: extension.name,
@@ -8063,6 +8415,10 @@ const _ExtensionService = class _ExtensionService {
8063
8415
  bindingsObject = { ...Object.fromEntries(entries) };
8064
8416
  }
8065
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
+ }
8066
8422
  const addPmPlugins = getExtensionConfigField(extension, "addPmPlugins", context);
8067
8423
  if (addPmPlugins) {
8068
8424
  const pmPlugins = addPmPlugins();
@@ -8070,7 +8426,13 @@ const _ExtensionService = class _ExtensionService {
8070
8426
  }
8071
8427
  return plugins;
8072
8428
  }).flat();
8073
- return [...allPlugins];
8429
+ return [
8430
+ inputRulesPlugin({
8431
+ editor,
8432
+ rules: inputRules
8433
+ }),
8434
+ ...allPlugins
8435
+ ];
8074
8436
  }
8075
8437
  /**
8076
8438
  * Get all node views from the extensions.
@@ -8161,164 +8523,6 @@ attachEditorEvents_fn = function(extension) {
8161
8523
  if (onDestroy2) this.editor.on("destroy", onDestroy2);
8162
8524
  };
8163
8525
  let ExtensionService = _ExtensionService;
8164
- function chainableEditorState(transaction, state) {
8165
- let { selection, doc: doc2, storedMarks } = transaction;
8166
- return {
8167
- ...state,
8168
- apply: state.apply.bind(state),
8169
- applyTransaction: state.applyTransaction.bind(state),
8170
- plugins: state.plugins,
8171
- schema: state.schema,
8172
- reconfigure: state.reconfigure.bind(state),
8173
- toJSON: state.toJSON.bind(state),
8174
- get storedMarks() {
8175
- return storedMarks;
8176
- },
8177
- get selection() {
8178
- return selection;
8179
- },
8180
- get doc() {
8181
- return doc2;
8182
- },
8183
- get tr() {
8184
- selection = transaction.selection;
8185
- doc2 = transaction.doc;
8186
- storedMarks = transaction.storedMarks;
8187
- return transaction;
8188
- }
8189
- };
8190
- }
8191
- class CommandService {
8192
- constructor(props) {
8193
- __publicField(this, "editor");
8194
- __publicField(this, "rawCommands");
8195
- this.editor = props.editor;
8196
- this.rawCommands = this.editor.extensionService.commands;
8197
- }
8198
- /**
8199
- * Static method for creating a service.
8200
- * @param args Arguments for the constructor.
8201
- */
8202
- static create(...args) {
8203
- return new CommandService(...args);
8204
- }
8205
- /**
8206
- * Get editor state.
8207
- */
8208
- get state() {
8209
- return this.editor.state;
8210
- }
8211
- /**
8212
- * Get all commands with wrapped command method.
8213
- */
8214
- get commands() {
8215
- const { editor, state } = this;
8216
- const { view } = editor;
8217
- const { tr } = state;
8218
- const props = this.createProps(tr);
8219
- const entries = Object.entries(this.rawCommands).map(([name, command2]) => {
8220
- const method = (...args) => {
8221
- const fn2 = command2(...args)(props);
8222
- if (!tr.getMeta("preventDispatch")) {
8223
- view.dispatch(tr);
8224
- }
8225
- return fn2;
8226
- };
8227
- return [name, method];
8228
- });
8229
- return Object.fromEntries(entries);
8230
- }
8231
- /**
8232
- * Create a chain of commands to call multiple commands at once.
8233
- */
8234
- get chain() {
8235
- return () => this.createChain();
8236
- }
8237
- /**
8238
- * Check if a command or a chain of commands can be executed. Without executing it.
8239
- */
8240
- get can() {
8241
- return () => this.createCan();
8242
- }
8243
- /**
8244
- * Creates a chain of commands.
8245
- * @param startTr Start transaction.
8246
- * @param shouldDispatch Should dispatch or not.
8247
- */
8248
- createChain(startTr, shouldDispatch = true) {
8249
- const { editor, state, rawCommands } = this;
8250
- const { view } = editor;
8251
- const callbacks = [];
8252
- const hasStartTr = !!startTr;
8253
- const tr = startTr || state.tr;
8254
- const run = () => {
8255
- if (!hasStartTr && shouldDispatch && !tr.getMeta("preventDispatch")) {
8256
- view.dispatch(tr);
8257
- }
8258
- return callbacks.every((cb) => cb === true);
8259
- };
8260
- const entries = Object.entries(rawCommands).map(([name, command2]) => {
8261
- const chainedCommand = (...args) => {
8262
- const props = this.createProps(tr, shouldDispatch);
8263
- const callback = command2(...args)(props);
8264
- callbacks.push(callback);
8265
- return chain;
8266
- };
8267
- return [name, chainedCommand];
8268
- });
8269
- const chain = {
8270
- ...Object.fromEntries(entries),
8271
- run
8272
- };
8273
- return chain;
8274
- }
8275
- /**
8276
- * Creates a can check for commands.
8277
- * @param startTr Start transaction.
8278
- */
8279
- createCan(startTr) {
8280
- const { rawCommands, state } = this;
8281
- const dispatch = false;
8282
- const tr = startTr || state.tr;
8283
- const props = this.createProps(tr, dispatch);
8284
- const commands2 = Object.fromEntries(
8285
- Object.entries(rawCommands).map(([name, command2]) => {
8286
- return [name, (...args) => command2(...args)({ ...props, dispatch: void 0 })];
8287
- })
8288
- );
8289
- return {
8290
- ...commands2,
8291
- chain: () => this.createChain(tr, dispatch)
8292
- };
8293
- }
8294
- /**
8295
- * Creates default props for the command method.
8296
- * @param {*} tr Transaction.
8297
- * @param {*} shouldDispatch Check if should dispatch.
8298
- * @returns Object with props.
8299
- */
8300
- createProps(tr, shouldDispatch = true) {
8301
- const { editor, state, rawCommands } = this;
8302
- const { view } = editor;
8303
- const props = {
8304
- tr,
8305
- editor,
8306
- view,
8307
- state: chainableEditorState(tr, state),
8308
- dispatch: shouldDispatch ? () => void 0 : void 0,
8309
- chain: () => this.createChain(tr, shouldDispatch),
8310
- can: () => this.createCan(tr),
8311
- get commands() {
8312
- return Object.fromEntries(
8313
- Object.entries(rawCommands).map(([name, command2]) => {
8314
- return [name, (...args) => command2(...args)(props)];
8315
- })
8316
- );
8317
- }
8318
- };
8319
- return props;
8320
- }
8321
- }
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;
@@ -11375,6 +11605,7 @@ const _Editor = class _Editor extends EventEmitter {
11375
11605
  editorProps: {},
11376
11606
  parseOptions: {},
11377
11607
  coreExtensionOptions: {},
11608
+ enableInputRules: true,
11378
11609
  isCommentsEnabled: false,
11379
11610
  isNewFile: false,
11380
11611
  scale: 1,
@@ -11813,7 +12044,7 @@ const _Editor = class _Editor extends EventEmitter {
11813
12044
  * @returns {Y.Doc | undefined} Updated Y.Doc if any, otherwise undefined
11814
12045
  */
11815
12046
  processCollaborationMigrations() {
11816
- console.debug("[checkVersionMigrations] Current editor version", "0.8.9");
12047
+ console.debug("[checkVersionMigrations] Current editor version", "0.8.11");
11817
12048
  if (!this.options.ydoc) return;
11818
12049
  const metaMap = this.options.ydoc.getMap("meta");
11819
12050
  let docVersion = metaMap.get("version");
@@ -13206,6 +13437,45 @@ const RunItem = Node.create({
13206
13437
  };
13207
13438
  }
13208
13439
  });
13440
+ function wrappingInputRule(config) {
13441
+ return new InputRule({
13442
+ match: config.match,
13443
+ handler: ({
13444
+ state,
13445
+ range,
13446
+ match,
13447
+ chain
13448
+ }) => {
13449
+ const attributes = callOrGet(config.getAttributes, null, match) || {};
13450
+ const tr = state.tr.delete(range.from, range.to);
13451
+ const $start = tr.doc.resolve(range.from);
13452
+ const blockRange = $start.blockRange();
13453
+ const wrapping = blockRange && findWrapping(blockRange, config.type, attributes);
13454
+ if (!wrapping) {
13455
+ return null;
13456
+ }
13457
+ tr.wrap(blockRange, wrapping);
13458
+ if (config.keepMarks && config.editor) {
13459
+ const { selection, storedMarks } = state;
13460
+ const { splittableMarks } = config.editor.extensionService;
13461
+ const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks();
13462
+ if (marks) {
13463
+ const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name));
13464
+ tr.ensureMarks(filteredMarks);
13465
+ }
13466
+ }
13467
+ if (config.keepAttributes) {
13468
+ const nodeType = config.type.name === "bulletList" || config.type.name === "orderedList" ? "listItem" : config.type.name;
13469
+ chain().updateAttributes(nodeType, attributes).run();
13470
+ }
13471
+ const before = tr.doc.resolve(range.from - 1).nodeBefore;
13472
+ if (before && before.type === config.type && canJoin(tr.doc, range.from - 1) && (!config.joinPredicate || config.joinPredicate(match, before))) {
13473
+ tr.join(range.from - 1);
13474
+ }
13475
+ }
13476
+ });
13477
+ }
13478
+ const inputRegex$1 = /^\s*([-+*])\s$/;
13209
13479
  const BulletList = Node.create({
13210
13480
  name: "bulletList",
13211
13481
  group: "block list",
@@ -13216,7 +13486,8 @@ const BulletList = Node.create({
13216
13486
  return {
13217
13487
  itemTypeName: "listItem",
13218
13488
  htmlAttributes: {},
13219
- keepMarks: true
13489
+ keepMarks: true,
13490
+ keepAttributes: false
13220
13491
  };
13221
13492
  },
13222
13493
  parseDOM() {
@@ -13254,8 +13525,29 @@ const BulletList = Node.create({
13254
13525
  return this.editor.commands.toggleBulletList();
13255
13526
  }
13256
13527
  };
13257
- }
13528
+ },
13258
13529
  // Input rules.
13530
+ addInputRules() {
13531
+ let inputRule = wrappingInputRule({
13532
+ match: inputRegex$1,
13533
+ type: this.type
13534
+ });
13535
+ if (this.options.keepMarks || this.options.keepAttributes) {
13536
+ inputRule = wrappingInputRule({
13537
+ match: inputRegex$1,
13538
+ type: this.type,
13539
+ keepMarks: this.options.keepMarks,
13540
+ keepAttributes: this.options.keepAttributes,
13541
+ getAttributes: () => {
13542
+ return this.editor.getAttributes("textStyle");
13543
+ },
13544
+ editor: this.editor
13545
+ });
13546
+ }
13547
+ return [
13548
+ inputRule
13549
+ ];
13550
+ }
13259
13551
  });
13260
13552
  function orderedListSync(options = {}) {
13261
13553
  return new Plugin({
@@ -13466,6 +13758,7 @@ function buildFirstListItemAttrs({ state, listItems }) {
13466
13758
  listNumberingType
13467
13759
  };
13468
13760
  }
13761
+ const inputRegex = /^(\d+)\.\s$/;
13469
13762
  const OrderedList = Node.create({
13470
13763
  name: "orderedList",
13471
13764
  group: "block list",
@@ -13477,6 +13770,7 @@ const OrderedList = Node.create({
13477
13770
  itemTypeName: "listItem",
13478
13771
  htmlAttributes: {},
13479
13772
  keepMarks: true,
13773
+ keepAttributes: false,
13480
13774
  listStyleTypes: ["decimal", "lowerAlpha", "lowerRoman"]
13481
13775
  };
13482
13776
  },
@@ -13634,6 +13928,28 @@ const OrderedList = Node.create({
13634
13928
  },
13635
13929
  addPmPlugins() {
13636
13930
  return [orderedListMarker(), orderedListSync()];
13931
+ },
13932
+ addInputRules() {
13933
+ let inputRule = wrappingInputRule({
13934
+ match: inputRegex,
13935
+ type: this.type,
13936
+ getAttributes: (match) => ({ start: +match[1] }),
13937
+ joinPredicate: (match, node) => node.childCount + node.attrs.start === +match[1]
13938
+ });
13939
+ if (this.options.keepMarks || this.options.keepAttributes) {
13940
+ inputRule = wrappingInputRule({
13941
+ match: inputRegex,
13942
+ type: this.type,
13943
+ keepMarks: this.options.keepMarks,
13944
+ keepAttributes: this.options.keepAttributes,
13945
+ getAttributes: (match) => ({ start: +match[1], ...this.editor.getAttributes("textStyle") }),
13946
+ joinPredicate: (match, node) => node.childCount + node.attrs.start === +match[1],
13947
+ editor: this.editor
13948
+ });
13949
+ }
13950
+ return [
13951
+ inputRule
13952
+ ];
13637
13953
  }
13638
13954
  });
13639
13955
  function randomId() {
@@ -22636,6 +22952,7 @@ const onImageLoad = (editor) => {
22636
22952
  const getRichTextExtensions = () => {
22637
22953
  return [
22638
22954
  Bold,
22955
+ BulletList,
22639
22956
  Color,
22640
22957
  Document,
22641
22958
  FontFamily,
@@ -22643,8 +22960,10 @@ const getRichTextExtensions = () => {
22643
22960
  History,
22644
22961
  Heading,
22645
22962
  Italic,
22963
+ ListItem,
22646
22964
  LineHeight,
22647
22965
  Link,
22966
+ OrderedList,
22648
22967
  Paragraph,
22649
22968
  LineBreak,
22650
22969
  HardBreak,
@@ -22749,4 +23068,4 @@ export {
22749
23068
  redoDepth as r,
22750
23069
  undoDepth as u
22751
23070
  };
22752
- //# sourceMappingURL=editor-BChxC9A0.js.map
23071
+ //# sourceMappingURL=editor-H6Apbtdi.js.map