overtype 2.0.5 → 2.1.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/dist/overtype.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * OverType v2.0.5
2
+ * OverType v2.0.6
3
3
  * A lightweight markdown editor library with perfect WYSIWYG alignment
4
4
  * @license MIT
5
5
  * @author David Miranda
@@ -53,6 +53,24 @@ var OverType = (() => {
53
53
  static setCodeHighlighter(highlighter) {
54
54
  this.codeHighlighter = highlighter;
55
55
  }
56
+ /**
57
+ * Set custom syntax processor function
58
+ * @param {Function|null} processor - Function that takes (html) and returns modified HTML
59
+ */
60
+ static setCustomSyntax(processor) {
61
+ this.customSyntax = processor;
62
+ }
63
+ /**
64
+ * Apply custom syntax processor to parsed HTML
65
+ * @param {string} html - Parsed HTML line
66
+ * @returns {string} HTML with custom syntax applied
67
+ */
68
+ static applyCustomSyntax(html) {
69
+ if (this.customSyntax) {
70
+ return this.customSyntax(html);
71
+ }
72
+ return html;
73
+ }
56
74
  /**
57
75
  * Escape HTML special characters
58
76
  * @param {string} text - Raw text to escape
@@ -117,7 +135,7 @@ var OverType = (() => {
117
135
  * @returns {string} Parsed bullet list item
118
136
  */
119
137
  static parseBulletList(html) {
120
- return html.replace(/^((?: )*)([-*])\s(.+)$/, (match, indent, marker, content) => {
138
+ return html.replace(/^((?: )*)([-*+])\s(.+)$/, (match, indent, marker, content) => {
121
139
  return `${indent}<li class="bullet-list"><span class="syntax-marker">${marker} </span>${content}</li>`;
122
140
  });
123
141
  }
@@ -176,7 +194,7 @@ var OverType = (() => {
176
194
  * @returns {string} HTML with italic styling
177
195
  */
178
196
  static parseItalic(html) {
179
- html = html.replace(new RegExp("(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)", "g"), '<em><span class="syntax-marker">*</span>$1<span class="syntax-marker">*</span></em>');
197
+ html = html.replace(new RegExp("(?<![\\*>])\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)", "g"), '<em><span class="syntax-marker">*</span>$1<span class="syntax-marker">*</span></em>');
180
198
  html = html.replace(new RegExp("(?<=^|\\s)_(?!_)(.+?)(?<!_)_(?!_)(?=\\s|$)", "g"), '<em><span class="syntax-marker">_</span>$1<span class="syntax-marker">_</span></em>');
181
199
  return html;
182
200
  }
@@ -391,14 +409,14 @@ var OverType = (() => {
391
409
  const codeFenceRegex = /^```[^`]*$/;
392
410
  if (codeFenceRegex.test(line)) {
393
411
  inCodeBlock = !inCodeBlock;
394
- return this.parseLine(line, isPreviewMode);
412
+ return this.applyCustomSyntax(this.parseLine(line, isPreviewMode));
395
413
  }
396
414
  if (inCodeBlock) {
397
415
  const escaped = this.escapeHtml(line);
398
416
  const indented = this.preserveIndentation(escaped, line);
399
417
  return `<div>${indented || "&nbsp;"}</div>`;
400
418
  }
401
- return this.parseLine(line, isPreviewMode);
419
+ return this.applyCustomSyntax(this.parseLine(line, isPreviewMode));
402
420
  });
403
421
  const html = parsedLines.join("");
404
422
  return this.postProcessHTML(html, instanceHighlighter);
@@ -730,6 +748,8 @@ var OverType = (() => {
730
748
  __publicField(MarkdownParser, "linkIndex", 0);
731
749
  // Global code highlighter function
732
750
  __publicField(MarkdownParser, "codeHighlighter", null);
751
+ // Custom syntax processor function
752
+ __publicField(MarkdownParser, "customSyntax", null);
733
753
  /**
734
754
  * List pattern definitions
735
755
  */
@@ -2788,6 +2808,28 @@ ${blockSuffix}` : suffix;
2788
2808
  button.addEventListener("click", button._clickHandler);
2789
2809
  return button;
2790
2810
  }
2811
+ /**
2812
+ * Handle button action programmatically (used by keyboard shortcuts)
2813
+ * @param {Object} buttonConfig - Button configuration object with action function
2814
+ */
2815
+ async handleAction(buttonConfig) {
2816
+ this.editor.textarea.focus();
2817
+ try {
2818
+ if (buttonConfig.action) {
2819
+ await buttonConfig.action({
2820
+ editor: this.editor,
2821
+ getValue: () => this.editor.getValue(),
2822
+ setValue: (value) => this.editor.setValue(value),
2823
+ event: null
2824
+ });
2825
+ }
2826
+ } catch (error) {
2827
+ console.error(`Action "${buttonConfig.name}" error:`, error);
2828
+ this.editor.wrapper.dispatchEvent(new CustomEvent("button-error", {
2829
+ detail: { buttonName: buttonConfig.name, error }
2830
+ }));
2831
+ }
2832
+ }
2791
2833
  /**
2792
2834
  * Sanitize SVG to prevent XSS
2793
2835
  */
@@ -3726,10 +3768,13 @@ ${blockSuffix}` : suffix;
3726
3768
  */
3727
3769
  handleKeydown(event) {
3728
3770
  if (event.key === "Tab") {
3729
- event.preventDefault();
3730
3771
  const start = this.textarea.selectionStart;
3731
3772
  const end = this.textarea.selectionEnd;
3732
3773
  const value = this.textarea.value;
3774
+ if (event.shiftKey && start === end) {
3775
+ return;
3776
+ }
3777
+ event.preventDefault();
3733
3778
  if (start !== end && event.shiftKey) {
3734
3779
  const before = value.substring(0, start);
3735
3780
  const selection = value.substring(start, end);
@@ -4085,6 +4130,8 @@ ${blockSuffix}` : suffix;
4085
4130
  this.statsBar.className = "overtype-stats";
4086
4131
  this.container.appendChild(this.statsBar);
4087
4132
  this._updateStats();
4133
+ } else if (show && this.statsBar) {
4134
+ this._updateStats();
4088
4135
  } else if (!show && this.statsBar) {
4089
4136
  this.statsBar.remove();
4090
4137
  this.statsBar = null;
@@ -4153,6 +4200,44 @@ ${blockSuffix}` : suffix;
4153
4200
  static init(target, options = {}) {
4154
4201
  return new _OverType(target, options);
4155
4202
  }
4203
+ /**
4204
+ * Initialize editors with options from data-ot-* attributes
4205
+ * @param {string} selector - CSS selector for target elements
4206
+ * @param {Object} defaults - Default options (data attrs override these)
4207
+ * @returns {Array<OverType>} Array of OverType instances
4208
+ * @example
4209
+ * // HTML: <div class="editor" data-ot-toolbar="true" data-ot-theme="cave"></div>
4210
+ * OverType.initFromData('.editor', { fontSize: '14px' });
4211
+ */
4212
+ static initFromData(selector, defaults = {}) {
4213
+ const elements = document.querySelectorAll(selector);
4214
+ return Array.from(elements).map((el) => {
4215
+ const options = { ...defaults };
4216
+ for (const attr of el.attributes) {
4217
+ if (attr.name.startsWith("data-ot-")) {
4218
+ const kebab = attr.name.slice(8);
4219
+ const key = kebab.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
4220
+ options[key] = _OverType._parseDataValue(attr.value);
4221
+ }
4222
+ }
4223
+ return new _OverType(el, options);
4224
+ });
4225
+ }
4226
+ /**
4227
+ * Parse a data attribute value to the appropriate type
4228
+ * @private
4229
+ */
4230
+ static _parseDataValue(value) {
4231
+ if (value === "true")
4232
+ return true;
4233
+ if (value === "false")
4234
+ return false;
4235
+ if (value === "null")
4236
+ return null;
4237
+ if (value !== "" && !isNaN(Number(value)))
4238
+ return Number(value);
4239
+ return value;
4240
+ }
4156
4241
  /**
4157
4242
  * Get instance from element
4158
4243
  * @param {Element} element - DOM element
@@ -4253,6 +4338,32 @@ ${blockSuffix}` : suffix;
4253
4338
  }
4254
4339
  });
4255
4340
  }
4341
+ /**
4342
+ * Set custom syntax processor for extending markdown parsing
4343
+ * @param {Function|null} processor - Function that takes (html) and returns modified HTML
4344
+ * @example
4345
+ * OverType.setCustomSyntax((html) => {
4346
+ * // Highlight footnote references [^1]
4347
+ * return html.replace(/\[\^(\w+)\]/g, '<span class="footnote-ref">$&</span>');
4348
+ * });
4349
+ */
4350
+ static setCustomSyntax(processor) {
4351
+ MarkdownParser.setCustomSyntax(processor);
4352
+ document.querySelectorAll(".overtype-wrapper").forEach((wrapper) => {
4353
+ const instance = wrapper._instance;
4354
+ if (instance && instance.updatePreview) {
4355
+ instance.updatePreview();
4356
+ }
4357
+ });
4358
+ document.querySelectorAll("overtype-editor").forEach((webComponent) => {
4359
+ if (typeof webComponent.getEditor === "function") {
4360
+ const instance = webComponent.getEditor();
4361
+ if (instance && instance.updatePreview) {
4362
+ instance.updatePreview();
4363
+ }
4364
+ }
4365
+ });
4366
+ }
4256
4367
  /**
4257
4368
  * Initialize global event listeners
4258
4369
  */
@@ -4323,6 +4434,9 @@ ${blockSuffix}` : suffix;
4323
4434
  */
4324
4435
 
4325
4436
  if (typeof window !== "undefined" && typeof window.document !== "undefined") {
4437
+ // Extract exports BEFORE reassigning OverType (var OverType is window.OverType)
4438
+ window.toolbarButtons = OverType.toolbarButtons;
4439
+ window.defaultToolbarButtons = OverType.defaultToolbarButtons;
4326
4440
  window.OverType = OverType.default ? OverType.default : OverType;
4327
4441
  }
4328
4442