overtype 1.2.2 → 1.2.4

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/src/toolbar.js CHANGED
@@ -7,10 +7,67 @@ import * as icons from './icons.js';
7
7
  import * as markdownActions from 'markdown-actions';
8
8
 
9
9
  export class Toolbar {
10
- constructor(editor) {
10
+ constructor(editor, buttonConfig = null) {
11
11
  this.editor = editor;
12
12
  this.container = null;
13
13
  this.buttons = {};
14
+ this.buttonConfig = buttonConfig;
15
+ }
16
+
17
+ /**
18
+ * Check if cursor/selection is inside a markdown link
19
+ * @param {HTMLTextAreaElement} textarea - The textarea element
20
+ * @returns {boolean} True if inside a link
21
+ */
22
+ isInsideLink(textarea) {
23
+ const value = textarea.value;
24
+ const start = textarea.selectionStart;
25
+ const end = textarea.selectionEnd;
26
+
27
+ // Look backwards for [ and forwards for ](
28
+ let insideLink = false;
29
+ let openBracket = -1;
30
+ let closeBracket = -1;
31
+
32
+ // Find the nearest [ before cursor
33
+ for (let i = start - 1; i >= 0; i--) {
34
+ if (value[i] === '[') {
35
+ openBracket = i;
36
+ break;
37
+ }
38
+ if (value[i] === '\n') {
39
+ break; // Links don't span lines
40
+ }
41
+ }
42
+
43
+ // Find the nearest ]( after cursor
44
+ if (openBracket >= 0) {
45
+ for (let i = end; i < value.length - 1; i++) {
46
+ if (value[i] === ']' && value[i + 1] === '(') {
47
+ closeBracket = i;
48
+ break;
49
+ }
50
+ if (value[i] === '\n') {
51
+ break; // Links don't span lines
52
+ }
53
+ }
54
+ }
55
+
56
+ // Check if we're inside [...](...)
57
+ if (openBracket >= 0 && closeBracket >= 0) {
58
+ // Also need to verify the ) exists after ](
59
+ for (let i = closeBracket + 2; i < value.length; i++) {
60
+ if (value[i] === ')') {
61
+ insideLink = true;
62
+ break;
63
+ }
64
+ if (value[i] === '\n' || value[i] === ' ') {
65
+ break; // URLs typically don't have spaces or newlines
66
+ }
67
+ }
68
+ }
69
+
70
+ return insideLink;
14
71
  }
15
72
 
16
73
  /**
@@ -24,7 +81,7 @@ export class Toolbar {
24
81
  this.container.setAttribute('aria-label', 'Text formatting');
25
82
 
26
83
  // Define toolbar buttons
27
- const buttonConfig = [
84
+ const buttonConfig = this.buttonConfig ?? [
28
85
  { name: 'bold', icon: icons.boldIcon, title: 'Bold (Ctrl+B)', action: 'toggleBold' },
29
86
  { name: 'italic', icon: icons.italicIcon, title: 'Italic (Ctrl+I)', action: 'toggleItalic' },
30
87
  { separator: true },
@@ -136,6 +193,10 @@ export class Toolbar {
136
193
  markdownActions.insertLink(textarea);
137
194
  break;
138
195
  case 'toggleCode':
196
+ // Don't allow code formatting inside links
197
+ if (this.isInsideLink(textarea)) {
198
+ return;
199
+ }
139
200
  markdownActions.toggleCode(textarea);
140
201
  break;
141
202
  case 'toggleBulletList':