@kungal/editor-core 0.25.2 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,58 @@
1
1
  # @kungal/editor-core
2
2
 
3
+ ## 0.27.0
4
+
5
+ ### Minor Changes
6
+
7
+ - ac86c0a: Add a heading-outline API for building a table of contents (TOC).
8
+
9
+ A host (e.g. a desktop editor with a left-side outline) can now render its own TOC
10
+ and navigate the editor, without reaching into editor internals:
11
+
12
+ - **`@update:headings`** on `<KunEditor>` — emits the ordered outline
13
+ (`KunHeading[]` = `{ level, text }`) whenever the content changes.
14
+ - **`ref.scrollToHeading(index)`** — scrolls to that heading in the _current_ view
15
+ and places the caret there: the WYSIWYG heading in wysiwyg mode, the CodeMirror
16
+ heading line in source/split mode (so a click navigates the editable pane).
17
+ - **editor-core** exports the pure `parseHeadings(markdown)` (and `KunHeading`) it's
18
+ built on — usable server-side too. Parses ATX headings, skipping code fences.
19
+
20
+ The TOC's styling, colour, indentation and layout (e.g. reserving space on the
21
+ left of the split editor) are entirely the host's — the editor only exposes the
22
+ data + navigation, matching the headless design.
23
+
24
+ Verified in a new docs example (`/examples/toc`): the outline tracks the content;
25
+ clicking an item scrolls + carets to that heading in wysiwyg (scrollTop 0→386,
26
+ caret in the target) and in source (CodeMirror scrolled, cursor on `## …`); new
27
+ `parseHeadings` unit tests pass; 0 console errors.
28
+
29
+ ## 0.26.0
30
+
31
+ ### Minor Changes
32
+
33
+ - 945708d: Add an insert-link feature (click to add a URL).
34
+
35
+ The `link` mark already existed (so `[text](url)` round-trips and pasted URLs
36
+ autolink), but there was no click-to-insert UI. Now there is:
37
+
38
+ - **editor-core**: `insertLinkCommand` (`{ href, text? }`) — applies the link mark
39
+ to the selection, or inserts linked text on an empty selection; clears the
40
+ stored mark afterwards. Re-exported from `@kungal/editor-core/preset`.
41
+ - **editor-vue**: `KunEditorToolbarApi.insertLink(payload)`; a `link` button in the
42
+ default toolbar and the selection bubble (both default-on); `'link'` added to
43
+ `KunToolbarItem` and `KunSelectionItem`. Headless UI prompts for the URL.
44
+ - **editor-nuxt**: `<KunEditorToolbar>` gains a `link` button — a KunPopover with a
45
+ KunInput for the URL.
46
+
47
+ A link is a **mark** (`[text](url)`), deliberately distinct from the custom-NODE
48
+ embeds (mention / quote). A future "article card" or custom component would be a
49
+ node like those (schema + toUrl/fromUrl), not this — a separate mechanism.
50
+
51
+ Verified in the docs production build: the KunUI toolbar popover wraps a selection
52
+ (`[…](https://example.com)`); the selection bubble does too
53
+ (`[linktext](https://kun.com)`); 4 new core tests (wrap / insert / autolink
54
+ fallback / blank-href no-op) pass; 0 console errors.
55
+
3
56
  ## 0.25.2
4
57
 
5
58
  ## 0.25.1
