@notectl/core 1.0.8 → 1.0.9

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 (106) hide show
  1. package/dist/chunks/ToolbarPlugin-DFkl1uYO.mjs +818 -0
  2. package/dist/chunks/ToolbarPlugin-DFkl1uYO.mjs.map +1 -0
  3. package/dist/chunks/{index-CxiWyUho.mjs → index-BCvuDpVr.mjs} +2 -2
  4. package/dist/chunks/{index-CxiWyUho.mjs.map → index-BCvuDpVr.mjs.map} +1 -1
  5. package/dist/chunks/{index-C2GQoHot.mjs → index-BFsYGsBR.mjs} +2 -2
  6. package/dist/chunks/{index-C2GQoHot.mjs.map → index-BFsYGsBR.mjs.map} +1 -1
  7. package/dist/chunks/{index-B_3qDrUN.mjs → index-BIL37LSL.mjs} +23 -14
  8. package/dist/chunks/index-BIL37LSL.mjs.map +1 -0
  9. package/dist/chunks/{index-Ct0ivLhO.mjs → index-BL56fbXt.mjs} +214 -219
  10. package/dist/chunks/{index-Ct0ivLhO.mjs.map → index-BL56fbXt.mjs.map} +1 -1
  11. package/dist/chunks/{index-BYgspns5.mjs → index-BQ8iIYLn.mjs} +2 -2
  12. package/dist/chunks/{index-BYgspns5.mjs.map → index-BQ8iIYLn.mjs.map} +1 -1
  13. package/dist/chunks/index-BTJfyJlJ.mjs +187 -0
  14. package/dist/chunks/index-BTJfyJlJ.mjs.map +1 -0
  15. package/dist/chunks/{index-D3CQWJiw.mjs → index-DA8TG2S8.mjs} +39 -19
  16. package/dist/chunks/index-DA8TG2S8.mjs.map +1 -0
  17. package/dist/chunks/{index-C-YWHOcC.mjs → index-DAFCISBN.mjs} +21 -21
  18. package/dist/chunks/{index-C-YWHOcC.mjs.map → index-DAFCISBN.mjs.map} +1 -1
  19. package/dist/chunks/{index-BAk1EG1x.mjs → index-DGrRWMlW.mjs} +2 -2
  20. package/dist/chunks/{index-BAk1EG1x.mjs.map → index-DGrRWMlW.mjs.map} +1 -1
  21. package/dist/chunks/{index-CT3HGdQt.mjs → index-DfO_fKw6.mjs} +6 -6
  22. package/dist/chunks/{index-CT3HGdQt.mjs.map → index-DfO_fKw6.mjs.map} +1 -1
  23. package/dist/chunks/resolvePluginLocale-B4w1OkPy.mjs.map +1 -1
  24. package/dist/editor/DocumentSerializer.d.ts.map +1 -1
  25. package/dist/editor/NotectlEditor.d.ts +27 -5
  26. package/dist/editor/NotectlEditor.d.ts.map +1 -1
  27. package/dist/editor/styles/list.d.ts +2 -0
  28. package/dist/editor/styles/list.d.ts.map +1 -1
  29. package/dist/editor/styles/toolbar.d.ts +1 -1
  30. package/dist/editor/styles/toolbar.d.ts.map +1 -1
  31. package/dist/index.d.ts +6 -3
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/input/ClipboardHandler.d.ts +2 -0
  34. package/dist/input/ClipboardHandler.d.ts.map +1 -1
  35. package/dist/input/InputHandler.d.ts +2 -0
  36. package/dist/input/InputHandler.d.ts.map +1 -1
  37. package/dist/input/KeyboardHandler.d.ts +2 -0
  38. package/dist/input/KeyboardHandler.d.ts.map +1 -1
  39. package/dist/input/LegacyHTMLNormalizer.d.ts +18 -0
  40. package/dist/input/LegacyHTMLNormalizer.d.ts.map +1 -0
  41. package/dist/input/PasteHandler.d.ts +4 -0
  42. package/dist/input/PasteHandler.d.ts.map +1 -1
  43. package/dist/model/HTMLParser.d.ts +13 -0
  44. package/dist/model/HTMLParser.d.ts.map +1 -1
  45. package/dist/model/SchemaRegistry.d.ts +2 -2
  46. package/dist/model/SchemaRegistry.d.ts.map +1 -1
  47. package/dist/notectl-core.mjs +546 -394
  48. package/dist/notectl-core.mjs.map +1 -1
  49. package/dist/notectl-core.umd.js +1772 -1161
  50. package/dist/notectl-core.umd.js.map +1 -1
  51. package/dist/plugins/Plugin.d.ts +17 -2
  52. package/dist/plugins/Plugin.d.ts.map +1 -1
  53. package/dist/plugins/PluginManager.d.ts +17 -1
  54. package/dist/plugins/PluginManager.d.ts.map +1 -1
  55. package/dist/plugins/alignment/AlignmentPlugin.d.ts.map +1 -1
  56. package/dist/plugins/alignment.mjs +1 -1
  57. package/dist/plugins/code-block/CodeBlockPlugin.d.ts.map +1 -1
  58. package/dist/plugins/code-block.mjs +1 -1
  59. package/dist/plugins/font-size.mjs +1 -1
  60. package/dist/plugins/font.mjs +1 -1
  61. package/dist/plugins/heading/HeadingBlockTypePicker.d.ts +14 -0
  62. package/dist/plugins/heading/HeadingBlockTypePicker.d.ts.map +1 -0
  63. package/dist/plugins/heading/HeadingCommands.d.ts +5 -0
  64. package/dist/plugins/heading/HeadingCommands.d.ts.map +1 -0
  65. package/dist/plugins/heading/HeadingInputRules.d.ts +5 -0
  66. package/dist/plugins/heading/HeadingInputRules.d.ts.map +1 -0
  67. package/dist/plugins/heading/HeadingKeyboardHandlers.d.ts +5 -0
  68. package/dist/plugins/heading/HeadingKeyboardHandlers.d.ts.map +1 -0
  69. package/dist/plugins/heading/HeadingPlugin.d.ts +1 -41
  70. package/dist/plugins/heading/HeadingPlugin.d.ts.map +1 -1
  71. package/dist/plugins/heading.mjs +1 -1
  72. package/dist/plugins/image/ImagePlugin.d.ts.map +1 -1
  73. package/dist/plugins/image.mjs +1 -1
  74. package/dist/plugins/list/ListPlugin.d.ts +9 -0
  75. package/dist/plugins/list/ListPlugin.d.ts.map +1 -1
  76. package/dist/plugins/list.mjs +1 -1
  77. package/dist/plugins/strikethrough/StrikethroughPlugin.d.ts.map +1 -1
  78. package/dist/plugins/strikethrough.mjs +1 -1
  79. package/dist/plugins/super-sub/SuperSubPlugin.d.ts.map +1 -1
  80. package/dist/plugins/super-sub.mjs +1 -1
  81. package/dist/plugins/text-formatting/TextFormattingPlugin.d.ts.map +1 -1
  82. package/dist/plugins/text-formatting.mjs +1 -1
  83. package/dist/plugins/toolbar/ToolbarLocale.d.ts +1 -0
  84. package/dist/plugins/toolbar/ToolbarLocale.d.ts.map +1 -1
  85. package/dist/plugins/toolbar/ToolbarOverflowBehavior.d.ts +23 -0
  86. package/dist/plugins/toolbar/ToolbarOverflowBehavior.d.ts.map +1 -0
  87. package/dist/plugins/toolbar/ToolbarOverflowController.d.ts +56 -0
  88. package/dist/plugins/toolbar/ToolbarOverflowController.d.ts.map +1 -0
  89. package/dist/plugins/toolbar/ToolbarPlugin.d.ts +17 -0
  90. package/dist/plugins/toolbar/ToolbarPlugin.d.ts.map +1 -1
  91. package/dist/plugins/toolbar.mjs +1 -1
  92. package/dist/state/ReadonlyGuard.d.ts +6 -0
  93. package/dist/state/ReadonlyGuard.d.ts.map +1 -0
  94. package/dist/state/Transaction.d.ts +4 -0
  95. package/dist/state/Transaction.d.ts.map +1 -1
  96. package/dist/view/EditorView.d.ts +2 -0
  97. package/dist/view/EditorView.d.ts.map +1 -1
  98. package/package.json +1 -1
  99. package/dist/chunks/ToolbarPlugin-DY2xaJiu.mjs +0 -368
  100. package/dist/chunks/ToolbarPlugin-DY2xaJiu.mjs.map +0 -1
  101. package/dist/chunks/index-B_3qDrUN.mjs.map +0 -1
  102. package/dist/chunks/index-D3CQWJiw.mjs.map +0 -1
  103. package/dist/chunks/index-Dh76rR13.mjs +0 -196
  104. package/dist/chunks/index-Dh76rR13.mjs.map +0 -1
  105. package/dist/input/SourceNormalizer.d.ts +0 -7
  106. package/dist/input/SourceNormalizer.d.ts.map +0 -1
