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