@@ -0,0 +1,30 @@
1
+ // src/outline.ts
2
+ var FENCE = /^\s{0,3}(?:```|~~~)/;
3
+ var ATX = /^ {0,3}(#{1,6})\s+(.+?)\s*#*\s*$/;
4
+ var parseHeadings = (markdown) => {
5
+ const out = [];
6
+ let inFence = false;
7
+ for (const line of markdown.split("\n")) {
8
+ if (FENCE.test(line)) {
9
+ inFence = !inFence;
10
+ continue;
11
+ }
12
+ if (inFence) {
13
+ continue;
14
+ }
15
+ const m = line.match(ATX);
16
+ if (m) {
17
+ out.push({ level: m[1].length, text: m[2].trim() });
18
+ }
19
+ }
20
+ return out;
21
+ };
22
+
23
+ // src/index.ts
24
+ var MENTION_SCHEME = "kungal-user:";
25
+ var QUOTE_SCHEME = "kungal-reply:";
26
+ var KUN_EDITOR_CORE_VERSION = "0.0.0";
27
+
28
+ export { KUN_EDITOR_CORE_VERSION, MENTION_SCHEME, QUOTE_SCHEME, parseHeadings };
29
+ //# sourceMappingURL=chunk-PT42ZQGO.js.map
30
+ //# sourceMappingURL=chunk-PT42ZQGO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/outline.ts","../src/index.ts"],"names":[],"mappings":";AAgBA,IAAM,KAAA,GAAQ,qBAAA;AACd,IAAM,GAAA,GAAM,kCAAA;AAGL,IAAM,aAAA,GAAgB,CAAC,QAAA,KAAmC;AAC/D,EAAA,MAAM,MAAoB,EAAC;AAC3B,EAAA,IAAI,OAAA,GAAU,KAAA;AACd,EAAA,KAAA,MAAW,IAAA,IAAQ,QAAA,CAAS,KAAA,CAAM,IAAI,CAAA,EAAG;AACvC,IAAA,IAAI,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,EAAG;AACpB,MAAA,OAAA,GAAU,CAAC,OAAA;AACX,MAAA;AAAA,IACF;AACA,IAAA,IAAI,OAAA,EAAS;AACX,MAAA;AAAA,IACF;AACA,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AACxB,IAAA,IAAI,CAAA,EAAG;AACL,MAAA,GAAA,CAAI,IAAA,CAAK,EAAE,KAAA,EAAO,CAAA,CAAE,CAAC,CAAA,CAAG,MAAA,EAAQ,IAAA,EAAM,CAAA,CAAE,CAAC,CAAA,CAAG,IAAA,IAAQ,CAAA;AAAA,IACtD;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;;;ACtBO,IAAM,cAAA,GAAiB;AAMvB,IAAM,YAAA,GAAe;AAErB,IAAM,uBAAA,GAA0B","file":"chunk-PT42ZQGO.js","sourcesContent":["// Heading outline (table-of-contents) parsing — pure, zero-dep, so it lives in\n// the light main entry (a host, or the server, can build a TOC without pulling in\n// @milkdown/kit). Parses ATX headings (`#`…`######`) — what the toolbar produces\n// — and skips fenced code blocks so a `# comment` inside ``` isn't mistaken for a\n// heading. Setext headings (underlined) are intentionally not parsed.\n//\n// The result is an ordered list; a UI renders it and, on click, calls the\n// editor's `scrollToHeading(index)` with the item's array index.\n\nexport interface KunHeading {\n /** Heading level 1–6. */\n level: number\n /** The heading's text (trailing `#` closers stripped). */\n text: string\n}\n\nconst FENCE = /^\\s{0,3}(?:```|~~~)/\nconst ATX = /^ {0,3}(#{1,6})\\s+(.+?)\\s*#*\\s*$/\n\n/** Parse the ordered ATX-heading outline from a markdown string. */\nexport const parseHeadings = (markdown: string): KunHeading[] => {\n const out: KunHeading[] = []\n let inFence = false\n for (const line of markdown.split('\\n')) {\n if (FENCE.test(line)) {\n inFence = !inFence\n continue\n }\n if (inFence) {\n continue\n }\n const m = line.match(ATX)\n if (m) {\n out.push({ level: m[1]!.length, text: m[2]!.trim() })\n }\n }\n return out\n}\n","// @kungal/editor-core — public entry.\n//\n// STATUS: scaffold. The adapter contracts (the stable public surface) are\n// defined and exported now; the Milkdown plugin ports land incrementally per\n// docs/architecture.md § migration. Consumers should code against the types\n// below — those are the contract that will not churn as plugins move over.\n\nexport * from './types'\n\n// Heading outline (TOC) parsing — pure, so it's here in the light entry.\nexport * from './outline'\n\n// Markdown scheme used to encode an @mention as a plain link the server can\n// render + parse: `[@name](kungal-user:<id>)`. Lives here (not the plugin) so\n// hosts and the server can share the exact string. See ./plugins/mention.\nexport const MENTION_SCHEME = 'kungal-user:'\n\n// Markdown scheme for an inline reference (reply quote): `[label](kungal-reply:<refId>)`.\n// Like MENTION_SCHEME, shared with the server renderer so both agree on the\n// exact string. The reference is opaque here — the host decides what `refId` /\n// `label` mean (see docs/architecture.md § the reply-quote question, option 1).\nexport const QUOTE_SCHEME = 'kungal-reply:'\n\nexport const KUN_EDITOR_CORE_VERSION = '0.0.0'\n\n// ── The Milkdown plugins live in the `./preset` subpath ──────────────────────\n// This main entry stays light on purpose: types + MENTION_SCHEME, ZERO runtime\n// deps, so the server (which only needs the @mention scheme string) can import\n// it without installing @milkdown/kit / katex / codemirror.\n//\n// The composed Milkdown bundle and the individual plugin factories are exported\n// from `@kungal/editor-core/preset` (they pull in the peer deps):\n//\n// import { createKunEditorPlugins } from '@kungal/editor-core/preset'\n//\n// P1 landed (docs/architecture.md § migration): spoiler, katex, code-block,\n// stop-link — each a factory (createXxxPlugin), never a host-bound singleton.\n// P2 adds the adapter-driven plugins (upload / mention / sticker).\n"]}
package/dist/index.cjs CHANGED
@@ -1,5 +1,27 @@
1
1
  'use strict';
2
2
 
3
+ // src/outline.ts
4
+ var FENCE = /^\s{0,3}(?:```|~~~)/;
5
+ var ATX = /^ {0,3}(#{1,6})\s+(.+?)\s*#*\s*$/;
6
+ var parseHeadings = (markdown) => {
7
+ const out = [];
8
+ let inFence = false;
9
+ for (const line of markdown.split("\n")) {
10
+ if (FENCE.test(line)) {
11
+ inFence = !inFence;
12
+ continue;
13
+ }
14
+ if (inFence) {
15
+ continue;
16
+ }
17
+ const m = line.match(ATX);
18
+ if (m) {
19
+ out.push({ level: m[1].length, text: m[2].trim() });
20
+ }
21
+ }
22
+ return out;
23
+ };
24
+
3
25
  // src/index.ts
4
26
  var MENTION_SCHEME = "kungal-user:";
5
27
  var QUOTE_SCHEME = "kungal-reply:";
@@ -8,5 +30,6 @@ var KUN_EDITOR_CORE_VERSION = "0.0.0";
8
30
  exports.KUN_EDITOR_CORE_VERSION = KUN_EDITOR_CORE_VERSION;
9
31
  exports.MENTION_SCHEME = MENTION_SCHEME;
10
32
  exports.QUOTE_SCHEME = QUOTE_SCHEME;
33
+ exports.parseHeadings = parseHeadings;
11
34
  //# sourceMappingURL=index.cjs.map
12
35
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;AAYO,IAAM,cAAA,GAAiB;AAMvB,IAAM,YAAA,GAAe;AAErB,IAAM,uBAAA,GAA0B","file":"index.cjs","sourcesContent":["// @kungal/editor-core — public entry.\n//\n// STATUS: scaffold. The adapter contracts (the stable public surface) are\n// defined and exported now; the Milkdown plugin ports land incrementally per\n// docs/architecture.md § migration. Consumers should code against the types\n// below — those are the contract that will not churn as plugins move over.\n\nexport * from './types'\n\n// Markdown scheme used to encode an @mention as a plain link the server can\n// render + parse: `[@name](kungal-user:<id>)`. Lives here (not the plugin) so\n// hosts and the server can share the exact string. See ./plugins/mention.\nexport const MENTION_SCHEME = 'kungal-user:'\n\n// Markdown scheme for an inline reference (reply quote): `[label](kungal-reply:<refId>)`.\n// Like MENTION_SCHEME, shared with the server renderer so both agree on the\n// exact string. The reference is opaque here — the host decides what `refId` /\n// `label` mean (see docs/architecture.md § the reply-quote question, option 1).\nexport const QUOTE_SCHEME = 'kungal-reply:'\n\nexport const KUN_EDITOR_CORE_VERSION = '0.0.0'\n\n// ── The Milkdown plugins live in the `./preset` subpath ──────────────────────\n// This main entry stays light on purpose: types + MENTION_SCHEME, ZERO runtime\n// deps, so the server (which only needs the @mention scheme string) can import\n// it without installing @milkdown/kit / katex / codemirror.\n//\n// The composed Milkdown bundle and the individual plugin factories are exported\n// from `@kungal/editor-core/preset` (they pull in the peer deps):\n//\n// import { createKunEditorPlugins } from '@kungal/editor-core/preset'\n//\n// P1 landed (docs/architecture.md § migration): spoiler, katex, code-block,\n// stop-link — each a factory (createXxxPlugin), never a host-bound singleton.\n// P2 adds the adapter-driven plugins (upload / mention / sticker).\n"]}
1
+ {"version":3,"sources":["../src/outline.ts","../src/index.ts"],"names":[],"mappings":";;;AAgBA,IAAM,KAAA,GAAQ,qBAAA;AACd,IAAM,GAAA,GAAM,kCAAA;AAGL,IAAM,aAAA,GAAgB,CAAC,QAAA,KAAmC;AAC/D,EAAA,MAAM,MAAoB,EAAC;AAC3B,EAAA,IAAI,OAAA,GAAU,KAAA;AACd,EAAA,KAAA,MAAW,IAAA,IAAQ,QAAA,CAAS,KAAA,CAAM,IAAI,CAAA,EAAG;AACvC,IAAA,IAAI,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,EAAG;AACpB,MAAA,OAAA,GAAU,CAAC,OAAA;AACX,MAAA;AAAA,IACF;AACA,IAAA,IAAI,OAAA,EAAS;AACX,MAAA;AAAA,IACF;AACA,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AACxB,IAAA,IAAI,CAAA,EAAG;AACL,MAAA,GAAA,CAAI,IAAA,CAAK,EAAE,KAAA,EAAO,CAAA,CAAE,CAAC,CAAA,CAAG,MAAA,EAAQ,IAAA,EAAM,CAAA,CAAE,CAAC,CAAA,CAAG,IAAA,IAAQ,CAAA;AAAA,IACtD;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;;;ACtBO,IAAM,cAAA,GAAiB;AAMvB,IAAM,YAAA,GAAe;AAErB,IAAM,uBAAA,GAA0B","file":"index.cjs","sourcesContent":["// Heading outline (table-of-contents) parsing — pure, zero-dep, so it lives in\n// the light main entry (a host, or the server, can build a TOC without pulling in\n// @milkdown/kit). Parses ATX headings (`#`…`######`) — what the toolbar produces\n// — and skips fenced code blocks so a `# comment` inside ``` isn't mistaken for a\n// heading. Setext headings (underlined) are intentionally not parsed.\n//\n// The result is an ordered list; a UI renders it and, on click, calls the\n// editor's `scrollToHeading(index)` with the item's array index.\n\nexport interface KunHeading {\n /** Heading level 1–6. */\n level: number\n /** The heading's text (trailing `#` closers stripped). */\n text: string\n}\n\nconst FENCE = /^\\s{0,3}(?:```|~~~)/\nconst ATX = /^ {0,3}(#{1,6})\\s+(.+?)\\s*#*\\s*$/\n\n/** Parse the ordered ATX-heading outline from a markdown string. */\nexport const parseHeadings = (markdown: string): KunHeading[] => {\n const out: KunHeading[] = []\n let inFence = false\n for (const line of markdown.split('\\n')) {\n if (FENCE.test(line)) {\n inFence = !inFence\n continue\n }\n if (inFence) {\n continue\n }\n const m = line.match(ATX)\n if (m) {\n out.push({ level: m[1]!.length, text: m[2]!.trim() })\n }\n }\n return out\n}\n","// @kungal/editor-core — public entry.\n//\n// STATUS: scaffold. The adapter contracts (the stable public surface) are\n// defined and exported now; the Milkdown plugin ports land incrementally per\n// docs/architecture.md § migration. Consumers should code against the types\n// below — those are the contract that will not churn as plugins move over.\n\nexport * from './types'\n\n// Heading outline (TOC) parsing — pure, so it's here in the light entry.\nexport * from './outline'\n\n// Markdown scheme used to encode an @mention as a plain link the server can\n// render + parse: `[@name](kungal-user:<id>)`. Lives here (not the plugin) so\n// hosts and the server can share the exact string. See ./plugins/mention.\nexport const MENTION_SCHEME = 'kungal-user:'\n\n// Markdown scheme for an inline reference (reply quote): `[label](kungal-reply:<refId>)`.\n// Like MENTION_SCHEME, shared with the server renderer so both agree on the\n// exact string. The reference is opaque here — the host decides what `refId` /\n// `label` mean (see docs/architecture.md § the reply-quote question, option 1).\nexport const QUOTE_SCHEME = 'kungal-reply:'\n\nexport const KUN_EDITOR_CORE_VERSION = '0.0.0'\n\n// ── The Milkdown plugins live in the `./preset` subpath ──────────────────────\n// This main entry stays light on purpose: types + MENTION_SCHEME, ZERO runtime\n// deps, so the server (which only needs the @mention scheme string) can import\n// it without installing @milkdown/kit / katex / codemirror.\n//\n// The composed Milkdown bundle and the individual plugin factories are exported\n// from `@kungal/editor-core/preset` (they pull in the peer deps):\n//\n// import { createKunEditorPlugins } from '@kungal/editor-core/preset'\n//\n// P1 landed (docs/architecture.md § migration): spoiler, katex, code-block,\n// stop-link — each a factory (createXxxPlugin), never a host-bound singleton.\n// P2 adds the adapter-driven plugins (upload / mention / sticker).\n"]}
package/dist/index.d.cts CHANGED
@@ -1,7 +1,16 @@
1
1
  export { K as KunEditorAdapters, a as KunEditorFeatures, b as KunEditorLocale, M as MentionUser, N as Notify, c as NotifyLevel, S as SearchMentionUsers, d as StickerItem, e as StickerPack, f as StickerSource, U as UploadImage } from './types-Dq7UxR_g.cjs';
2
2
 
3
+ interface KunHeading {
4
+ /** Heading level 1–6. */
5
+ level: number;
6
+ /** The heading's text (trailing `#` closers stripped). */
7
+ text: string;
8
+ }
9
+ /** Parse the ordered ATX-heading outline from a markdown string. */
10
+ declare const parseHeadings: (markdown: string) => KunHeading[];
11
+
3
12
  declare const MENTION_SCHEME = "kungal-user:";
4
13
  declare const QUOTE_SCHEME = "kungal-reply:";
5
14
  declare const KUN_EDITOR_CORE_VERSION = "0.0.0";
6
15
 
7
- export { KUN_EDITOR_CORE_VERSION, MENTION_SCHEME, QUOTE_SCHEME };
16
+ export { KUN_EDITOR_CORE_VERSION, type KunHeading, MENTION_SCHEME, QUOTE_SCHEME, parseHeadings };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,16 @@
1
1
  export { K as KunEditorAdapters, a as KunEditorFeatures, b as KunEditorLocale, M as MentionUser, N as Notify, c as NotifyLevel, S as SearchMentionUsers, d as StickerItem, e as StickerPack, f as StickerSource, U as UploadImage } from './types-Dq7UxR_g.js';
2
2
 
3
+ interface KunHeading {
4
+ /** Heading level 1–6. */
5
+ level: number;
6
+ /** The heading's text (trailing `#` closers stripped). */
7
+ text: string;
8
+ }
9
+ /** Parse the ordered ATX-heading outline from a markdown string. */
10
+ declare const parseHeadings: (markdown: string) => KunHeading[];
11
+
3
12
  declare const MENTION_SCHEME = "kungal-user:";
4
13
  declare const QUOTE_SCHEME = "kungal-reply:";
5
14
  declare const KUN_EDITOR_CORE_VERSION = "0.0.0";
6
15
 
7
- export { KUN_EDITOR_CORE_VERSION, MENTION_SCHEME, QUOTE_SCHEME };
16
+ export { KUN_EDITOR_CORE_VERSION, type KunHeading, MENTION_SCHEME, QUOTE_SCHEME, parseHeadings };
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- export { KUN_EDITOR_CORE_VERSION, MENTION_SCHEME, QUOTE_SCHEME } from './chunk-KY2VN6IQ.js';
1
+ export { KUN_EDITOR_CORE_VERSION, MENTION_SCHEME, QUOTE_SCHEME, parseHeadings } from './chunk-PT42ZQGO.js';
2
2
  //# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
@@ -196,6 +196,29 @@ var linkCustomKeymap = utils.$useKeymap("linkCustomKeymap", {
196
196
  }
197
197
  });
198
198
  var createStopLinkPlugin = () => [stopLinkCommand, linkCustomKeymap].flat();
199
+ var insertLinkCommand = utils.$command(
200
+ "InsertKunLink",
201
+ (ctx) => (payload) => (state, dispatch) => {
202
+ const href = payload?.href?.trim();
203
+ if (!href) {
204
+ return false;
205
+ }
206
+ const markType = commonmark.linkSchema.type(ctx);
207
+ const mark = markType.create({ href });
208
+ const { from, to, empty } = state.selection;
209
+ if (empty) {
210
+ const text = payload?.text?.trim() || href;
211
+ const tr = state.tr.insertText(text, from);
212
+ tr.addMark(from, from + text.length, mark);
213
+ tr.removeStoredMark(markType);
214
+ dispatch?.(tr.scrollIntoView());
215
+ } else {
216
+ dispatch?.(state.tr.addMark(from, to, mark).scrollIntoView());
217
+ }
218
+ return true;
219
+ }
220
+ );
221
+ var createLinkPlugin = () => [insertLinkCommand].flat();
199
222
  var setHeadingCommand = utils.$command(
200
223
  "SetHeadingKun",
201
224
  (ctx) => (level = 0) => level >= 1 && level <= 6 ? commands.setBlockType(commonmark.headingSchema.type(ctx), { level }) : commands.setBlockType(commonmark.paragraphSchema.type(ctx))
@@ -1160,6 +1183,7 @@ var createKunEditorPlugins = (adapters = {}, features = {}, options = {}) => {
1160
1183
  plugins.push(imageUploadPlaceholder);
1161
1184
  }
1162
1185
  plugins.push(createStopLinkPlugin());
1186
+ plugins.push(createLinkPlugin());
1163
1187
  plugins.push(createHeadingPlugin());
1164
1188
  if (options.placeholder) {
1165
1189
  plugins.push(
@@ -1182,6 +1206,7 @@ exports.createCodeBlockPlugins = createCodeBlockPlugins;
1182
1206
  exports.createHeadingPlugin = createHeadingPlugin;
1183
1207
  exports.createKatexPlugins = createKatexPlugins;
1184
1208
  exports.createKunEditorPlugins = createKunEditorPlugins;
1209
+ exports.createLinkPlugin = createLinkPlugin;
1185
1210
  exports.createMentionPlugin = createMentionPlugin;
1186
1211
  exports.createPlaceholderPlugin = createPlaceholderPlugin;
1187
1212
  exports.createQuotePlugin = createQuotePlugin;
@@ -1193,6 +1218,7 @@ exports.createUploader = createUploader;
1193
1218
  exports.editIcon = editIcon;
1194
1219
  exports.imageUploadPlaceholder = imageUploadPlaceholder;
1195
1220
  exports.insertKunSpoilerCommand = insertKunSpoilerCommand;
1221
+ exports.insertLinkCommand = insertLinkCommand;
1196
1222
  exports.insertMentionCommand = insertMentionCommand;
1197
1223
  exports.insertQuoteCommand = insertQuoteCommand;
1198
1224
  exports.insertSpoilerInputRule = insertSpoilerInputRule;