@@ -1,8 +1,17 @@
1
1
  import { A as e, t } from "./Commands-CSpSwGXv.mjs";
2
2
  import { r as i } from "./resolvePluginLocale-B4w1OkPy.mjs";
3
3
  import { m as a } from "./TypeBrands-C09nE2qO.mjs";
4
- import { f as o } from "./ToolbarItem-ugDymuXi.mjs";
5
- const r = { boldLabel: "Bold", italicLabel: "Italic", underlineLabel: "Underline" }, n = { en: r, de: { boldLabel: "Fett", italicLabel: "Kursiv", underlineLabel: "Unterstrichen" }, es: { boldLabel: "Negrita", italicLabel: "Cursiva", underlineLabel: "Subrayado" }, fr: { boldLabel: "Gras", italicLabel: "Italique", underlineLabel: "Souligné" }, zh: { boldLabel: "粗体", italicLabel: "斜体", underlineLabel: "下划线" }, ru: { boldLabel: "Жирный", italicLabel: "Курсив", underlineLabel: "Подчёркнутый" }, ar: { boldLabel: "غامق", italicLabel: "مائل", underlineLabel: "تحته خط" }, hi: { boldLabel: "बोल्ड", italicLabel: "इटैलिक", underlineLabel: "अंडरलाइन" } }, l = { bold: true, italic: true, underline: true }, s = [{ type: "bold", configKey: "bold", rank: 0, tag: "strong", label: "Bold", icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z"/></svg>', keyBinding: "Mod-B", toHTMLString: (e2) => `<strong>${e2}</strong>`, parseHTML: [{ tag: "strong" }, { tag: "b" }], sanitize: { tags: ["strong", "b"] } }, { type: "italic", configKey: "italic", rank: 1, tag: "em", label: "Italic", icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z"/></svg>', keyBinding: "Mod-I", toHTMLString: (e2) => `<em>${e2}</em>`, parseHTML: [{ tag: "em" }, { tag: "i" }], sanitize: { tags: ["em", "i"] } }, { type: "underline", configKey: "underline", rank: 2, tag: "u", label: "Underline", icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z"/></svg>', keyBinding: "Mod-U", toHTMLString: (e2) => `<u>${e2}</u>`, parseHTML: [{ tag: "u" }], sanitize: { tags: ["u"] } }];
4
+ import { f as r } from "./ToolbarItem-ugDymuXi.mjs";
5
+ const o = { boldLabel: "Bold", italicLabel: "Italic", underlineLabel: "Underline" }, n = { en: o, de: { boldLabel: "Fett", italicLabel: "Kursiv", underlineLabel: "Unterstrichen" }, es: { boldLabel: "Negrita", italicLabel: "Cursiva", underlineLabel: "Subrayado" }, fr: { boldLabel: "Gras", italicLabel: "Italique", underlineLabel: "Souligné" }, zh: { boldLabel: "粗体", italicLabel: "斜体", underlineLabel: "下划线" }, ru: { boldLabel: "Жирный", italicLabel: "Курсив", underlineLabel: "Подчёркнутый" }, ar: { boldLabel: "غامق", italicLabel: "مائل", underlineLabel: "تحته خط" }, hi: { boldLabel: "बोल्ड", italicLabel: "इटैलिक", underlineLabel: "अंडरलाइन" } }, s = { bold: true, italic: true, underline: true }, l = [{ type: "bold", configKey: "bold", rank: 0, tag: "strong", label: "Bold", icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z"/></svg>', keyBinding: "Mod-B", toHTMLString: (e2) => `<strong>${e2}</strong>`, parseHTML: [{ tag: "strong" }, { tag: "b", getAttrs: (e2) => {
6
+ const t2 = e2.style.fontWeight;
7
+ return "normal" !== t2 && "400" !== t2 && {};
8
+ } }, { tag: "span", getAttrs: (e2) => {
9
+ const t2 = e2.style.fontWeight;
10
+ if (!t2) return false;
11
+ if ("bold" === t2) return {};
12
+ const i2 = Number.parseInt(t2, 10);
13
+ return !Number.isNaN(i2) && i2 >= 700 && {};
14
+ } }], sanitize: { tags: ["strong", "b"] } }, { type: "italic", configKey: "italic", rank: 1, tag: "em", label: "Italic", icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z"/></svg>', keyBinding: "Mod-I", toHTMLString: (e2) => `<em>${e2}</em>`, parseHTML: [{ tag: "em" }, { tag: "i" }, { tag: "span", getAttrs: (e2) => "italic" === e2.style.fontStyle && {} }], sanitize: { tags: ["em", "i"] } }, { type: "underline", configKey: "underline", rank: 2, tag: "u", label: "Underline", icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z"/></svg>', keyBinding: "Mod-U", toHTMLString: (e2) => `<u>${e2}</u>`, parseHTML: [{ tag: "u" }, { tag: "span", getAttrs: (e2) => !!e2.style.textDecoration.includes("underline") && {} }], sanitize: { tags: ["u"] } }];
6
15
  class g {
7
16
  id = "text-formatting";
8
17
  name = "Text Formatting";
@@ -10,25 +19,25 @@ class g {
10
19
  config;
11
20
  locale;
12
21
  constructor(e2) {
13
- this.config = { ...l, ...e2 };
22
+ this.config = { ...s, ...e2 };
14
23
  }
15
24
  init(e2) {
16
25
  this.locale = i(n, e2, this.config.locale);
17
- const t2 = s.filter((e3) => this.config[e3.configKey]), a2 = t2.filter((e3) => this.isToolbarVisible(e3.configKey)).at(-1);
26
+ const t2 = l.filter((e3) => this.config[e3.configKey]), a2 = t2.filter((e3) => this.isToolbarVisible(e3.configKey)).at(-1);
18
27
  for (const i2 of t2) {
19
28
  const t3 = this.config.separatorAfter && i2 === a2;
20
29
  this.registerMark(e2, i2, t3);
21
30
  }
22
31
  this.registerKeymaps(e2, t2), this.registerDisabledToolbarItems(e2);
23
32
  }
24
- registerMark(i2, r2, n2) {
25
- const l2 = c(r2.type), s2 = this.isToolbarVisible(r2.configKey);
26
- if (i2.registerMarkSpec({ type: r2.type, rank: r2.rank, toDOM: () => document.createElement(r2.tag), toHTMLString: (e2, t2) => r2.toHTMLString(t2), parseHTML: r2.parseHTML, sanitize: r2.sanitize }), i2.registerCommand(l2, () => {
27
- const t2 = e(i2.getState(), a(r2.type));
33
+ registerMark(i2, o2, n2) {
34
+ const s2 = c(o2.type), l2 = this.isToolbarVisible(o2.configKey);
35
+ if (i2.registerMarkSpec({ type: o2.type, rank: o2.rank, toDOM: () => document.createElement(o2.tag), toHTMLString: (e2, t2) => o2.toHTMLString(t2), parseHTML: o2.parseHTML, sanitize: o2.sanitize }), i2.registerCommand(s2, () => {
36
+ const t2 = e(i2.getState(), a(o2.type));
28
37
  return !!t2 && (i2.dispatch(t2), true);
29
- }), s2) {
30
- const e2 = this.getMarkLabel(r2.type);
31
- i2.registerToolbarItem({ id: r2.type, group: "format", icon: r2.icon, label: e2, tooltip: `${e2} (${o(r2.keyBinding)})`, command: l2, priority: 10 * r2.rank + 10, separatorAfter: n2, isActive: (e3) => t(e3, a(r2.type)) });
38
+ }), l2) {
39
+ const e2 = this.getMarkLabel(o2.type);
40
+ i2.registerToolbarItem({ id: o2.type, group: "format", icon: o2.icon, label: e2, tooltip: `${e2} (${r(o2.keyBinding)})`, command: s2, priority: 10 * o2.rank + 10, separatorAfter: n2, isActive: (e3) => t(e3, a(o2.type)) });
32
41
  }
33
42
  }
34
43
  registerKeymaps(e2, t2) {
@@ -40,7 +49,7 @@ class g {
40
49
  Object.keys(i2).length > 0 && e2.registerKeymap(i2);
41
50
  }
42
51
  registerDisabledToolbarItems(e2) {
43
- if (this.config.toolbar) for (const t2 of s) {
52
+ if (this.config.toolbar) for (const t2 of l) {
44
53
  const i2 = this.config[t2.configKey], a2 = this.config.toolbar[t2.configKey] ?? true;
45
54
  !i2 && a2 && e2.registerToolbarItem({ id: t2.type, group: "format", icon: t2.icon, label: this.getMarkLabel(t2.type), command: c(t2.type), priority: 10 * t2.rank + 10, isEnabled: () => false });
46
55
  }
@@ -59,6 +68,6 @@ function c(e2) {
59
68
  export {
60
69
  g as T,
61
70
  n as a,
62
- r as b
71
+ o as b
63
72
  };
64
- //# sourceMappingURL=index-B_3qDrUN.mjs.map
73
+ //# sourceMappingURL=index-BIL37LSL.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-BIL37LSL.mjs","sources":["../../src/plugins/text-formatting/TextFormattingLocale.ts","../../src/plugins/text-formatting/TextFormattingPlugin.ts"],"sourcesContent":["/**\n * Locale interface and default English locale for the TextFormattingPlugin.\n */\n\n// --- Locale Interface ---\n\nexport interface TextFormattingLocale {\n\treadonly boldLabel: string;\n\treadonly italicLabel: string;\n\treadonly underlineLabel: string;\n}\n\n// --- Default English Locale ---\n\nexport const TEXT_FORMATTING_LOCALE_EN: TextFormattingLocale = {\n\tboldLabel: 'Bold',\n\titalicLabel: 'Italic',\n\tunderlineLabel: 'Underline',\n};\n\n// --- German Locale ---\n\nexport const TEXT_FORMATTING_LOCALE_DE: TextFormattingLocale = {\n\tboldLabel: 'Fett',\n\titalicLabel: 'Kursiv',\n\tunderlineLabel: 'Unterstrichen',\n};\n\n// --- Spanish Locale ---\n\nexport const TEXT_FORMATTING_LOCALE_ES: TextFormattingLocale = {\n\tboldLabel: 'Negrita',\n\titalicLabel: 'Cursiva',\n\tunderlineLabel: 'Subrayado',\n};\n\n// --- French Locale ---\n\nexport const TEXT_FORMATTING_LOCALE_FR: TextFormattingLocale = {\n\tboldLabel: 'Gras',\n\titalicLabel: 'Italique',\n\tunderlineLabel: 'Souligné',\n};\n\n// --- Chinese (Simplified) Locale ---\n\nexport const TEXT_FORMATTING_LOCALE_ZH: TextFormattingLocale = {\n\tboldLabel: '粗体',\n\titalicLabel: '斜体',\n\tunderlineLabel: '下划线',\n};\n\n// --- Russian Locale ---\n\nexport const TEXT_FORMATTING_LOCALE_RU: TextFormattingLocale = {\n\tboldLabel: 'Жирный',\n\titalicLabel: 'Курсив',\n\tunderlineLabel: 'Подчёркнутый',\n};\n\n// --- Arabic Locale ---\n\nexport const TEXT_FORMATTING_LOCALE_AR: TextFormattingLocale = {\n\tboldLabel: 'غامق',\n\titalicLabel: 'مائل',\n\tunderlineLabel: 'تحته خط',\n};\n\n// --- Hindi Locale ---\n\nexport const TEXT_FORMATTING_LOCALE_HI: TextFormattingLocale = {\n\tboldLabel: 'बोल्ड',\n\titalicLabel: 'इटैलिक',\n\tunderlineLabel: 'अंडरलाइन',\n};\n\n// --- Locale Map ---\n\nexport const TEXT_FORMATTING_LOCALES: Record<string, TextFormattingLocale> = {\n\ten: TEXT_FORMATTING_LOCALE_EN,\n\tde: TEXT_FORMATTING_LOCALE_DE,\n\tes: TEXT_FORMATTING_LOCALE_ES,\n\tfr: TEXT_FORMATTING_LOCALE_FR,\n\tzh: TEXT_FORMATTING_LOCALE_ZH,\n\tru: TEXT_FORMATTING_LOCALE_RU,\n\tar: TEXT_FORMATTING_LOCALE_AR,\n\thi: TEXT_FORMATTING_LOCALE_HI,\n};\n","/**\n * TextFormattingPlugin: registers inline marks (bold, italic, underline)\n * with their MarkSpecs, toggle commands, keyboard shortcuts, and toolbar items.\n *\n * This plugin is data-driven — each mark type is defined declaratively and\n * all registrations (MarkSpec, command, keymap, toolbar item) are derived\n * from the same definition.\n *\n * Supports two separate config dimensions:\n * - Feature config (bold/italic/underline): controls whether the mark is\n * registered in the schema. When disabled, the keyboard shortcut does nothing.\n * - Toolbar config: controls whether the toolbar button is visible.\n * When a feature is disabled but toolbar is enabled, the button renders as disabled.\n */\n\nimport { isMarkActive, toggleMark } from '../../commands/Commands.js';\nimport { resolvePluginLocale } from '../../i18n/resolvePluginLocale.js';\nimport type { ParseRule } from '../../model/ParseRule.js';\nimport type { SanitizeConfig } from '../../model/SanitizeConfig.js';\nimport { markType as mkType } from '../../model/TypeBrands.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { formatShortcut } from '../toolbar/ToolbarItem.js';\nimport { TEXT_FORMATTING_LOCALES, type TextFormattingLocale } from './TextFormattingLocale.js';\n\n// --- Configuration ---\n\n/** Controls toolbar button visibility per mark. */\nexport interface TextFormattingToolbarConfig {\n\treadonly bold?: boolean;\n\treadonly italic?: boolean;\n\treadonly underline?: boolean;\n}\n\n/** Controls which inline marks are enabled and which toolbar buttons are shown. */\nexport interface TextFormattingConfig {\n\treadonly bold: boolean;\n\treadonly italic: boolean;\n\treadonly underline: boolean;\n\treadonly toolbar?: TextFormattingToolbarConfig;\n\t/** When true, a separator is rendered after the last text-formatting toolbar item. */\n\treadonly separatorAfter?: boolean;\n\treadonly locale?: TextFormattingLocale;\n}\n\nconst DEFAULT_CONFIG: TextFormattingConfig = {\n\tbold: true,\n\titalic: true,\n\tunderline: true,\n};\n\n// --- Mark Definitions ---\n\ninterface MarkDefinition {\n\treadonly type: string;\n\treadonly configKey: keyof Omit<TextFormattingConfig, 'toolbar' | 'separatorAfter' | 'locale'>;\n\treadonly rank: number;\n\treadonly tag: string;\n\treadonly label: string;\n\treadonly icon: string;\n\treadonly keyBinding: string;\n\treadonly toHTMLString: (content: string) => string;\n\treadonly parseHTML: readonly ParseRule[];\n\treadonly sanitize: SanitizeConfig;\n}\n\nconst BOLD_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z\"/></svg>';\nconst ITALIC_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z\"/></svg>';\nconst UNDERLINE_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z\"/></svg>';\n\nconst MARK_DEFINITIONS: readonly MarkDefinition[] = [\n\t{\n\t\ttype: 'bold',\n\t\tconfigKey: 'bold',\n\t\trank: 0,\n\t\ttag: 'strong',\n\t\tlabel: 'Bold',\n\t\ticon: BOLD_ICON,\n\t\tkeyBinding: 'Mod-B',\n\t\ttoHTMLString: (content) => `<strong>${content}</strong>`,\n\t\tparseHTML: [\n\t\t\t{ tag: 'strong' },\n\t\t\t{\n\t\t\t\ttag: 'b',\n\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\tconst fw: string = el.style.fontWeight;\n\t\t\t\t\treturn fw === 'normal' || fw === '400' ? false : {};\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\ttag: 'span',\n\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\tconst fw: string = el.style.fontWeight;\n\t\t\t\t\tif (!fw) return false;\n\t\t\t\t\tif (fw === 'bold') return {};\n\t\t\t\t\tconst numeric: number = Number.parseInt(fw, 10);\n\t\t\t\t\treturn !Number.isNaN(numeric) && numeric >= 700 ? {} : false;\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tsanitize: { tags: ['strong', 'b'] },\n\t},\n\t{\n\t\ttype: 'italic',\n\t\tconfigKey: 'italic',\n\t\trank: 1,\n\t\ttag: 'em',\n\t\tlabel: 'Italic',\n\t\ticon: ITALIC_ICON,\n\t\tkeyBinding: 'Mod-I',\n\t\ttoHTMLString: (content) => `<em>${content}</em>`,\n\t\tparseHTML: [\n\t\t\t{ tag: 'em' },\n\t\t\t{ tag: 'i' },\n\t\t\t{\n\t\t\t\ttag: 'span',\n\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\treturn el.style.fontStyle === 'italic' ? {} : false;\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tsanitize: { tags: ['em', 'i'] },\n\t},\n\t{\n\t\ttype: 'underline',\n\t\tconfigKey: 'underline',\n\t\trank: 2,\n\t\ttag: 'u',\n\t\tlabel: 'Underline',\n\t\ticon: UNDERLINE_ICON,\n\t\tkeyBinding: 'Mod-U',\n\t\ttoHTMLString: (content) => `<u>${content}</u>`,\n\t\tparseHTML: [\n\t\t\t{ tag: 'u' },\n\t\t\t{\n\t\t\t\ttag: 'span',\n\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\treturn el.style.textDecoration.includes('underline') ? {} : false;\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tsanitize: { tags: ['u'] },\n\t},\n];\n\n// --- Plugin ---\n\nexport class TextFormattingPlugin implements Plugin {\n\treadonly id = 'text-formatting';\n\treadonly name = 'Text Formatting';\n\treadonly priority = 20;\n\n\tprivate readonly config: TextFormattingConfig;\n\tprivate locale!: TextFormattingLocale;\n\n\tconstructor(config?: Partial<TextFormattingConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tthis.locale = resolvePluginLocale(TEXT_FORMATTING_LOCALES, context, this.config.locale);\n\n\t\tconst enabledMarks = MARK_DEFINITIONS.filter((def) => this.config[def.configKey]);\n\n\t\t// Determine which marks will have visible toolbar items\n\t\tconst visibleToolbarMarks = enabledMarks.filter((def) => this.isToolbarVisible(def.configKey));\n\t\tconst lastVisibleMark = visibleToolbarMarks.at(-1);\n\n\t\tfor (const def of enabledMarks) {\n\t\t\tconst isSeparatorTarget = this.config.separatorAfter && def === lastVisibleMark;\n\t\t\tthis.registerMark(context, def, isSeparatorTarget);\n\t\t}\n\n\t\tthis.registerKeymaps(context, enabledMarks);\n\n\t\t// Register disabled placeholder buttons for marks that are disabled\n\t\t// as features but explicitly requested in the toolbar config\n\t\tthis.registerDisabledToolbarItems(context);\n\t}\n\n\tprivate registerMark(\n\t\tcontext: PluginContext,\n\t\tdef: MarkDefinition,\n\t\tseparatorAfter?: boolean,\n\t): void {\n\t\tconst commandName = toCommandName(def.type);\n\t\tconst toolbarVisible = this.isToolbarVisible(def.configKey);\n\n\t\tcontext.registerMarkSpec({\n\t\t\ttype: def.type,\n\t\t\trank: def.rank,\n\t\t\ttoDOM() {\n\t\t\t\treturn document.createElement(def.tag);\n\t\t\t},\n\t\t\ttoHTMLString: (_mark, content) => def.toHTMLString(content),\n\t\t\tparseHTML: def.parseHTML,\n\t\t\tsanitize: def.sanitize,\n\t\t});\n\n\t\tcontext.registerCommand(commandName, () => {\n\t\t\tconst tr = toggleMark(context.getState(), mkType(def.type));\n\t\t\tif (tr) {\n\t\t\t\tcontext.dispatch(tr);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\n\t\tif (toolbarVisible) {\n\t\t\tconst label: string = this.getMarkLabel(def.type);\n\t\t\tcontext.registerToolbarItem({\n\t\t\t\tid: def.type,\n\t\t\t\tgroup: 'format',\n\t\t\t\ticon: def.icon,\n\t\t\t\tlabel,\n\t\t\t\ttooltip: `${label} (${formatShortcut(def.keyBinding)})`,\n\t\t\t\tcommand: commandName,\n\t\t\t\tpriority: def.rank * 10 + 10,\n\t\t\t\tseparatorAfter,\n\t\t\t\tisActive: (state) => isMarkActive(state, mkType(def.type)),\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate registerKeymaps(context: PluginContext, marks: readonly MarkDefinition[]): void {\n\t\tconst keymap: Record<string, () => boolean> = {};\n\t\tfor (const def of marks) {\n\t\t\tconst commandName = toCommandName(def.type);\n\t\t\tkeymap[def.keyBinding] = () => context.executeCommand(commandName);\n\t\t}\n\t\tif (Object.keys(keymap).length > 0) {\n\t\t\tcontext.registerKeymap(keymap);\n\t\t}\n\t}\n\n\t/**\n\t * Registers disabled toolbar buttons for marks whose feature is disabled\n\t * but whose toolbar button is explicitly requested.\n\t */\n\tprivate registerDisabledToolbarItems(context: PluginContext): void {\n\t\tif (!this.config.toolbar) return;\n\n\t\tfor (const def of MARK_DEFINITIONS) {\n\t\t\tconst featureEnabled = this.config[def.configKey];\n\t\t\tconst toolbarVisible = this.config.toolbar[def.configKey] ?? true;\n\n\t\t\tif (!featureEnabled && toolbarVisible) {\n\t\t\t\tcontext.registerToolbarItem({\n\t\t\t\t\tid: def.type,\n\t\t\t\t\tgroup: 'format',\n\t\t\t\t\ticon: def.icon,\n\t\t\t\t\tlabel: this.getMarkLabel(def.type),\n\t\t\t\t\tcommand: toCommandName(def.type),\n\t\t\t\t\tpriority: def.rank * 10 + 10,\n\t\t\t\t\tisEnabled: () => false,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getMarkLabel(type: string): string {\n\t\tconst key = `${type}Label` as keyof TextFormattingLocale;\n\t\treturn this.locale[key] as string;\n\t}\n\n\t/** Checks if a toolbar button should be visible for a given mark. */\n\tprivate isToolbarVisible(\n\t\tconfigKey: keyof Omit<TextFormattingConfig, 'toolbar' | 'separatorAfter' | 'locale'>,\n\t): boolean {\n\t\tif (!this.config.toolbar) return true;\n\t\treturn this.config.toolbar[configKey] ?? true;\n\t}\n}\n\n/** Converts a mark type to its toggle command name (e.g. 'bold' → 'toggleBold'). */\nfunction toCommandName(markType: string): string {\n\treturn `toggle${markType.charAt(0).toUpperCase()}${markType.slice(1)}`;\n}\n"],"names":["TEXT_FORMATTING_LOCALE_EN","boldLabel","italicLabel","underlineLabel","TEXT_FORMATTING_LOCALES","en","de","es","fr","zh","ru","ar","hi","DEFAULT_CONFIG","bold","italic","underline","MARK_DEFINITIONS","type","configKey","rank","tag","label","icon","keyBinding","toHTMLString","content","parseHTML","getAttrs","el","fw","style","fontWeight","numeric","Number","parseInt","isNaN","sanitize","tags","fontStyle","textDecoration","includes","TextFormattingPlugin","id","name","priority","config","locale","this","context","resolvePluginLocale","enabledMarks","filter","def","lastVisibleMark","isToolbarVisible","at","isSeparatorTarget","separatorAfter","registerMark","registerKeymaps","registerDisabledToolbarItems","commandName","toCommandName","toolbarVisible","registerMarkSpec","toDOM","document","createElement","_mark","registerCommand","tr","toggleMark","getState","mkType","dispatch","getMarkLabel","registerToolbarItem","group","tooltip","formatShortcut","command","isActive","state","isMarkActive","marks","keymap","executeCommand","Object","keys","length","registerKeymap","toolbar","featureEnabled","isEnabled","key","markType","charAt","toUpperCase","slice"],"mappings":";;;;AAcO,MAAMA,IAAkD,EAC9DC,WAAW,QACXC,aAAa,UACbC,gBAAgB,YAAA,GA6DJC,IAAgE,EAC5EC,IAAIL,GACJM,IA1D8D,EAC9DL,WAAW,QACXC,aAAa,UACbC,gBAAgB,gBAAA,GAwDhBI,IAnD8D,EAC9DN,WAAW,WACXC,aAAa,WACbC,gBAAgB,YAAA,GAiDhBK,IA5C8D,EAC9DP,WAAW,QACXC,aAAa,YACbC,gBAAgB,WAAA,GA0ChBM,IArC8D,EAC9DR,WAAW,MACXC,aAAa,MACbC,gBAAgB,MAAA,GAmChBO,IA9B8D,EAC9DT,WAAW,UACXC,aAAa,UACbC,gBAAgB,eAAA,GA4BhBQ,IAvB8D,EAC9DV,WAAW,QACXC,aAAa,QACbC,gBAAgB,UAAA,GAqBhBS,IAhB8D,EAC9DX,WAAW,SACXC,aAAa,UACbC,gBAAgB,WAAA,EAAA,GC7BXU,IAAuC,EAC5CC,MAAAA,MACAC,QAAAA,MACAC,gBAAW,GAyBNC,IAA8C,CACnD,EACCC,MAAM,QACNC,WAAW,QACXC,MAAM,GACNC,KAAK,UACLC,OAAO,QACPC,MAbD,uTAcCC,YAAY,SACZC,cAAeC,CAAAA,OAAY,WAAWA,EAAAA,aACtCC,WAAW,CACV,EAAEN,KAAK,YACP,EACCA,KAAK,KACLO,UAAWC,CAAAA,OAAAA;AACV,QAAMC,KAAaD,GAAGE,MAAMC;AAC5B,SAAc,aAAPF,MAA0B,UAAPA,MAAuB,CAAA;AAAA,EAAA,GAGnD,EACCT,KAAK,QACLO,UAAWC,CAAAA,OAAAA;AACV,QAAMC,KAAaD,GAAGE,MAAMC;AAC5B,MAAA,CAAKF,GAAI,QAAA;AACT,MAAW,WAAPA,GAAe,QAAO,CAAA;AAC1B,QAAMG,KAAkBC,OAAOC,SAASL,IAAI,EAAA;AAC5C,UAAQI,OAAOE,MAAMH,EAAAA,KAAYA,MAAW,OAAM,CAAA;AAAA,EAAA,CAAA,GAIrDI,UAAU,EAAEC,MAAM,CAAC,UAAU,GAAA,EAAA,EAAA,GAE9B,EACCpB,MAAM,UACNC,WAAW,UACXC,MAAM,GACNC,KAAK,MACLC,OAAO,UACPC,MA1CD,kIA2CCC,YAAY,SACZC,cAAeC,CAAAA,OAAY,OAAOA,EAAAA,SAClCC,WAAW,CACV,EAAEN,KAAK,KAAA,GACP,EAAEA,KAAK,IAAA,GACP,EACCA,KAAK,QACLO,UAAWC,CAAAA,OACoB,aAAvBA,GAAGE,MAAMQ,aAAyB,CAAA,EAAA,CAAA,GAI5CF,UAAU,EAAEC,MAAM,CAAC,MAAM,GAAA,EAAA,EAAA,GAE1B,EACCpB,MAAM,aACNC,WAAW,aACXC,MAAM,GACNC,KAAK,KACLC,OAAO,aACPC,MA7DD,qMA8DCC,YAAY,SACZC,cAAeC,CAAAA,OAAY,MAAMA,EAAAA,QACjCC,WAAW,CACV,EAAEN,KAAK,IAAA,GACP,EACCA,KAAK,QACLO,UAAWC,CAAAA,OAAAA,CAAAA,CACHA,GAAGE,MAAMS,eAAeC,SAAS,WAAA,KAAe,CAAA,EAAA,CAAA,GAI1DJ,UAAU,EAAEC,MAAM,CAAC;AAMd,MAAMI,EAAAA;AAAAA,EACHC,KAAK;AAAA,EACLC,OAAO;AAAA,EACPC,WAAW;AAAA,EAEHC;AAAAA,EACTC;AAAAA,EAER,YAAYD,IAAAA;AACXE,SAAKF,SAAS,EAAA,GAAKjC,GAAAA,GAAmBiC;EACvC;AAAA,EAEA,KAAKG,IAAAA;AACJD,SAAKD,SAASG,EAAoB9C,GAAyB6C,IAASD,KAAKF,OAAOC,MAAAA;AAEhF,UAAMI,KAAelC,EAAiBmC,OAAQC,CAAAA,OAAQL,KAAKF,OAAOO,GAAIlC,SAAAA,CAAAA,GAIhEmC,KADsBH,GAAaC,OAAQC,CAAAA,OAAQL,KAAKO,iBAAiBF,GAAIlC,SAAAA,CAAAA,EACvCqC,GAAAA;AAE5C,eAAWH,MAAOF,IAAc;AAC/B,YAAMM,KAAoBT,KAAKF,OAAOY,kBAAkBL,OAAQC;AAChEN,WAAKW,aAAaV,IAASI,IAAKI,EAAAA;AAAAA,IACjC;AAEAT,SAAKY,gBAAgBX,IAASE,KAI9BH,KAAKa,6BAA6BZ,EAAAA;AAAAA,EACnC;AAAA,EAEQ,aACPA,IACAI,IACAK;AAEA,UAAMI,KAAcC,EAAcV,GAAInC,IAAAA,GAChC8C,KAAiBhB,KAAKO,iBAAiBF,GAAIlC,SAAAA;AAsBjD,QApBA8B,GAAQgB,iBAAiB,EACxB/C,MAAMmC,GAAInC,MACVE,MAAMiC,GAAIjC,MACV8C,OAAA,MACQC,SAASC,cAAcf,GAAIhC,GAAAA,GAEnCI,cAAc,CAAC4C,IAAO3C,OAAY2B,GAAI5B,aAAaC,EAAAA,GACnDC,WAAW0B,GAAI1B,WACfU,UAAUgB,GAAIhB,SAAAA,CAAAA,GAGfY,GAAQqB,gBAAgBR,IAAa,MAAA;AACpC,YAAMS,KAAKC,EAAWvB,GAAQwB,SAAAA,GAAYC,EAAOrB,GAAInC,IAAAA,CAAAA;AACrD,aAAA,CAAA,CAAIqD,OACHtB,GAAQ0B,SAASJ,EAAAA,GAAAA;AAAAA,IACV,CAAA,GAKLP,IAAgB;AACnB,YAAM1C,KAAgB0B,KAAK4B,aAAavB,GAAInC,IAAAA;AAC5C+B,MAAAA,GAAQ4B,oBAAoB,EAC3BlC,IAAIU,GAAInC,MACR4D,OAAO,UACPvD,MAAM8B,GAAI9B,MACVD,OAAAA,IACAyD,SAAS,GAAGzD,OAAU0D,EAAe3B,GAAI7B,UAAAA,CAAAA,KACzCyD,SAASnB,IACTjB,UAAqB,KAAXQ,GAAIjC,OAAY,IAC1BsC,gBAAAA,IACAwB,UAAWC,CAAAA,OAAUC,EAAaD,IAAOT,EAAOrB,GAAInC,IAAAA,CAAAA,EAAAA,CAAAA;AAAAA,IAEtD;AAAA,EACD;AAAA,EAEQ,gBAAgB+B,IAAwBoC,IAAAA;AAC/C,UAAMC,KAAwC,CAAA;AAC9C,eAAWjC,MAAOgC,IAAO;AACxB,YAAMvB,KAAcC,EAAcV,GAAInC,IAAAA;AACtCoE,MAAAA,GAAOjC,GAAI7B,UAAAA,IAAc,MAAMyB,GAAQsC,eAAezB,EAAAA;AAAAA,IACvD;AACI0B,WAAOC,KAAKH,EAAAA,EAAQI,SAAS,KAChCzC,GAAQ0C,eAAeL,EAAAA;AAAAA,EAEzB;AAAA,EAMQ,6BAA6BrC,IAAAA;AACpC,QAAKD,KAAKF,OAAO8C,QAEjB,YAAWvC,MAAOpC,GAAkB;AACnC,YAAM4E,KAAiB7C,KAAKF,OAAOO,GAAIlC,SAAAA,GACjC6C,KAAiBhB,KAAKF,OAAO8C,QAAQvC,GAAIlC,SAAAA,KAAAA;OAE1C0E,MAAkB7B,MACtBf,GAAQ4B,oBAAoB,EAC3BlC,IAAIU,GAAInC,MACR4D,OAAO,UACPvD,MAAM8B,GAAI9B,MACVD,OAAO0B,KAAK4B,aAAavB,GAAInC,IAAAA,GAC7B+D,SAASlB,EAAcV,GAAInC,IAAAA,GAC3B2B,UAAqB,KAAXQ,GAAIjC,OAAY,IAC1B0E,WAAW,MAAA,MAAM,CAAA;AAAA,IAGpB;AAAA,EACD;AAAA,EAEQ,aAAa5E;AACpB,UAAM6E,KAAM,GAAG7E,EAAAA;AACf,WAAO8B,KAAKD,OAAOgD,EAAAA;AAAAA,EACpB;AAAA,EAGQ,iBACP5E,IAAAA;AAEA,WAAA,CAAK6B,KAAKF,OAAO8C,YACV5C,KAAKF,OAAO8C,QAAQzE,EAAAA,KAAAA;AAAAA,EAC5B;AAAA;AAID,SAAS4C,EAAciC,IAAAA;AACtB,SAAO,SAASA,GAASC,OAAO,CAAA,EAAGC,YAAAA,CAAAA,GAAgBF,GAASG,MAAM,CAAA,CAAA;AACnE;"}