markdown-actions 1.0.0 → 1.0.2

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.
@@ -15,8 +15,58 @@ var __spreadValues = (a, b) => {
15
15
  return a;
16
16
  };
17
17
 
18
- // src/core/style-args.js
19
- function getDefaultStyleArgs() {
18
+ // src/core/formats.js
19
+ var FORMATS = {
20
+ bold: {
21
+ prefix: "**",
22
+ suffix: "**",
23
+ trimFirst: true
24
+ },
25
+ italic: {
26
+ prefix: "_",
27
+ suffix: "_",
28
+ trimFirst: true
29
+ },
30
+ code: {
31
+ prefix: "`",
32
+ suffix: "`",
33
+ blockPrefix: "```",
34
+ blockSuffix: "```"
35
+ },
36
+ link: {
37
+ prefix: "[",
38
+ suffix: "](url)",
39
+ replaceNext: "url",
40
+ scanFor: "https?://"
41
+ },
42
+ bulletList: {
43
+ prefix: "- ",
44
+ multiline: true,
45
+ unorderedList: true
46
+ },
47
+ numberedList: {
48
+ prefix: "1. ",
49
+ multiline: true,
50
+ orderedList: true
51
+ },
52
+ quote: {
53
+ prefix: "> ",
54
+ multiline: true,
55
+ surroundWithNewlines: true
56
+ },
57
+ taskList: {
58
+ prefix: "- [ ] ",
59
+ multiline: true,
60
+ surroundWithNewlines: true
61
+ },
62
+ header1: { prefix: "# " },
63
+ header2: { prefix: "## " },
64
+ header3: { prefix: "### " },
65
+ header4: { prefix: "#### " },
66
+ header5: { prefix: "##### " },
67
+ header6: { prefix: "###### " }
68
+ };
69
+ function getDefaultStyle() {
20
70
  return {
21
71
  prefix: "",
22
72
  suffix: "",
@@ -32,17 +82,155 @@ function getDefaultStyleArgs() {
32
82
  trimFirst: false
33
83
  };
34
84
  }
35
- function mergeStyleWithDefaults(style) {
36
- return __spreadValues(__spreadValues({}, getDefaultStyleArgs()), style);
85
+ function mergeWithDefaults(format) {
86
+ return __spreadValues(__spreadValues({}, getDefaultStyle()), format);
37
87
  }
38
88
 
39
- // src/core/selection-new.js
89
+ // src/debug.js
90
+ var debugMode = false;
91
+ function setDebugMode(enabled) {
92
+ debugMode = enabled;
93
+ }
94
+ function getDebugMode() {
95
+ return debugMode;
96
+ }
97
+ function debugLog(funcName, message, data) {
98
+ if (!debugMode)
99
+ return;
100
+ console.group(`\u{1F50D} ${funcName}`);
101
+ console.log(message);
102
+ if (data) {
103
+ console.log("Data:", data);
104
+ }
105
+ console.groupEnd();
106
+ }
107
+ function debugSelection(textarea, label) {
108
+ if (!debugMode)
109
+ return;
110
+ const selected = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);
111
+ console.group(`\u{1F4CD} Selection: ${label}`);
112
+ console.log("Position:", `${textarea.selectionStart}-${textarea.selectionEnd}`);
113
+ console.log("Selected text:", JSON.stringify(selected));
114
+ console.log("Length:", selected.length);
115
+ const before = textarea.value.slice(Math.max(0, textarea.selectionStart - 10), textarea.selectionStart);
116
+ const after = textarea.value.slice(textarea.selectionEnd, Math.min(textarea.value.length, textarea.selectionEnd + 10));
117
+ console.log("Context:", JSON.stringify(before) + "[SELECTION]" + JSON.stringify(after));
118
+ console.groupEnd();
119
+ }
120
+ function debugResult(result) {
121
+ if (!debugMode)
122
+ return;
123
+ console.group("\u{1F4DD} Result");
124
+ console.log("Text to insert:", JSON.stringify(result.text));
125
+ console.log("New selection:", `${result.selectionStart}-${result.selectionEnd}`);
126
+ console.groupEnd();
127
+ }
128
+
129
+ // src/core/insertion.js
130
+ var canInsertText = null;
131
+ function insertText(textarea, { text, selectionStart, selectionEnd }) {
132
+ const debugMode2 = getDebugMode();
133
+ if (debugMode2) {
134
+ console.group("\u{1F527} insertText");
135
+ console.log("Current selection:", `${textarea.selectionStart}-${textarea.selectionEnd}`);
136
+ console.log("Text to insert:", JSON.stringify(text));
137
+ console.log("New selection to set:", selectionStart, "-", selectionEnd);
138
+ }
139
+ textarea.focus();
140
+ const originalSelectionStart = textarea.selectionStart;
141
+ const originalSelectionEnd = textarea.selectionEnd;
142
+ const before = textarea.value.slice(0, originalSelectionStart);
143
+ const after = textarea.value.slice(originalSelectionEnd);
144
+ if (debugMode2) {
145
+ console.log("Before text (last 20):", JSON.stringify(before.slice(-20)));
146
+ console.log("After text (first 20):", JSON.stringify(after.slice(0, 20)));
147
+ console.log("Selected text being replaced:", JSON.stringify(textarea.value.slice(originalSelectionStart, originalSelectionEnd)));
148
+ }
149
+ const originalValue = textarea.value;
150
+ const hasSelection = originalSelectionStart !== originalSelectionEnd;
151
+ if (!hasSelection && (canInsertText === null || canInsertText === true)) {
152
+ textarea.contentEditable = "true";
153
+ try {
154
+ canInsertText = document.execCommand("insertText", false, text);
155
+ } catch (error) {
156
+ canInsertText = false;
157
+ }
158
+ textarea.contentEditable = "false";
159
+ } else if (hasSelection) {
160
+ if (debugMode2)
161
+ console.log("Has selection, skipping execCommand and using manual mode");
162
+ canInsertText = false;
163
+ }
164
+ if (debugMode2) {
165
+ console.log("canInsertText before:", canInsertText);
166
+ console.log("execCommand result:", canInsertText);
167
+ }
168
+ if (canInsertText) {
169
+ const expectedValue = before + text + after;
170
+ const actualValue = textarea.value;
171
+ if (debugMode2) {
172
+ console.log("Expected length:", expectedValue.length);
173
+ console.log("Actual length:", actualValue.length);
174
+ }
175
+ if (actualValue !== expectedValue) {
176
+ if (debugMode2) {
177
+ console.log("execCommand changed the value but not as expected");
178
+ console.log("Expected:", JSON.stringify(expectedValue.slice(0, 100)));
179
+ console.log("Actual:", JSON.stringify(actualValue.slice(0, 100)));
180
+ }
181
+ }
182
+ }
183
+ if (!canInsertText) {
184
+ if (debugMode2)
185
+ console.log("Using manual insertion");
186
+ if (textarea.value === originalValue) {
187
+ if (debugMode2)
188
+ console.log("Value unchanged, doing manual replacement");
189
+ try {
190
+ document.execCommand("ms-beginUndoUnit");
191
+ } catch (e) {
192
+ }
193
+ textarea.value = before + text + after;
194
+ try {
195
+ document.execCommand("ms-endUndoUnit");
196
+ } catch (e) {
197
+ }
198
+ textarea.dispatchEvent(new CustomEvent("input", { bubbles: true, cancelable: true }));
199
+ } else {
200
+ if (debugMode2)
201
+ console.log("Value was changed by execCommand, skipping manual insertion");
202
+ }
203
+ }
204
+ if (debugMode2)
205
+ console.log("Setting selection range:", selectionStart, selectionEnd);
206
+ if (selectionStart != null && selectionEnd != null) {
207
+ textarea.setSelectionRange(selectionStart, selectionEnd);
208
+ } else {
209
+ textarea.setSelectionRange(originalSelectionStart, textarea.selectionEnd);
210
+ }
211
+ if (debugMode2) {
212
+ console.log("Final value length:", textarea.value.length);
213
+ console.groupEnd();
214
+ }
215
+ }
216
+ function setUndoMethod(method) {
217
+ switch (method) {
218
+ case "native":
219
+ canInsertText = true;
220
+ break;
221
+ case "manual":
222
+ canInsertText = false;
223
+ break;
224
+ case "auto":
225
+ canInsertText = null;
226
+ break;
227
+ }
228
+ }
229
+
230
+ // src/core/selection.js
40
231
  function isMultipleLines(string) {
41
232
  return string.trim().split("\n").length > 1;
42
233
  }
43
- function repeat(string, n) {
44
- return Array(n + 1).join(string);
45
- }
46
234
  function wordSelectionStart(text, i) {
47
235
  let index = i;
48
236
  while (text[index] && text[index - 1] != null && !text[index - 1].match(/\s/)) {
@@ -67,7 +255,11 @@ function expandSelectionToLine(textarea) {
67
255
  textarea.selectionStart = counter;
68
256
  }
69
257
  if (textarea.selectionEnd >= counter && textarea.selectionEnd < counter + lineLength) {
70
- textarea.selectionEnd = counter + lineLength - 1;
258
+ if (index === lines.length - 1) {
259
+ textarea.selectionEnd = Math.min(counter + lines[index].length, textarea.value.length);
260
+ } else {
261
+ textarea.selectionEnd = counter + lineLength - 1;
262
+ }
71
263
  }
72
264
  counter += lineLength;
73
265
  }
@@ -95,19 +287,13 @@ function newlinesToSurroundSelectedText(textarea) {
95
287
  const breaksAfter = afterSelection.match(/^\n*/);
96
288
  const newlinesBeforeSelection = breaksBefore ? breaksBefore[0].length : 0;
97
289
  const newlinesAfterSelection = breaksAfter ? breaksAfter[0].length : 0;
98
- let newlinesToAppend;
99
- let newlinesToPrepend;
290
+ let newlinesToAppend = "";
291
+ let newlinesToPrepend = "";
100
292
  if (beforeSelection.match(/\S/) && newlinesBeforeSelection < 2) {
101
- newlinesToAppend = repeat("\n", 2 - newlinesBeforeSelection);
293
+ newlinesToAppend = "\n".repeat(2 - newlinesBeforeSelection);
102
294
  }
103
295
  if (afterSelection.match(/\S/) && newlinesAfterSelection < 2) {
104
- newlinesToPrepend = repeat("\n", 2 - newlinesAfterSelection);
105
- }
106
- if (newlinesToAppend == null) {
107
- newlinesToAppend = "";
108
- }
109
- if (newlinesToPrepend == null) {
110
- newlinesToPrepend = "";
296
+ newlinesToPrepend = "\n".repeat(2 - newlinesAfterSelection);
111
297
  }
112
298
  return { newlinesToAppend, newlinesToPrepend };
113
299
  }
@@ -120,64 +306,52 @@ function preserveSelection(textarea, callback) {
120
306
  textarea.selectionEnd = end;
121
307
  textarea.scrollTop = scrollTop;
122
308
  }
123
-
124
- // src/core/insertion-new.js
125
- var canInsertText = null;
126
- function insertText(textarea, { text, selectionStart, selectionEnd }) {
127
- const originalSelectionStart = textarea.selectionStart;
128
- const before = textarea.value.slice(0, originalSelectionStart);
129
- const after = textarea.value.slice(textarea.selectionEnd);
130
- if (canInsertText === null || canInsertText === true) {
131
- textarea.contentEditable = "true";
132
- try {
133
- canInsertText = document.execCommand("insertText", false, text);
134
- } catch (error) {
135
- canInsertText = false;
136
- }
137
- textarea.contentEditable = "false";
138
- }
139
- if (canInsertText && !textarea.value.slice(0, textarea.selectionStart).endsWith(text)) {
140
- canInsertText = false;
141
- }
142
- if (!canInsertText) {
143
- try {
144
- document.execCommand("ms-beginUndoUnit");
145
- } catch (e) {
309
+ function applyLineOperation(textarea, operation, options = {}) {
310
+ const originalStart = textarea.selectionStart;
311
+ const originalEnd = textarea.selectionEnd;
312
+ const noInitialSelection = originalStart === originalEnd;
313
+ if (noInitialSelection) {
314
+ const value = textarea.value;
315
+ const start = originalStart;
316
+ let lineStart = start;
317
+ let lineEnd = start;
318
+ while (lineStart > 0 && value[lineStart - 1] !== "\n") {
319
+ lineStart--;
146
320
  }
147
- textarea.value = before + text + after;
148
- try {
149
- document.execCommand("ms-endUndoUnit");
150
- } catch (e) {
321
+ while (lineEnd < value.length && value[lineEnd] !== "\n") {
322
+ lineEnd++;
151
323
  }
152
- textarea.dispatchEvent(new CustomEvent("input", { bubbles: true, cancelable: true }));
153
- }
154
- if (selectionStart != null && selectionEnd != null) {
155
- textarea.setSelectionRange(selectionStart, selectionEnd);
324
+ textarea.selectionStart = lineStart;
325
+ textarea.selectionEnd = lineEnd;
156
326
  } else {
157
- textarea.setSelectionRange(originalSelectionStart, textarea.selectionEnd);
327
+ expandSelectionToLine(textarea);
158
328
  }
159
- }
160
- function setUndoMethod(method) {
161
- if (method === "native") {
162
- canInsertText = true;
163
- } else if (method === "manual") {
164
- canInsertText = false;
165
- } else {
166
- canInsertText = null;
329
+ const result = operation(textarea);
330
+ if (noInitialSelection && options.prefix) {
331
+ const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);
332
+ const isRemoving = selectedText.startsWith(options.prefix);
333
+ if (isRemoving) {
334
+ result.selectionStart = Math.max(originalStart - options.prefix.length, textarea.selectionStart);
335
+ result.selectionEnd = result.selectionStart;
336
+ } else {
337
+ result.selectionStart = originalStart + options.prefix.length;
338
+ result.selectionEnd = result.selectionStart;
339
+ }
167
340
  }
341
+ return result;
168
342
  }
169
343
 
170
- // src/operations/block-new.js
171
- function blockStyle(textarea, arg) {
344
+ // src/operations/block.js
345
+ function blockStyle(textarea, style) {
172
346
  let newlinesToAppend;
173
347
  let newlinesToPrepend;
174
- const { prefix, suffix, blockPrefix, blockSuffix, replaceNext, prefixSpace, scanFor, surroundWithNewlines } = arg;
348
+ const { prefix, suffix, blockPrefix, blockSuffix, replaceNext, prefixSpace, scanFor, surroundWithNewlines, trimFirst } = style;
175
349
  const originalSelectionStart = textarea.selectionStart;
176
350
  const originalSelectionEnd = textarea.selectionEnd;
177
351
  let selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);
178
- let prefixToUse = isMultipleLines(selectedText) && blockPrefix.length > 0 ? `${blockPrefix}
352
+ let prefixToUse = isMultipleLines(selectedText) && blockPrefix && blockPrefix.length > 0 ? `${blockPrefix}
179
353
  ` : prefix;
180
- let suffixToUse = isMultipleLines(selectedText) && blockSuffix.length > 0 ? `
354
+ let suffixToUse = isMultipleLines(selectedText) && blockSuffix && blockSuffix.length > 0 ? `
181
355
  ${blockSuffix}` : suffix;
182
356
  if (prefixSpace) {
183
357
  const beforeSelection = textarea.value[textarea.selectionStart - 1];
@@ -185,10 +359,10 @@ ${blockSuffix}` : suffix;
185
359
  prefixToUse = ` ${prefixToUse}`;
186
360
  }
187
361
  }
188
- selectedText = expandSelectedText(textarea, prefixToUse, suffixToUse, arg.multiline);
362
+ selectedText = expandSelectedText(textarea, prefixToUse, suffixToUse, style.multiline);
189
363
  let selectionStart = textarea.selectionStart;
190
364
  let selectionEnd = textarea.selectionEnd;
191
- const hasReplaceNext = replaceNext.length > 0 && suffixToUse.indexOf(replaceNext) > -1 && selectedText.length > 0;
365
+ const hasReplaceNext = replaceNext && replaceNext.length > 0 && suffixToUse.indexOf(replaceNext) > -1 && selectedText.length > 0;
192
366
  if (surroundWithNewlines) {
193
367
  const ref = newlinesToSurroundSelectedText(textarea);
194
368
  newlinesToAppend = ref.newlinesToAppend;
@@ -212,7 +386,7 @@ ${blockSuffix}` : suffix;
212
386
  selectionStart = originalSelectionStart + prefixToUse.length;
213
387
  selectionEnd = originalSelectionEnd + prefixToUse.length;
214
388
  const whitespaceEdges = selectedText.match(/^\s*|\s*$/g);
215
- if (arg.trimFirst && whitespaceEdges) {
389
+ if (trimFirst && whitespaceEdges) {
216
390
  const leadingWhitespace = whitespaceEdges[0] || "";
217
391
  const trailingWhitespace = whitespaceEdges[1] || "";
218
392
  replacementText = leadingWhitespace + prefixToUse + selectedText.trim() + suffixToUse + trailingWhitespace;
@@ -220,9 +394,9 @@ ${blockSuffix}` : suffix;
220
394
  selectionEnd -= trailingWhitespace.length;
221
395
  }
222
396
  return { text: replacementText, selectionStart, selectionEnd };
223
- } else if (scanFor.length > 0 && selectedText.match(scanFor)) {
397
+ } else if (scanFor && scanFor.length > 0 && selectedText.match(scanFor)) {
224
398
  suffixToUse = suffixToUse.replace(replaceNext, selectedText);
225
- const replacementText = prefixToUse + selectedText + suffixToUse;
399
+ const replacementText = prefixToUse + suffixToUse;
226
400
  selectionStart = selectionEnd = selectionStart + prefixToUse.length;
227
401
  return { text: replacementText, selectionStart, selectionEnd };
228
402
  } else {
@@ -232,18 +406,24 @@ ${blockSuffix}` : suffix;
232
406
  return { text: replacementText, selectionStart, selectionEnd };
233
407
  }
234
408
  }
235
- function multilineStyle(textarea, arg) {
236
- const { prefix, suffix, surroundWithNewlines } = arg;
409
+ function multilineStyle(textarea, style) {
410
+ const { prefix, suffix, surroundWithNewlines } = style;
237
411
  let text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);
238
412
  let selectionStart = textarea.selectionStart;
239
413
  let selectionEnd = textarea.selectionEnd;
240
414
  const lines = text.split("\n");
241
- const undoStyle = lines.every((line) => line.startsWith(prefix) && line.endsWith(suffix));
415
+ const undoStyle = lines.every((line) => line.startsWith(prefix) && (!suffix || line.endsWith(suffix)));
242
416
  if (undoStyle) {
243
- text = lines.map((line) => line.slice(prefix.length, line.length - suffix.length)).join("\n");
417
+ text = lines.map((line) => {
418
+ let result = line.slice(prefix.length);
419
+ if (suffix) {
420
+ result = result.slice(0, result.length - suffix.length);
421
+ }
422
+ return result;
423
+ }).join("\n");
244
424
  selectionEnd = selectionStart + text.length;
245
425
  } else {
246
- text = lines.map((line) => prefix + line + suffix).join("\n");
426
+ text = lines.map((line) => prefix + line + (suffix || "")).join("\n");
247
427
  if (surroundWithNewlines) {
248
428
  const { newlinesToAppend, newlinesToPrepend } = newlinesToSurroundSelectedText(textarea);
249
429
  selectionStart += newlinesToAppend.length;
@@ -254,7 +434,7 @@ function multilineStyle(textarea, arg) {
254
434
  return { text, selectionStart, selectionEnd };
255
435
  }
256
436
 
257
- // src/operations/list-new.js
437
+ // src/operations/list.js
258
438
  function undoOrderedListStyle(text) {
259
439
  const lines = text.split("\n");
260
440
  const orderedListRegex = /^\d+\.\s+/;
@@ -274,7 +454,7 @@ function undoUnorderedListStyle(text) {
274
454
  const shouldUndoUnorderedList = lines.every((line) => line.startsWith(unorderedListPrefix));
275
455
  let result = lines;
276
456
  if (shouldUndoUnorderedList) {
277
- result = lines.map((line) => line.slice(unorderedListPrefix.length, line.length));
457
+ result = lines.map((line) => line.slice(unorderedListPrefix.length));
278
458
  }
279
459
  return {
280
460
  text: result.join("\n"),
@@ -289,19 +469,19 @@ function makePrefix(index, unorderedList) {
289
469
  }
290
470
  }
291
471
  function clearExistingListStyle(style, selectedText) {
292
- let undoResultOpositeList;
293
472
  let undoResult;
473
+ let undoResultOppositeList;
294
474
  let pristineText;
295
475
  if (style.orderedList) {
296
476
  undoResult = undoOrderedListStyle(selectedText);
297
- undoResultOpositeList = undoUnorderedListStyle(undoResult.text);
298
- pristineText = undoResultOpositeList.text;
477
+ undoResultOppositeList = undoUnorderedListStyle(undoResult.text);
478
+ pristineText = undoResultOppositeList.text;
299
479
  } else {
300
480
  undoResult = undoUnorderedListStyle(selectedText);
301
- undoResultOpositeList = undoOrderedListStyle(undoResult.text);
302
- pristineText = undoResultOpositeList.text;
481
+ undoResultOppositeList = undoOrderedListStyle(undoResult.text);
482
+ pristineText = undoResultOppositeList.text;
303
483
  }
304
- return [undoResult, undoResultOpositeList, pristineText];
484
+ return [undoResult, undoResultOppositeList, pristineText];
305
485
  }
306
486
  function listStyle(textarea, style) {
307
487
  const noInitialSelection = textarea.selectionStart === textarea.selectionEnd;
@@ -309,14 +489,14 @@ function listStyle(textarea, style) {
309
489
  let selectionEnd = textarea.selectionEnd;
310
490
  expandSelectionToLine(textarea);
311
491
  const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);
312
- const [undoResult, undoResultOpositeList, pristineText] = clearExistingListStyle(style, selectedText);
492
+ const [undoResult, undoResultOppositeList, pristineText] = clearExistingListStyle(style, selectedText);
313
493
  const prefixedLines = pristineText.split("\n").map((value, index) => {
314
494
  return `${makePrefix(index, style.unorderedList)}${value}`;
315
495
  });
316
496
  const totalPrefixLength = prefixedLines.reduce((previousValue, _currentValue, currentIndex) => {
317
497
  return previousValue + makePrefix(currentIndex, style.unorderedList).length;
318
498
  }, 0);
319
- const totalPrefixLengthOpositeList = prefixedLines.reduce((previousValue, _currentValue, currentIndex) => {
499
+ const totalPrefixLengthOppositeList = prefixedLines.reduce((previousValue, _currentValue, currentIndex) => {
320
500
  return previousValue + makePrefix(currentIndex, !style.unorderedList).length;
321
501
  }, 0);
322
502
  if (undoResult.processed) {
@@ -335,9 +515,9 @@ function listStyle(textarea, style) {
335
515
  selectionStart = Math.max(selectionStart + makePrefix(0, style.unorderedList).length + newlinesToAppend.length, 0);
336
516
  selectionEnd = selectionStart;
337
517
  } else {
338
- if (undoResultOpositeList.processed) {
518
+ if (undoResultOppositeList.processed) {
339
519
  selectionStart = Math.max(textarea.selectionStart + newlinesToAppend.length, 0);
340
- selectionEnd = textarea.selectionEnd + newlinesToAppend.length + totalPrefixLength - totalPrefixLengthOpositeList;
520
+ selectionEnd = textarea.selectionEnd + newlinesToAppend.length + totalPrefixLength - totalPrefixLengthOppositeList;
341
521
  } else {
342
522
  selectionStart = Math.max(textarea.selectionStart + newlinesToAppend.length, 0);
343
523
  selectionEnd = textarea.selectionEnd + newlinesToAppend.length + totalPrefixLength;
@@ -345,18 +525,10 @@ function listStyle(textarea, style) {
345
525
  }
346
526
  return { text, selectionStart, selectionEnd };
347
527
  }
348
-
349
- // src/core/style-text.js
350
- function styleSelectedText(textarea, styleArgs) {
351
- const text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);
352
- let result;
353
- if (styleArgs.orderedList || styleArgs.unorderedList) {
354
- result = listStyle(textarea, styleArgs);
355
- } else if (styleArgs.multiline && isMultipleLines(text)) {
356
- result = multilineStyle(textarea, styleArgs);
357
- } else {
358
- result = blockStyle(textarea, styleArgs);
359
- }
528
+ function applyListStyle(textarea, style) {
529
+ const originalStart = textarea.selectionStart;
530
+ const originalEnd = textarea.selectionEnd;
531
+ const result = listStyle(textarea, style);
360
532
  insertText(textarea, result);
361
533
  }
362
534
 
@@ -441,107 +613,146 @@ function hasFormat(textarea, format) {
441
613
  const activeFormats = getActiveFormats(textarea);
442
614
  return activeFormats.includes(format);
443
615
  }
444
-
445
- // src/index-new.js
446
- var FORMATS2 = {
447
- bold: { prefix: "**", suffix: "**", trimFirst: true },
448
- italic: { prefix: "_", suffix: "_", trimFirst: true },
449
- code: {
450
- prefix: "`",
451
- suffix: "`",
452
- blockPrefix: "```",
453
- blockSuffix: "```"
454
- },
455
- link: {
456
- prefix: "[",
457
- suffix: "](url)",
458
- replaceNext: "url",
459
- scanFor: "https?://"
460
- },
461
- quote: {
462
- prefix: "> ",
463
- multiline: true,
464
- surroundWithNewlines: true
465
- },
466
- bulletList: {
467
- prefix: "- ",
468
- multiline: true,
469
- unorderedList: true
470
- },
471
- numberedList: {
472
- prefix: "1. ",
473
- multiline: true,
474
- orderedList: true
475
- },
476
- header1: { prefix: "# " },
477
- header2: { prefix: "## " },
478
- header3: { prefix: "### " },
479
- header4: { prefix: "#### " },
480
- header5: { prefix: "##### " },
481
- header6: { prefix: "###### " }
482
- };
483
- function applyStyle(textarea, format) {
484
- const style = mergeStyleWithDefaults(format);
485
- textarea.focus();
486
- styleSelectedText(textarea, style);
616
+ function expandSelection(textarea, options = {}) {
617
+ if (!textarea)
618
+ return;
619
+ const { toWord, toLine, toFormat } = options;
620
+ const { selectionStart, selectionEnd, value } = textarea;
621
+ if (toLine) {
622
+ const lines = value.split("\n");
623
+ let lineStart = 0;
624
+ let lineEnd = 0;
625
+ let currentPos = 0;
626
+ for (const line of lines) {
627
+ if (selectionStart >= currentPos && selectionStart <= currentPos + line.length) {
628
+ lineStart = currentPos;
629
+ lineEnd = currentPos + line.length;
630
+ break;
631
+ }
632
+ currentPos += line.length + 1;
633
+ }
634
+ textarea.selectionStart = lineStart;
635
+ textarea.selectionEnd = lineEnd;
636
+ } else if (toWord && selectionStart === selectionEnd) {
637
+ let start = selectionStart;
638
+ let end = selectionEnd;
639
+ while (start > 0 && !/\s/.test(value[start - 1])) {
640
+ start--;
641
+ }
642
+ while (end < value.length && !/\s/.test(value[end])) {
643
+ end++;
644
+ }
645
+ textarea.selectionStart = start;
646
+ textarea.selectionEnd = end;
647
+ }
487
648
  }
649
+
650
+ // src/index.js
488
651
  function toggleBold(textarea) {
489
652
  if (!textarea || textarea.disabled || textarea.readOnly)
490
653
  return;
491
- applyStyle(textarea, FORMATS2.bold);
654
+ debugLog("toggleBold", "Starting");
655
+ debugSelection(textarea, "Before");
656
+ const style = mergeWithDefaults(FORMATS.bold);
657
+ const result = blockStyle(textarea, style);
658
+ debugResult(result);
659
+ insertText(textarea, result);
660
+ debugSelection(textarea, "After");
492
661
  }
493
662
  function toggleItalic(textarea) {
494
663
  if (!textarea || textarea.disabled || textarea.readOnly)
495
664
  return;
496
- applyStyle(textarea, FORMATS2.italic);
665
+ const style = mergeWithDefaults(FORMATS.italic);
666
+ const result = blockStyle(textarea, style);
667
+ insertText(textarea, result);
497
668
  }
498
669
  function toggleCode(textarea) {
499
670
  if (!textarea || textarea.disabled || textarea.readOnly)
500
671
  return;
501
- applyStyle(textarea, FORMATS2.code);
672
+ const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);
673
+ const style = mergeWithDefaults(FORMATS.code);
674
+ let result;
675
+ if (isMultipleLines(selectedText)) {
676
+ const blockStyle2 = {
677
+ prefix: "```\n",
678
+ suffix: "\n```",
679
+ surroundWithNewlines: true
680
+ };
681
+ result = multilineStyle(textarea, mergeWithDefaults(blockStyle2));
682
+ } else {
683
+ result = blockStyle(textarea, style);
684
+ }
685
+ insertText(textarea, result);
502
686
  }
503
687
  function insertLink(textarea, options = {}) {
504
688
  if (!textarea || textarea.disabled || textarea.readOnly)
505
689
  return;
506
- let format = __spreadValues({}, FORMATS2.link);
690
+ const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);
691
+ let style = mergeWithDefaults(FORMATS.link);
507
692
  if (options.url) {
508
- format.suffix = `](${options.url})`;
509
- format.replaceNext = "";
693
+ style.suffix = `](${options.url})`;
694
+ style.replaceNext = "";
510
695
  }
511
- if (options.text && !textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)) {
696
+ if (options.text && !selectedText) {
512
697
  const pos = textarea.selectionStart;
513
698
  textarea.value = textarea.value.slice(0, pos) + options.text + textarea.value.slice(pos);
514
699
  textarea.selectionStart = pos;
515
700
  textarea.selectionEnd = pos + options.text.length;
516
701
  }
517
- applyStyle(textarea, format);
702
+ const result = blockStyle(textarea, style);
703
+ insertText(textarea, result);
518
704
  }
519
705
  function toggleBulletList(textarea) {
520
706
  if (!textarea || textarea.disabled || textarea.readOnly)
521
707
  return;
522
- applyStyle(textarea, FORMATS2.bulletList);
708
+ const style = mergeWithDefaults(FORMATS.bulletList);
709
+ applyListStyle(textarea, style);
523
710
  }
524
711
  function toggleNumberedList(textarea) {
525
712
  if (!textarea || textarea.disabled || textarea.readOnly)
526
713
  return;
527
- applyStyle(textarea, FORMATS2.numberedList);
714
+ const style = mergeWithDefaults(FORMATS.numberedList);
715
+ applyListStyle(textarea, style);
528
716
  }
529
717
  function toggleQuote(textarea) {
530
718
  if (!textarea || textarea.disabled || textarea.readOnly)
531
719
  return;
532
- applyStyle(textarea, FORMATS2.quote);
720
+ debugLog("toggleQuote", "Starting");
721
+ debugSelection(textarea, "Initial");
722
+ const style = mergeWithDefaults(FORMATS.quote);
723
+ const result = applyLineOperation(
724
+ textarea,
725
+ (ta) => multilineStyle(ta, style),
726
+ { prefix: style.prefix }
727
+ );
728
+ debugResult(result);
729
+ insertText(textarea, result);
730
+ debugSelection(textarea, "Final");
533
731
  }
534
- function insertHeader(textarea, level = 1) {
732
+ function toggleTaskList(textarea) {
733
+ if (!textarea || textarea.disabled || textarea.readOnly)
734
+ return;
735
+ const style = mergeWithDefaults(FORMATS.taskList);
736
+ const result = applyLineOperation(
737
+ textarea,
738
+ (ta) => multilineStyle(ta, style),
739
+ { prefix: style.prefix }
740
+ );
741
+ insertText(textarea, result);
742
+ }
743
+ function insertHeader(textarea, level = 1, toggle = false) {
535
744
  if (!textarea || textarea.disabled || textarea.readOnly)
536
745
  return;
537
746
  if (level < 1 || level > 6)
538
747
  level = 1;
539
- const headerKey = `header${level}`;
540
- const format = FORMATS2[headerKey] || FORMATS2.header1;
748
+ const originalStart = textarea.selectionStart;
749
+ const originalEnd = textarea.selectionEnd;
750
+ const noInitialSelection = originalStart === originalEnd;
751
+ const headerKey = `header${level === 1 ? "1" : level}`;
752
+ const style = mergeWithDefaults(FORMATS[headerKey] || FORMATS.header1);
541
753
  const value = textarea.value;
542
- const start = textarea.selectionStart;
543
- let lineStart = start;
544
- let lineEnd = start;
754
+ let lineStart = originalStart;
755
+ let lineEnd = originalStart;
545
756
  while (lineStart > 0 && value[lineStart - 1] !== "\n") {
546
757
  lineStart--;
547
758
  }
@@ -551,12 +762,63 @@ function insertHeader(textarea, level = 1) {
551
762
  textarea.selectionStart = lineStart;
552
763
  textarea.selectionEnd = lineEnd;
553
764
  const currentLine = value.slice(lineStart, lineEnd);
765
+ const existingHeaderMatch = currentLine.match(/^(#{1,6})\s*/);
766
+ const existingPrefixLength = existingHeaderMatch ? existingHeaderMatch[0].length : 0;
767
+ const existingLevel = existingHeaderMatch ? existingHeaderMatch[1].length : 0;
554
768
  const cleanedLine = currentLine.replace(/^#{1,6}\s*/, "");
555
- const newLine = format.prefix + cleanedLine;
556
- const tempSelection = textarea.selectionStart;
557
- textarea.value = value.slice(0, lineStart) + newLine + value.slice(lineEnd);
558
- textarea.selectionStart = lineStart + format.prefix.length;
559
- textarea.selectionEnd = lineStart + newLine.length;
769
+ let newLine;
770
+ let isRemoving = false;
771
+ if (toggle && existingLevel === level) {
772
+ newLine = cleanedLine;
773
+ isRemoving = true;
774
+ } else {
775
+ newLine = style.prefix + cleanedLine;
776
+ }
777
+ let selectionStart, selectionEnd;
778
+ if (noInitialSelection) {
779
+ const cursorOffsetInLine = originalStart - lineStart;
780
+ if (isRemoving) {
781
+ if (cursorOffsetInLine < existingPrefixLength) {
782
+ selectionStart = lineStart;
783
+ } else {
784
+ selectionStart = originalStart - existingPrefixLength;
785
+ }
786
+ } else if (existingPrefixLength > 0) {
787
+ if (cursorOffsetInLine < existingPrefixLength) {
788
+ selectionStart = lineStart + Math.min(cursorOffsetInLine, style.prefix.length);
789
+ } else {
790
+ const prefixDiff = style.prefix.length - existingPrefixLength;
791
+ selectionStart = originalStart + prefixDiff;
792
+ }
793
+ } else {
794
+ selectionStart = originalStart + style.prefix.length;
795
+ }
796
+ selectionStart = Math.min(selectionStart, lineStart + newLine.length);
797
+ selectionEnd = selectionStart;
798
+ } else {
799
+ if (isRemoving) {
800
+ selectionStart = lineStart;
801
+ selectionEnd = lineStart + newLine.length;
802
+ } else {
803
+ selectionStart = lineStart + style.prefix.length;
804
+ selectionEnd = lineStart + newLine.length;
805
+ }
806
+ }
807
+ const result = {
808
+ text: newLine,
809
+ selectionStart,
810
+ selectionEnd
811
+ };
812
+ insertText(textarea, result);
813
+ }
814
+ function toggleH1(textarea) {
815
+ insertHeader(textarea, 1, true);
816
+ }
817
+ function toggleH2(textarea) {
818
+ insertHeader(textarea, 2, true);
819
+ }
820
+ function toggleH3(textarea) {
821
+ insertHeader(textarea, 3, true);
560
822
  }
561
823
  function getActiveFormats2(textarea) {
562
824
  return getActiveFormats(textarea);
@@ -564,32 +826,27 @@ function getActiveFormats2(textarea) {
564
826
  function hasFormat2(textarea, format) {
565
827
  return hasFormat(textarea, format);
566
828
  }
567
- function expandSelection(textarea, options = {}) {
568
- if (!textarea)
569
- return;
570
- const { toWord, toLine } = options;
571
- const { selectionStart, selectionEnd, value } = textarea;
572
- if (toLine) {
573
- expandSelectionToLine(textarea);
574
- } else if (toWord && selectionStart === selectionEnd) {
575
- let start = selectionStart;
576
- let end = selectionEnd;
577
- while (start > 0 && !/\s/.test(value[start - 1])) {
578
- start--;
579
- }
580
- while (end < value.length && !/\s/.test(value[end])) {
581
- end++;
582
- }
583
- textarea.selectionStart = start;
584
- textarea.selectionEnd = end;
585
- }
829
+ function expandSelection2(textarea, options = {}) {
830
+ expandSelection(textarea, options);
586
831
  }
587
832
  function applyCustomFormat(textarea, format) {
588
833
  if (!textarea || textarea.disabled || textarea.readOnly)
589
834
  return;
590
- applyStyle(textarea, format);
835
+ const style = mergeWithDefaults(format);
836
+ let result;
837
+ if (style.multiline) {
838
+ const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);
839
+ if (isMultipleLines(selectedText)) {
840
+ result = multilineStyle(textarea, style);
841
+ } else {
842
+ result = blockStyle(textarea, style);
843
+ }
844
+ } else {
845
+ result = blockStyle(textarea, style);
846
+ }
847
+ insertText(textarea, result);
591
848
  }
592
- var index_new_default = {
849
+ var src_default = {
593
850
  toggleBold,
594
851
  toggleItalic,
595
852
  toggleCode,
@@ -597,29 +854,41 @@ var index_new_default = {
597
854
  toggleBulletList,
598
855
  toggleNumberedList,
599
856
  toggleQuote,
857
+ toggleTaskList,
600
858
  insertHeader,
859
+ toggleH1,
860
+ toggleH2,
861
+ toggleH3,
601
862
  getActiveFormats: getActiveFormats2,
602
863
  hasFormat: hasFormat2,
603
- expandSelection,
864
+ expandSelection: expandSelection2,
604
865
  applyCustomFormat,
605
866
  preserveSelection,
606
- setUndoMethod
867
+ setUndoMethod,
868
+ setDebugMode,
869
+ getDebugMode
607
870
  };
608
871
  export {
609
872
  applyCustomFormat,
610
- index_new_default as default,
611
- expandSelection,
873
+ src_default as default,
874
+ expandSelection2 as expandSelection,
612
875
  getActiveFormats2 as getActiveFormats,
876
+ getDebugMode,
613
877
  hasFormat2 as hasFormat,
614
878
  insertHeader,
615
879
  insertLink,
616
880
  preserveSelection,
881
+ setDebugMode,
617
882
  setUndoMethod,
618
883
  toggleBold,
619
884
  toggleBulletList,
620
885
  toggleCode,
886
+ toggleH1,
887
+ toggleH2,
888
+ toggleH3,
621
889
  toggleItalic,
622
890
  toggleNumberedList,
623
- toggleQuote
891
+ toggleQuote,
892
+ toggleTaskList
624
893
  };
625
894
  //# sourceMappingURL=markdown-actions.esm.js.map