markdown-actions 1.0.7 → 1.0.8
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/markdown-actions.esm.js +38 -48
- package/dist/markdown-actions.esm.js.map +3 -3
- package/dist/markdown-actions.js +38 -48
- package/dist/markdown-actions.js.map +3 -3
- package/dist/markdown-actions.min.js +22 -22
- package/package.json +1 -1
- package/src/index.js +59 -67
|
@@ -814,11 +814,12 @@ function insertHeader(textarea, level = 1, toggle = false) {
|
|
|
814
814
|
return;
|
|
815
815
|
if (level < 1 || level > 6)
|
|
816
816
|
level = 1;
|
|
817
|
+
debugLog("insertHeader", `Level: ${level}, Toggle: ${toggle}`);
|
|
817
818
|
const headerKey = `header${level === 1 ? "1" : level}`;
|
|
818
819
|
const style = mergeWithDefaults(FORMATS[headerKey] || FORMATS.header1);
|
|
819
|
-
const value = textarea.value;
|
|
820
820
|
const originalStart = textarea.selectionStart;
|
|
821
821
|
const originalEnd = textarea.selectionEnd;
|
|
822
|
+
const value = textarea.value;
|
|
822
823
|
let lineStart = originalStart;
|
|
823
824
|
while (lineStart > 0 && value[lineStart - 1] !== "\n") {
|
|
824
825
|
lineStart--;
|
|
@@ -827,54 +828,43 @@ function insertHeader(textarea, level = 1, toggle = false) {
|
|
|
827
828
|
while (lineEnd < value.length && value[lineEnd] !== "\n") {
|
|
828
829
|
lineEnd++;
|
|
829
830
|
}
|
|
830
|
-
const
|
|
831
|
-
|
|
831
|
+
const currentLine = value.slice(lineStart, lineEnd);
|
|
832
|
+
debugLog("insertHeader", `Current line: "${currentLine}"`);
|
|
833
|
+
const existingHeaderMatch = currentLine.match(/^(#{1,6})\s*/);
|
|
832
834
|
const existingLevel = existingHeaderMatch ? existingHeaderMatch[1].length : 0;
|
|
833
|
-
const
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
start: selStart + prefixDiff,
|
|
867
|
-
end: selEnd + prefixDiff
|
|
868
|
-
};
|
|
869
|
-
} else {
|
|
870
|
-
return {
|
|
871
|
-
start: selStart + style.prefix.length,
|
|
872
|
-
end: selEnd + style.prefix.length
|
|
873
|
-
};
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
}
|
|
877
|
-
);
|
|
835
|
+
const existingPrefixLength = existingHeaderMatch ? existingHeaderMatch[0].length : 0;
|
|
836
|
+
debugLog("insertHeader", `Existing level: ${existingLevel}, Target level: ${level}`);
|
|
837
|
+
let newLine;
|
|
838
|
+
let prefixChange = 0;
|
|
839
|
+
if (toggle && existingLevel === level) {
|
|
840
|
+
debugLog("insertHeader", "Toggling OFF header");
|
|
841
|
+
newLine = currentLine.replace(/^#{1,6}\s*/, "");
|
|
842
|
+
prefixChange = -existingPrefixLength;
|
|
843
|
+
} else if (existingLevel > 0) {
|
|
844
|
+
debugLog("insertHeader", "Replacing header");
|
|
845
|
+
const cleanedLine = currentLine.replace(/^#{1,6}\s*/, "");
|
|
846
|
+
newLine = style.prefix + cleanedLine;
|
|
847
|
+
prefixChange = style.prefix.length - existingPrefixLength;
|
|
848
|
+
} else {
|
|
849
|
+
debugLog("insertHeader", "Adding new header");
|
|
850
|
+
newLine = style.prefix + currentLine;
|
|
851
|
+
prefixChange = style.prefix.length;
|
|
852
|
+
}
|
|
853
|
+
const result = {
|
|
854
|
+
text: newLine,
|
|
855
|
+
selectionStart: lineStart,
|
|
856
|
+
selectionEnd: lineEnd
|
|
857
|
+
};
|
|
858
|
+
if (originalStart === originalEnd) {
|
|
859
|
+
result.selectionStart = Math.max(originalStart + prefixChange, lineStart);
|
|
860
|
+
result.selectionEnd = result.selectionStart;
|
|
861
|
+
} else {
|
|
862
|
+
result.selectionStart = Math.max(originalStart + prefixChange, lineStart);
|
|
863
|
+
result.selectionEnd = Math.max(originalEnd + prefixChange, lineStart);
|
|
864
|
+
}
|
|
865
|
+
debugLog("insertHeader", `Result: "${result.text}" (${result.selectionStart}, ${result.selectionEnd})`);
|
|
866
|
+
textarea.selectionStart = lineStart;
|
|
867
|
+
textarea.selectionEnd = lineEnd;
|
|
878
868
|
insertText(textarea, result);
|
|
879
869
|
}
|
|
880
870
|
function toggleH1(textarea) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/core/formats.js", "../src/debug.js", "../src/core/insertion.js", "../src/core/selection.js", "../src/operations/block.js", "../src/operations/list.js", "../src/core/detection.js", "../src/index.js"],
|
|
4
|
-
"sourcesContent": ["/**\n * Format definitions for markdown syntax\n */\n\nexport const FORMATS = {\n bold: {\n prefix: '**',\n suffix: '**',\n trimFirst: true\n },\n italic: {\n prefix: '_',\n suffix: '_',\n trimFirst: true\n },\n code: {\n prefix: '`',\n suffix: '`',\n blockPrefix: '```',\n blockSuffix: '```'\n },\n link: {\n prefix: '[',\n suffix: '](url)',\n replaceNext: 'url',\n scanFor: 'https?://'\n },\n bulletList: {\n prefix: '- ',\n multiline: true,\n unorderedList: true\n },\n numberedList: {\n prefix: '1. ',\n multiline: true,\n orderedList: true\n },\n quote: {\n prefix: '> ',\n multiline: true,\n surroundWithNewlines: true\n },\n taskList: {\n prefix: '- [ ] ',\n multiline: true,\n surroundWithNewlines: true\n },\n header1: { prefix: '# ' },\n header2: { prefix: '## ' },\n header3: { prefix: '### ' },\n header4: { prefix: '#### ' },\n header5: { prefix: '##### ' },\n header6: { prefix: '###### ' }\n}\n\n/**\n * Default style configuration\n */\nexport function getDefaultStyle() {\n return {\n prefix: '',\n suffix: '',\n blockPrefix: '',\n blockSuffix: '',\n multiline: false,\n replaceNext: '',\n prefixSpace: false,\n scanFor: '',\n surroundWithNewlines: false,\n orderedList: false,\n unorderedList: false,\n trimFirst: false\n }\n}\n\n/**\n * Merge format with defaults\n */\nexport function mergeWithDefaults(format) {\n return { ...getDefaultStyle(), ...format }\n}", "/**\n * Debug utilities for markdown-actions\n * Add console logging to track what's happening\n */\n\n// Debug mode flag - disabled by default\nlet debugMode = false;\n\n/**\n * Enable or disable debug mode\n * @param {boolean} enabled - Whether to enable debug mode\n */\nexport function setDebugMode(enabled) {\n debugMode = enabled;\n}\n\n/**\n * Get current debug mode status\n * @returns {boolean} Whether debug mode is enabled\n */\nexport function getDebugMode() {\n return debugMode;\n}\n\nexport function debugLog(funcName, message, data) {\n if (!debugMode) return;\n \n console.group(`\uD83D\uDD0D ${funcName}`);\n console.log(message);\n if (data) {\n console.log('Data:', data);\n }\n console.groupEnd();\n}\n\nexport function debugSelection(textarea, label) {\n if (!debugMode) return;\n \n const selected = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);\n console.group(`\uD83D\uDCCD Selection: ${label}`);\n console.log('Position:', `${textarea.selectionStart}-${textarea.selectionEnd}`);\n console.log('Selected text:', JSON.stringify(selected));\n console.log('Length:', selected.length);\n \n // Show context around selection\n const before = textarea.value.slice(Math.max(0, textarea.selectionStart - 10), textarea.selectionStart);\n const after = textarea.value.slice(textarea.selectionEnd, Math.min(textarea.value.length, textarea.selectionEnd + 10));\n console.log('Context:', JSON.stringify(before) + '[SELECTION]' + JSON.stringify(after));\n console.groupEnd();\n}\n\nexport function debugResult(result) {\n if (!debugMode) return;\n \n console.group('\uD83D\uDCDD Result');\n console.log('Text to insert:', JSON.stringify(result.text));\n console.log('New selection:', `${result.selectionStart}-${result.selectionEnd}`);\n console.groupEnd();\n}", "/**\n * Text insertion system with undo/redo support\n * Extracted and adapted from GitHub's markdown-toolbar-element\n */\n\nimport { getDebugMode } from '../debug.js'\n\nlet canInsertText = null\n\n/**\n * Insert text at current position with undo/redo support\n * @param {HTMLTextAreaElement} textarea - Target textarea\n * @param {Object} options - Text and selection options\n * @param {string} options.text - Text to insert\n * @param {number} [options.selectionStart] - New selection start\n * @param {number} [options.selectionEnd] - New selection end\n */\nexport function insertText(textarea, { text, selectionStart, selectionEnd }) {\n const debugMode = getDebugMode();\n \n if (debugMode) {\n console.group('\uD83D\uDD27 insertText');\n console.log('Current selection:', `${textarea.selectionStart}-${textarea.selectionEnd}`);\n console.log('Text to insert:', JSON.stringify(text));\n console.log('New selection to set:', selectionStart, '-', selectionEnd);\n }\n \n // Make sure the textarea is focused\n textarea.focus();\n \n const originalSelectionStart = textarea.selectionStart\n const originalSelectionEnd = textarea.selectionEnd\n const before = textarea.value.slice(0, originalSelectionStart)\n const after = textarea.value.slice(originalSelectionEnd)\n \n if (debugMode) {\n console.log('Before text (last 20):', JSON.stringify(before.slice(-20)));\n console.log('After text (first 20):', JSON.stringify(after.slice(0, 20)));\n console.log('Selected text being replaced:', JSON.stringify(textarea.value.slice(originalSelectionStart, originalSelectionEnd)));\n }\n \n // Store the original value to check if execCommand actually changed it\n const originalValue = textarea.value\n\n // Only try execCommand if there's no selection (just inserting at cursor)\n // For replacements, we should use manual mode\n const hasSelection = originalSelectionStart !== originalSelectionEnd\n \n if (!hasSelection && (canInsertText === null || canInsertText === true)) {\n textarea.contentEditable = 'true'\n try {\n canInsertText = document.execCommand('insertText', false, text)\n } catch (error) {\n canInsertText = false\n }\n textarea.contentEditable = 'false'\n } else if (hasSelection) {\n if (debugMode) console.log('Has selection, skipping execCommand and using manual mode');\n canInsertText = false\n }\n\n if (debugMode) {\n console.log('canInsertText before:', canInsertText);\n console.log('execCommand result:', canInsertText);\n }\n \n // Check if execCommand actually worked by comparing the value\n if (canInsertText) {\n const expectedValue = before + text + after\n const actualValue = textarea.value\n \n if (debugMode) {\n console.log('Expected length:', expectedValue.length);\n console.log('Actual length:', actualValue.length);\n }\n \n if (actualValue !== expectedValue) {\n if (debugMode) {\n console.log('execCommand changed the value but not as expected');\n console.log('Expected:', JSON.stringify(expectedValue.slice(0, 100)));\n console.log('Actual:', JSON.stringify(actualValue.slice(0, 100)));\n }\n // Don't set canInsertText to false here - execCommand did work\n // We just need to not double-insert\n }\n }\n\n if (!canInsertText) {\n if (debugMode) console.log('Using manual insertion');\n // Only do manual insertion if execCommand didn't change the value\n if (textarea.value === originalValue) {\n if (debugMode) console.log('Value unchanged, doing manual replacement');\n try {\n document.execCommand('ms-beginUndoUnit')\n } catch (e) {\n // Do nothing.\n }\n textarea.value = before + text + after\n try {\n document.execCommand('ms-endUndoUnit')\n } catch (e) {\n // Do nothing.\n }\n textarea.dispatchEvent(new CustomEvent('input', { bubbles: true, cancelable: true }))\n } else {\n if (debugMode) console.log('Value was changed by execCommand, skipping manual insertion');\n }\n }\n\n if (debugMode) console.log('Setting selection range:', selectionStart, selectionEnd);\n if (selectionStart != null && selectionEnd != null) {\n textarea.setSelectionRange(selectionStart, selectionEnd)\n } else {\n textarea.setSelectionRange(originalSelectionStart, textarea.selectionEnd)\n }\n \n if (debugMode) {\n console.log('Final value length:', textarea.value.length);\n console.groupEnd();\n }\n}\n\n/**\n * Configure undo method\n * @param {'native' | 'manual' | 'auto'} method - Undo method to use\n */\nexport function setUndoMethod(method) {\n switch (method) {\n case 'native':\n canInsertText = true\n break\n case 'manual':\n canInsertText = false\n break\n case 'auto':\n canInsertText = null\n break\n }\n}", "/**\n * Core selection utilities extracted and adapted from GitHub's markdown-toolbar-element\n */\n\n/**\n * Check if string contains multiple lines\n */\nexport function isMultipleLines(string) {\n return string.trim().split('\\n').length > 1\n}\n\n/**\n * Find the start of the word at position i\n */\nexport function wordSelectionStart(text, i) {\n let index = i\n while (text[index] && text[index - 1] != null && !text[index - 1].match(/\\s/)) {\n index--\n }\n return index\n}\n\n/**\n * Find the end of the word at position i\n */\nexport function wordSelectionEnd(text, i, multiline) {\n let index = i\n const breakpoint = multiline ? /\\n/ : /\\s/\n while (text[index] && !text[index].match(breakpoint)) {\n index++\n }\n return index\n}\n\n/**\n * Expand selection to line boundaries\n */\nexport function expandSelectionToLine(textarea) {\n const lines = textarea.value.split('\\n')\n let counter = 0\n for (let index = 0; index < lines.length; index++) {\n const lineLength = lines[index].length + 1\n if (textarea.selectionStart >= counter && textarea.selectionStart < counter + lineLength) {\n textarea.selectionStart = counter\n }\n if (textarea.selectionEnd >= counter && textarea.selectionEnd < counter + lineLength) {\n // For the last line, don't go past the actual text length\n if (index === lines.length - 1) {\n textarea.selectionEnd = Math.min(counter + lines[index].length, textarea.value.length)\n } else {\n textarea.selectionEnd = counter + lineLength - 1\n }\n }\n counter += lineLength\n }\n}\n\n/**\n * Expand selected text with smart boundary detection\n */\nexport function expandSelectedText(textarea, prefixToUse, suffixToUse, multiline = false) {\n if (textarea.selectionStart === textarea.selectionEnd) {\n textarea.selectionStart = wordSelectionStart(textarea.value, textarea.selectionStart)\n textarea.selectionEnd = wordSelectionEnd(textarea.value, textarea.selectionEnd, multiline)\n } else {\n const expandedSelectionStart = textarea.selectionStart - prefixToUse.length\n const expandedSelectionEnd = textarea.selectionEnd + suffixToUse.length\n const beginsWithPrefix = textarea.value.slice(expandedSelectionStart, textarea.selectionStart) === prefixToUse\n const endsWithSuffix = textarea.value.slice(textarea.selectionEnd, expandedSelectionEnd) === suffixToUse\n if (beginsWithPrefix && endsWithSuffix) {\n textarea.selectionStart = expandedSelectionStart\n textarea.selectionEnd = expandedSelectionEnd\n }\n }\n return textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n}\n\n/**\n * Calculate newlines needed to surround selected text\n */\nexport function newlinesToSurroundSelectedText(textarea) {\n const beforeSelection = textarea.value.slice(0, textarea.selectionStart)\n const afterSelection = textarea.value.slice(textarea.selectionEnd)\n\n const breaksBefore = beforeSelection.match(/\\n*$/)\n const breaksAfter = afterSelection.match(/^\\n*/)\n const newlinesBeforeSelection = breaksBefore ? breaksBefore[0].length : 0\n const newlinesAfterSelection = breaksAfter ? breaksAfter[0].length : 0\n\n let newlinesToAppend = ''\n let newlinesToPrepend = ''\n\n if (beforeSelection.match(/\\S/) && newlinesBeforeSelection < 2) {\n newlinesToAppend = '\\n'.repeat(2 - newlinesBeforeSelection)\n }\n\n if (afterSelection.match(/\\S/) && newlinesAfterSelection < 2) {\n newlinesToPrepend = '\\n'.repeat(2 - newlinesAfterSelection)\n }\n\n return { newlinesToAppend, newlinesToPrepend }\n}\n\n/**\n * Utility to preserve selection during operations\n */\nexport function preserveSelection(textarea, callback) {\n const start = textarea.selectionStart\n const end = textarea.selectionEnd\n const scrollTop = textarea.scrollTop\n \n callback()\n \n textarea.selectionStart = start\n textarea.selectionEnd = end\n textarea.scrollTop = scrollTop\n}\n\n/**\n * Apply a line-based operation with cursor preservation\n * This function handles expanding to line boundaries and preserving cursor position\n * @param {HTMLTextAreaElement} textarea - The textarea element\n * @param {Function} operation - The operation to perform (receives textarea and returns result)\n * @param {Object} options - Options for the operation\n * @param {string} options.prefix - The prefix being added/removed (for cursor adjustment)\n * @param {Function} options.adjustSelection - Custom selection adjustment function\n * @returns {Object} The result from the operation with adjusted cursor position\n */\nexport function applyLineOperation(textarea, operation, options = {}) {\n // Save original cursor position AND selection before any expansion\n const originalStart = textarea.selectionStart\n const originalEnd = textarea.selectionEnd\n const noInitialSelection = originalStart === originalEnd\n \n // Store the line start position to calculate offset later\n const value = textarea.value\n let lineStart = originalStart\n \n // Find start of the line containing the selection start\n while (lineStart > 0 && value[lineStart - 1] !== '\\n') {\n lineStart--\n }\n \n // Expand selection to line boundaries for the operation\n if (noInitialSelection) {\n // Expand to current line when no selection\n let lineEnd = originalStart\n \n // Find end of current line\n while (lineEnd < value.length && value[lineEnd] !== '\\n') {\n lineEnd++\n }\n \n textarea.selectionStart = lineStart\n textarea.selectionEnd = lineEnd\n } else {\n // For selections, expand to full lines\n expandSelectionToLine(textarea)\n }\n \n // Apply the operation\n const result = operation(textarea)\n \n // Restore original selection/cursor with prefix adjustment\n if (options.adjustSelection) {\n // Use custom selection adjustment logic\n const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n const isRemoving = selectedText.startsWith(options.prefix)\n const adjusted = options.adjustSelection(isRemoving, originalStart, originalEnd, lineStart)\n result.selectionStart = adjusted.start\n result.selectionEnd = adjusted.end\n } else if (options.prefix) {\n // Use default prefix-based adjustment\n const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n const isRemoving = selectedText.startsWith(options.prefix)\n \n if (noInitialSelection) {\n // No selection - just restore cursor position\n if (isRemoving) {\n // When removing prefix, adjust cursor position\n result.selectionStart = Math.max(originalStart - options.prefix.length, lineStart)\n result.selectionEnd = result.selectionStart\n } else {\n // When adding prefix, adjust cursor position\n result.selectionStart = originalStart + options.prefix.length\n result.selectionEnd = result.selectionStart\n }\n } else {\n // Had a selection - restore it with adjustment\n if (isRemoving) {\n // When removing prefix, shift selection back\n result.selectionStart = Math.max(originalStart - options.prefix.length, lineStart)\n result.selectionEnd = Math.max(originalEnd - options.prefix.length, lineStart)\n } else {\n // When adding prefix, shift selection forward\n result.selectionStart = originalStart + options.prefix.length\n result.selectionEnd = originalEnd + options.prefix.length\n }\n }\n }\n \n return result\n}", "/**\n * Block-level text formatting operations\n * Handles inline formats like bold, italic, code, and links\n */\n\nimport { expandSelectedText, newlinesToSurroundSelectedText, isMultipleLines } from '../core/selection.js'\nimport { insertText } from '../core/insertion.js'\n\n/**\n * Apply block-level styling to selected text\n */\nexport function blockStyle(textarea, style) {\n let newlinesToAppend\n let newlinesToPrepend\n\n const { prefix, suffix, blockPrefix, blockSuffix, replaceNext, prefixSpace, scanFor, surroundWithNewlines, trimFirst } = style\n const originalSelectionStart = textarea.selectionStart\n const originalSelectionEnd = textarea.selectionEnd\n\n let selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n let prefixToUse = isMultipleLines(selectedText) && blockPrefix && blockPrefix.length > 0 ? `${blockPrefix}\\n` : prefix\n let suffixToUse = isMultipleLines(selectedText) && blockSuffix && blockSuffix.length > 0 ? `\\n${blockSuffix}` : suffix\n\n if (prefixSpace) {\n const beforeSelection = textarea.value[textarea.selectionStart - 1]\n if (textarea.selectionStart !== 0 && beforeSelection != null && !beforeSelection.match(/\\s/)) {\n prefixToUse = ` ${prefixToUse}`\n }\n }\n \n selectedText = expandSelectedText(textarea, prefixToUse, suffixToUse, style.multiline)\n let selectionStart = textarea.selectionStart\n let selectionEnd = textarea.selectionEnd\n const hasReplaceNext = replaceNext && replaceNext.length > 0 && suffixToUse.indexOf(replaceNext) > -1 && selectedText.length > 0\n \n if (surroundWithNewlines) {\n const ref = newlinesToSurroundSelectedText(textarea)\n newlinesToAppend = ref.newlinesToAppend\n newlinesToPrepend = ref.newlinesToPrepend\n prefixToUse = newlinesToAppend + prefix\n suffixToUse += newlinesToPrepend\n }\n\n // Check if we should remove formatting (toggle off)\n if (selectedText.startsWith(prefixToUse) && selectedText.endsWith(suffixToUse)) {\n const replacementText = selectedText.slice(prefixToUse.length, selectedText.length - suffixToUse.length)\n if (originalSelectionStart === originalSelectionEnd) {\n let position = originalSelectionStart - prefixToUse.length\n position = Math.max(position, selectionStart)\n position = Math.min(position, selectionStart + replacementText.length)\n selectionStart = selectionEnd = position\n } else {\n selectionEnd = selectionStart + replacementText.length\n }\n return { text: replacementText, selectionStart, selectionEnd }\n } else if (!hasReplaceNext) {\n // Add formatting\n let replacementText = prefixToUse + selectedText + suffixToUse\n selectionStart = originalSelectionStart + prefixToUse.length\n selectionEnd = originalSelectionEnd + prefixToUse.length\n const whitespaceEdges = selectedText.match(/^\\s*|\\s*$/g)\n if (trimFirst && whitespaceEdges) {\n const leadingWhitespace = whitespaceEdges[0] || ''\n const trailingWhitespace = whitespaceEdges[1] || ''\n replacementText = leadingWhitespace + prefixToUse + selectedText.trim() + suffixToUse + trailingWhitespace\n selectionStart += leadingWhitespace.length\n selectionEnd -= trailingWhitespace.length\n }\n return { text: replacementText, selectionStart, selectionEnd }\n } else if (scanFor && scanFor.length > 0 && selectedText.match(scanFor)) {\n // Handle link/image with URL detection\n suffixToUse = suffixToUse.replace(replaceNext, selectedText)\n const replacementText = prefixToUse + suffixToUse\n selectionStart = selectionEnd = selectionStart + prefixToUse.length\n return { text: replacementText, selectionStart, selectionEnd }\n } else {\n // Handle link/image with placeholder\n const replacementText = prefixToUse + selectedText + suffixToUse\n selectionStart = selectionStart + prefixToUse.length + selectedText.length + suffixToUse.indexOf(replaceNext)\n selectionEnd = selectionStart + replaceNext.length\n return { text: replacementText, selectionStart, selectionEnd }\n }\n}\n\n/**\n * Apply style to selected text in textarea\n */\nexport function styleSelectedText(textarea, style) {\n const text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n \n let result\n if (style.orderedList || style.unorderedList) {\n // Will be handled by list operations\n return\n } else if (style.multiline && isMultipleLines(text)) {\n result = multilineStyle(textarea, style)\n } else {\n result = blockStyle(textarea, style)\n }\n\n insertText(textarea, result)\n}\n\n/**\n * Apply multiline styling (quotes, task lists, etc)\n * Note: This does NOT expand selection to line - that should be done by the caller if needed\n */\nexport function multilineStyle(textarea, style) {\n const { prefix, suffix, surroundWithNewlines } = style\n let text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n let selectionStart = textarea.selectionStart\n let selectionEnd = textarea.selectionEnd\n const lines = text.split('\\n')\n \n // Check if we need to undo (all lines have the format)\n const undoStyle = lines.every(line => line.startsWith(prefix) && (!suffix || line.endsWith(suffix)))\n\n if (undoStyle) {\n // Remove the formatting\n text = lines.map(line => {\n let result = line.slice(prefix.length)\n if (suffix) {\n result = result.slice(0, result.length - suffix.length)\n }\n return result\n }).join('\\n')\n selectionEnd = selectionStart + text.length\n } else {\n // Apply the formatting\n text = lines.map(line => prefix + line + (suffix || '')).join('\\n')\n if (surroundWithNewlines) {\n const { newlinesToAppend, newlinesToPrepend } = newlinesToSurroundSelectedText(textarea)\n selectionStart += newlinesToAppend.length\n selectionEnd = selectionStart + text.length\n text = newlinesToAppend + text + newlinesToPrepend\n }\n }\n\n return { text, selectionStart, selectionEnd }\n}", "/**\n * List operations for bullet and numbered lists\n */\n\nimport { expandSelectionToLine, newlinesToSurroundSelectedText, applyLineOperation } from '../core/selection.js'\nimport { insertText } from '../core/insertion.js'\n\n/**\n * Undo ordered list formatting\n */\nfunction undoOrderedListStyle(text) {\n const lines = text.split('\\n')\n const orderedListRegex = /^\\d+\\.\\s+/\n const shouldUndoOrderedList = lines.every(line => orderedListRegex.test(line))\n let result = lines\n if (shouldUndoOrderedList) {\n result = lines.map(line => line.replace(orderedListRegex, ''))\n }\n\n return {\n text: result.join('\\n'),\n processed: shouldUndoOrderedList\n }\n}\n\n/**\n * Undo unordered list formatting\n */\nfunction undoUnorderedListStyle(text) {\n const lines = text.split('\\n')\n const unorderedListPrefix = '- '\n const shouldUndoUnorderedList = lines.every(line => line.startsWith(unorderedListPrefix))\n let result = lines\n if (shouldUndoUnorderedList) {\n result = lines.map(line => line.slice(unorderedListPrefix.length))\n }\n\n return {\n text: result.join('\\n'),\n processed: shouldUndoUnorderedList\n }\n}\n\n/**\n * Make prefix for list item\n */\nfunction makePrefix(index, unorderedList) {\n if (unorderedList) {\n return '- '\n } else {\n return `${index + 1}. `\n }\n}\n\n/**\n * Clear existing list style\n */\nfunction clearExistingListStyle(style, selectedText) {\n let undoResult\n let undoResultOppositeList\n let pristineText\n \n if (style.orderedList) {\n undoResult = undoOrderedListStyle(selectedText)\n undoResultOppositeList = undoUnorderedListStyle(undoResult.text)\n pristineText = undoResultOppositeList.text\n } else {\n undoResult = undoUnorderedListStyle(selectedText)\n undoResultOppositeList = undoOrderedListStyle(undoResult.text)\n pristineText = undoResultOppositeList.text\n }\n \n return [undoResult, undoResultOppositeList, pristineText]\n}\n\n/**\n * Apply list styling to selected text\n */\nexport function listStyle(textarea, style) {\n const noInitialSelection = textarea.selectionStart === textarea.selectionEnd\n let selectionStart = textarea.selectionStart\n let selectionEnd = textarea.selectionEnd\n\n // Select whole line\n expandSelectionToLine(textarea)\n\n const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n\n // Clear any existing list formatting\n const [undoResult, undoResultOppositeList, pristineText] = clearExistingListStyle(style, selectedText)\n\n const prefixedLines = pristineText.split('\\n').map((value, index) => {\n return `${makePrefix(index, style.unorderedList)}${value}`\n })\n\n const totalPrefixLength = prefixedLines.reduce((previousValue, _currentValue, currentIndex) => {\n return previousValue + makePrefix(currentIndex, style.unorderedList).length\n }, 0)\n\n const totalPrefixLengthOppositeList = prefixedLines.reduce((previousValue, _currentValue, currentIndex) => {\n return previousValue + makePrefix(currentIndex, !style.unorderedList).length\n }, 0)\n\n // If we're undoing the same list type, just return the pristine text\n if (undoResult.processed) {\n if (noInitialSelection) {\n selectionStart = Math.max(selectionStart - makePrefix(0, style.unorderedList).length, 0)\n selectionEnd = selectionStart\n } else {\n selectionStart = textarea.selectionStart\n selectionEnd = textarea.selectionEnd - totalPrefixLength\n }\n return { text: pristineText, selectionStart, selectionEnd }\n }\n\n // Apply new list formatting\n const { newlinesToAppend, newlinesToPrepend } = newlinesToSurroundSelectedText(textarea)\n const text = newlinesToAppend + prefixedLines.join('\\n') + newlinesToPrepend\n\n if (noInitialSelection) {\n selectionStart = Math.max(selectionStart + makePrefix(0, style.unorderedList).length + newlinesToAppend.length, 0)\n selectionEnd = selectionStart\n } else {\n if (undoResultOppositeList.processed) {\n // Converting from one list type to another\n selectionStart = Math.max(textarea.selectionStart + newlinesToAppend.length, 0)\n selectionEnd = textarea.selectionEnd + newlinesToAppend.length + totalPrefixLength - totalPrefixLengthOppositeList\n } else {\n // Adding list formatting to plain text\n selectionStart = Math.max(textarea.selectionStart + newlinesToAppend.length, 0)\n selectionEnd = textarea.selectionEnd + newlinesToAppend.length + totalPrefixLength\n }\n }\n\n return { text, selectionStart, selectionEnd }\n}\n\n/**\n * Apply list style to textarea\n */\nexport function applyListStyle(textarea, style) {\n // Use applyLineOperation for consistent selection preservation\n const result = applyLineOperation(\n textarea,\n (ta) => listStyle(ta, style),\n {\n // Custom selection adjustment for lists\n adjustSelection: (isRemoving, selStart, selEnd, lineStart) => {\n // Get the current line to check if we're removing\n const currentLine = textarea.value.slice(lineStart, textarea.selectionEnd)\n const orderedListRegex = /^\\d+\\.\\s+/\n const unorderedListRegex = /^- /\n \n // Check if we're removing a list\n const hasOrderedList = orderedListRegex.test(currentLine)\n const hasUnorderedList = unorderedListRegex.test(currentLine)\n const isRemovingCurrent = (style.orderedList && hasOrderedList) || (style.unorderedList && hasUnorderedList)\n \n if (selStart === selEnd) {\n // No selection - cursor position\n if (isRemovingCurrent) {\n // Removing list - adjust cursor back\n const prefixMatch = currentLine.match(style.orderedList ? orderedListRegex : unorderedListRegex)\n const prefixLength = prefixMatch ? prefixMatch[0].length : 0\n return {\n start: Math.max(selStart - prefixLength, lineStart),\n end: Math.max(selStart - prefixLength, lineStart)\n }\n } else if (hasOrderedList || hasUnorderedList) {\n // Converting from one list type to another\n const oldPrefixMatch = currentLine.match(hasOrderedList ? orderedListRegex : unorderedListRegex)\n const oldPrefixLength = oldPrefixMatch ? oldPrefixMatch[0].length : 0\n const newPrefixLength = style.unorderedList ? 2 : 3 // \"- \" or \"1. \"\n const adjustment = newPrefixLength - oldPrefixLength\n return {\n start: selStart + adjustment,\n end: selStart + adjustment\n }\n } else {\n // Adding new list\n const prefixLength = style.unorderedList ? 2 : 3 // \"- \" or \"1. \"\n return {\n start: selStart + prefixLength,\n end: selStart + prefixLength\n }\n }\n } else {\n // Has selection - preserve it\n if (isRemovingCurrent) {\n // Removing current list type\n const prefixMatch = currentLine.match(style.orderedList ? orderedListRegex : unorderedListRegex)\n const prefixLength = prefixMatch ? prefixMatch[0].length : 0\n return {\n start: Math.max(selStart - prefixLength, lineStart),\n end: Math.max(selEnd - prefixLength, lineStart)\n }\n } else if (hasOrderedList || hasUnorderedList) {\n // Converting from one list type to another\n const oldPrefixMatch = currentLine.match(hasOrderedList ? orderedListRegex : unorderedListRegex)\n const oldPrefixLength = oldPrefixMatch ? oldPrefixMatch[0].length : 0\n const newPrefixLength = style.unorderedList ? 2 : 3 // \"- \" or \"1. \"\n const adjustment = newPrefixLength - oldPrefixLength\n return {\n start: selStart + adjustment,\n end: selEnd + adjustment\n }\n } else {\n // Adding new list\n const prefixLength = style.unorderedList ? 2 : 3 // \"- \" or \"1. \"\n return {\n start: selStart + prefixLength,\n end: selEnd + prefixLength\n }\n }\n }\n }\n }\n )\n \n insertText(textarea, result)\n}", "/**\n * Format detection utilities\n */\n\nimport { FORMATS } from './formats.js'\n\n/**\n * Check if text has a specific format applied\n */\nfunction hasFormatApplied(text, format) {\n if (!format.prefix) return false\n \n if (format.suffix) {\n return text.startsWith(format.prefix) && text.endsWith(format.suffix)\n } else {\n return text.startsWith(format.prefix)\n }\n}\n\n/**\n * Get active formats at cursor position\n */\nexport function getActiveFormats(textarea) {\n if (!textarea) return []\n \n const formats = []\n const { selectionStart, selectionEnd, value } = textarea\n \n // Get current line for line-based formats\n const lines = value.split('\\n')\n let lineStart = 0\n let currentLine = ''\n \n for (const line of lines) {\n if (selectionStart >= lineStart && selectionStart <= lineStart + line.length) {\n currentLine = line\n break\n }\n lineStart += line.length + 1\n }\n \n // Check line-based formats\n if (currentLine.startsWith('- ')) {\n if (currentLine.startsWith('- [ ] ') || currentLine.startsWith('- [x] ')) {\n formats.push('task-list')\n } else {\n formats.push('bullet-list')\n }\n }\n \n if (/^\\d+\\.\\s/.test(currentLine)) {\n formats.push('numbered-list')\n }\n \n if (currentLine.startsWith('> ')) {\n formats.push('quote')\n }\n \n if (currentLine.startsWith('# ')) formats.push('header')\n if (currentLine.startsWith('## ')) formats.push('header-2')\n if (currentLine.startsWith('### ')) formats.push('header-3')\n \n // Check inline formats by looking around cursor\n const lookBehind = Math.max(0, selectionStart - 10)\n const lookAhead = Math.min(value.length, selectionEnd + 10)\n const surrounding = value.slice(lookBehind, lookAhead)\n \n // Check for bold\n if (surrounding.includes('**')) {\n const beforeCursor = value.slice(Math.max(0, selectionStart - 100), selectionStart)\n const afterCursor = value.slice(selectionEnd, Math.min(value.length, selectionEnd + 100))\n const lastOpenBold = beforeCursor.lastIndexOf('**')\n const nextCloseBold = afterCursor.indexOf('**')\n if (lastOpenBold !== -1 && nextCloseBold !== -1) {\n formats.push('bold')\n }\n }\n \n // Check for italic\n if (surrounding.includes('_')) {\n const beforeCursor = value.slice(Math.max(0, selectionStart - 100), selectionStart)\n const afterCursor = value.slice(selectionEnd, Math.min(value.length, selectionEnd + 100))\n const lastOpenItalic = beforeCursor.lastIndexOf('_')\n const nextCloseItalic = afterCursor.indexOf('_')\n if (lastOpenItalic !== -1 && nextCloseItalic !== -1) {\n formats.push('italic')\n }\n }\n \n // Check for code\n if (surrounding.includes('`')) {\n const beforeCursor = value.slice(Math.max(0, selectionStart - 100), selectionStart)\n const afterCursor = value.slice(selectionEnd, Math.min(value.length, selectionEnd + 100))\n if (beforeCursor.includes('`') && afterCursor.includes('`')) {\n formats.push('code')\n }\n }\n \n // Check for link\n if (surrounding.includes('[') && surrounding.includes(']')) {\n const beforeCursor = value.slice(Math.max(0, selectionStart - 100), selectionStart)\n const afterCursor = value.slice(selectionEnd, Math.min(value.length, selectionEnd + 100))\n const lastOpenBracket = beforeCursor.lastIndexOf('[')\n const nextCloseBracket = afterCursor.indexOf(']')\n if (lastOpenBracket !== -1 && nextCloseBracket !== -1) {\n const afterBracket = value.slice(selectionEnd + nextCloseBracket + 1, selectionEnd + nextCloseBracket + 10)\n if (afterBracket.startsWith('(')) {\n formats.push('link')\n }\n }\n }\n \n return formats\n}\n\n/**\n * Check if specific format is active at cursor\n */\nexport function hasFormat(textarea, format) {\n const activeFormats = getActiveFormats(textarea)\n return activeFormats.includes(format)\n}\n\n/**\n * Expand selection based on options\n */\nexport function expandSelection(textarea, options = {}) {\n if (!textarea) return\n \n const { toWord, toLine, toFormat } = options\n const { selectionStart, selectionEnd, value } = textarea\n \n if (toLine) {\n // Find line boundaries\n const lines = value.split('\\n')\n let lineStart = 0\n let lineEnd = 0\n let currentPos = 0\n \n for (const line of lines) {\n if (selectionStart >= currentPos && selectionStart <= currentPos + line.length) {\n lineStart = currentPos\n lineEnd = currentPos + line.length\n break\n }\n currentPos += line.length + 1\n }\n \n textarea.selectionStart = lineStart\n textarea.selectionEnd = lineEnd\n } else if (toWord && selectionStart === selectionEnd) {\n // Find word boundaries\n let start = selectionStart\n let end = selectionEnd\n \n // Move start back to word boundary\n while (start > 0 && !/\\s/.test(value[start - 1])) {\n start--\n }\n \n // Move end forward to word boundary\n while (end < value.length && !/\\s/.test(value[end])) {\n end++\n }\n \n textarea.selectionStart = start\n textarea.selectionEnd = end\n }\n}", "/**\n * markdown-actions - Lightweight markdown toolbar functionality\n * Based on GitHub's markdown-toolbar-element\n */\n\nimport { FORMATS, mergeWithDefaults } from './core/formats.js'\nimport { insertText, setUndoMethod } from './core/insertion.js'\nimport { preserveSelection, isMultipleLines, expandSelectionToLine, applyLineOperation } from './core/selection.js'\nimport { blockStyle, multilineStyle } from './operations/block.js'\nimport { applyListStyle } from './operations/list.js'\nimport { getActiveFormats as getActive, hasFormat as has, expandSelection as expand } from './core/detection.js'\nimport { debugLog, debugSelection, debugResult, setDebugMode, getDebugMode } from './debug.js'\n\n/**\n * Toggle bold formatting\n */\nexport function toggleBold(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n \n debugLog('toggleBold', 'Starting');\n debugSelection(textarea, 'Before');\n \n const style = mergeWithDefaults(FORMATS.bold)\n const result = blockStyle(textarea, style)\n \n debugResult(result);\n \n insertText(textarea, result)\n \n debugSelection(textarea, 'After');\n}\n\n/**\n * Toggle italic formatting\n */\nexport function toggleItalic(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n const style = mergeWithDefaults(FORMATS.italic)\n const result = blockStyle(textarea, style)\n insertText(textarea, result)\n}\n\n/**\n * Toggle code formatting\n */\nexport function toggleCode(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n \n // blockStyle already handles both inline and block code correctly\n const style = mergeWithDefaults(FORMATS.code)\n const result = blockStyle(textarea, style)\n insertText(textarea, result)\n}\n\n/**\n * Insert or toggle link formatting\n */\nexport function insertLink(textarea, options = {}) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n \n const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n let style = mergeWithDefaults(FORMATS.link)\n \n // Check if selected text is a URL\n const isURL = selectedText && selectedText.match(/^https?:\\/\\//)\n \n if (isURL && !options.url) {\n // If selected text is a URL, use it as both link text and URL\n style.suffix = `](${selectedText})`\n style.replaceNext = ''\n // Don't change the selected text, it becomes the link text\n } else if (options.url) {\n // Override with custom URL if provided\n style.suffix = `](${options.url})`\n style.replaceNext = ''\n }\n \n // Override with custom text if provided\n if (options.text && !selectedText) {\n // Insert the text and select it\n const pos = textarea.selectionStart\n textarea.value = textarea.value.slice(0, pos) + options.text + textarea.value.slice(pos)\n textarea.selectionStart = pos\n textarea.selectionEnd = pos + options.text.length\n }\n \n const result = blockStyle(textarea, style)\n insertText(textarea, result)\n}\n\n/**\n * Toggle bullet list formatting\n */\nexport function toggleBulletList(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n const style = mergeWithDefaults(FORMATS.bulletList)\n applyListStyle(textarea, style)\n}\n\n/**\n * Toggle numbered list formatting\n */\nexport function toggleNumberedList(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n const style = mergeWithDefaults(FORMATS.numberedList)\n applyListStyle(textarea, style)\n}\n\n/**\n * Toggle quote formatting\n * Matches GitHub's implementation for quotes\n */\nexport function toggleQuote(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n \n debugLog('toggleQuote', 'Starting');\n debugSelection(textarea, 'Initial');\n \n const style = mergeWithDefaults(FORMATS.quote)\n \n // Use the reusable line operation helper\n const result = applyLineOperation(\n textarea,\n (ta) => multilineStyle(ta, style),\n { prefix: style.prefix }\n )\n \n debugResult(result);\n insertText(textarea, result)\n debugSelection(textarea, 'Final');\n}\n\n/**\n * Toggle task list formatting\n * Matches GitHub's implementation for task lists\n */\nexport function toggleTaskList(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n \n const style = mergeWithDefaults(FORMATS.taskList)\n \n // Use the reusable line operation helper\n const result = applyLineOperation(\n textarea,\n (ta) => multilineStyle(ta, style),\n { prefix: style.prefix }\n )\n \n insertText(textarea, result)\n}\n\n/**\n * Insert or toggle header with specific level\n */\nexport function insertHeader(textarea, level = 1, toggle = false) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n if (level < 1 || level > 6) level = 1\n \n const headerKey = `header${level === 1 ? '1' : level}`\n const style = mergeWithDefaults(FORMATS[headerKey] || FORMATS.header1)\n \n // Get the current line to check existing header BEFORE any operations\n const value = textarea.value\n const originalStart = textarea.selectionStart\n const originalEnd = textarea.selectionEnd\n \n // Find the start of the current line\n let lineStart = originalStart\n while (lineStart > 0 && value[lineStart - 1] !== '\\n') {\n lineStart--\n }\n \n // Find the end of the current line \n let lineEnd = originalEnd\n while (lineEnd < value.length && value[lineEnd] !== '\\n') {\n lineEnd++\n }\n \n // Get current line content\n const currentLineContent = value.slice(lineStart, lineEnd)\n const existingHeaderMatch = currentLineContent.match(/^(#{1,6})\\s*/)\n const existingLevel = existingHeaderMatch ? existingHeaderMatch[1].length : 0\n \n // Use applyLineOperation for consistent behavior\n const result = applyLineOperation(\n textarea,\n (ta) => {\n const currentLine = ta.value.slice(ta.selectionStart, ta.selectionEnd)\n \n // Remove any existing header formatting\n const cleanedLine = currentLine.replace(/^#{1,6}\\s*/, '')\n \n let newLine\n \n // If toggle mode and current line has the same header level, remove it\n if (toggle && existingLevel === level) {\n newLine = cleanedLine\n } else if (existingLevel > 0) {\n // Replace existing header with new one\n newLine = style.prefix + cleanedLine\n } else {\n // Apply new header\n newLine = style.prefix + cleanedLine\n }\n \n return {\n text: newLine,\n selectionStart: ta.selectionStart,\n selectionEnd: ta.selectionEnd\n }\n },\n {\n prefix: style.prefix,\n // Custom handler for header-specific logic\n adjustSelection: (isRemoving, selStart, selEnd, lineStart) => {\n const existingPrefixLength = existingHeaderMatch ? existingHeaderMatch[0].length : 0\n \n // Check if we're actually removing (toggle off)\n const actuallyRemoving = toggle && existingLevel === level\n \n if (actuallyRemoving) {\n // Removing the header entirely\n return {\n start: Math.max(selStart - existingPrefixLength, lineStart),\n end: Math.max(selEnd - existingPrefixLength, lineStart)\n }\n } else if (existingPrefixLength > 0) {\n // Replacing existing header with new one\n const prefixDiff = style.prefix.length - existingPrefixLength\n return {\n start: selStart + prefixDiff,\n end: selEnd + prefixDiff\n }\n } else {\n // Adding new header\n return {\n start: selStart + style.prefix.length,\n end: selEnd + style.prefix.length\n }\n }\n }\n }\n )\n \n insertText(textarea, result)\n}\n\n/**\n * Toggle H1 header\n */\nexport function toggleH1(textarea) {\n insertHeader(textarea, 1, true)\n}\n\n/**\n * Toggle H2 header\n */\nexport function toggleH2(textarea) {\n insertHeader(textarea, 2, true)\n}\n\n/**\n * Toggle H3 header\n */\nexport function toggleH3(textarea) {\n insertHeader(textarea, 3, true)\n}\n\n/**\n * Get active formats at cursor position\n */\nexport function getActiveFormats(textarea) {\n return getActive(textarea)\n}\n\n/**\n * Check if format is active at cursor\n */\nexport function hasFormat(textarea, format) {\n return has(textarea, format)\n}\n\n/**\n * Expand selection based on options\n */\nexport function expandSelection(textarea, options = {}) {\n expand(textarea, options)\n}\n\n/**\n * Apply custom format\n */\nexport function applyCustomFormat(textarea, format) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n \n const style = mergeWithDefaults(format)\n let result\n \n if (style.multiline) {\n const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n if (isMultipleLines(selectedText)) {\n result = multilineStyle(textarea, style)\n } else {\n result = blockStyle(textarea, style)\n }\n } else {\n result = blockStyle(textarea, style)\n }\n \n insertText(textarea, result)\n}\n\n/**\n * Preserve selection during callback\n */\nexport { preserveSelection }\n\n/**\n * Configure undo method\n */\nexport { setUndoMethod }\n\n/**\n * Debug mode control\n */\nexport { setDebugMode, getDebugMode }\n\n/**\n * Default export with all functions\n */\nexport default {\n toggleBold,\n toggleItalic,\n toggleCode,\n insertLink,\n toggleBulletList,\n toggleNumberedList,\n toggleQuote,\n toggleTaskList,\n insertHeader,\n toggleH1,\n toggleH2,\n toggleH3,\n getActiveFormats,\n hasFormat,\n expandSelection,\n applyCustomFormat,\n preserveSelection,\n setUndoMethod,\n setDebugMode,\n getDebugMode\n}"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["debugMode", "
|
|
4
|
+
"sourcesContent": ["/**\n * Format definitions for markdown syntax\n */\n\nexport const FORMATS = {\n bold: {\n prefix: '**',\n suffix: '**',\n trimFirst: true\n },\n italic: {\n prefix: '_',\n suffix: '_',\n trimFirst: true\n },\n code: {\n prefix: '`',\n suffix: '`',\n blockPrefix: '```',\n blockSuffix: '```'\n },\n link: {\n prefix: '[',\n suffix: '](url)',\n replaceNext: 'url',\n scanFor: 'https?://'\n },\n bulletList: {\n prefix: '- ',\n multiline: true,\n unorderedList: true\n },\n numberedList: {\n prefix: '1. ',\n multiline: true,\n orderedList: true\n },\n quote: {\n prefix: '> ',\n multiline: true,\n surroundWithNewlines: true\n },\n taskList: {\n prefix: '- [ ] ',\n multiline: true,\n surroundWithNewlines: true\n },\n header1: { prefix: '# ' },\n header2: { prefix: '## ' },\n header3: { prefix: '### ' },\n header4: { prefix: '#### ' },\n header5: { prefix: '##### ' },\n header6: { prefix: '###### ' }\n}\n\n/**\n * Default style configuration\n */\nexport function getDefaultStyle() {\n return {\n prefix: '',\n suffix: '',\n blockPrefix: '',\n blockSuffix: '',\n multiline: false,\n replaceNext: '',\n prefixSpace: false,\n scanFor: '',\n surroundWithNewlines: false,\n orderedList: false,\n unorderedList: false,\n trimFirst: false\n }\n}\n\n/**\n * Merge format with defaults\n */\nexport function mergeWithDefaults(format) {\n return { ...getDefaultStyle(), ...format }\n}", "/**\n * Debug utilities for markdown-actions\n * Add console logging to track what's happening\n */\n\n// Debug mode flag - disabled by default\nlet debugMode = false;\n\n/**\n * Enable or disable debug mode\n * @param {boolean} enabled - Whether to enable debug mode\n */\nexport function setDebugMode(enabled) {\n debugMode = enabled;\n}\n\n/**\n * Get current debug mode status\n * @returns {boolean} Whether debug mode is enabled\n */\nexport function getDebugMode() {\n return debugMode;\n}\n\nexport function debugLog(funcName, message, data) {\n if (!debugMode) return;\n \n console.group(`\uD83D\uDD0D ${funcName}`);\n console.log(message);\n if (data) {\n console.log('Data:', data);\n }\n console.groupEnd();\n}\n\nexport function debugSelection(textarea, label) {\n if (!debugMode) return;\n \n const selected = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);\n console.group(`\uD83D\uDCCD Selection: ${label}`);\n console.log('Position:', `${textarea.selectionStart}-${textarea.selectionEnd}`);\n console.log('Selected text:', JSON.stringify(selected));\n console.log('Length:', selected.length);\n \n // Show context around selection\n const before = textarea.value.slice(Math.max(0, textarea.selectionStart - 10), textarea.selectionStart);\n const after = textarea.value.slice(textarea.selectionEnd, Math.min(textarea.value.length, textarea.selectionEnd + 10));\n console.log('Context:', JSON.stringify(before) + '[SELECTION]' + JSON.stringify(after));\n console.groupEnd();\n}\n\nexport function debugResult(result) {\n if (!debugMode) return;\n \n console.group('\uD83D\uDCDD Result');\n console.log('Text to insert:', JSON.stringify(result.text));\n console.log('New selection:', `${result.selectionStart}-${result.selectionEnd}`);\n console.groupEnd();\n}", "/**\n * Text insertion system with undo/redo support\n * Extracted and adapted from GitHub's markdown-toolbar-element\n */\n\nimport { getDebugMode } from '../debug.js'\n\nlet canInsertText = null\n\n/**\n * Insert text at current position with undo/redo support\n * @param {HTMLTextAreaElement} textarea - Target textarea\n * @param {Object} options - Text and selection options\n * @param {string} options.text - Text to insert\n * @param {number} [options.selectionStart] - New selection start\n * @param {number} [options.selectionEnd] - New selection end\n */\nexport function insertText(textarea, { text, selectionStart, selectionEnd }) {\n const debugMode = getDebugMode();\n \n if (debugMode) {\n console.group('\uD83D\uDD27 insertText');\n console.log('Current selection:', `${textarea.selectionStart}-${textarea.selectionEnd}`);\n console.log('Text to insert:', JSON.stringify(text));\n console.log('New selection to set:', selectionStart, '-', selectionEnd);\n }\n \n // Make sure the textarea is focused\n textarea.focus();\n \n const originalSelectionStart = textarea.selectionStart\n const originalSelectionEnd = textarea.selectionEnd\n const before = textarea.value.slice(0, originalSelectionStart)\n const after = textarea.value.slice(originalSelectionEnd)\n \n if (debugMode) {\n console.log('Before text (last 20):', JSON.stringify(before.slice(-20)));\n console.log('After text (first 20):', JSON.stringify(after.slice(0, 20)));\n console.log('Selected text being replaced:', JSON.stringify(textarea.value.slice(originalSelectionStart, originalSelectionEnd)));\n }\n \n // Store the original value to check if execCommand actually changed it\n const originalValue = textarea.value\n\n // Only try execCommand if there's no selection (just inserting at cursor)\n // For replacements, we should use manual mode\n const hasSelection = originalSelectionStart !== originalSelectionEnd\n \n if (!hasSelection && (canInsertText === null || canInsertText === true)) {\n textarea.contentEditable = 'true'\n try {\n canInsertText = document.execCommand('insertText', false, text)\n } catch (error) {\n canInsertText = false\n }\n textarea.contentEditable = 'false'\n } else if (hasSelection) {\n if (debugMode) console.log('Has selection, skipping execCommand and using manual mode');\n canInsertText = false\n }\n\n if (debugMode) {\n console.log('canInsertText before:', canInsertText);\n console.log('execCommand result:', canInsertText);\n }\n \n // Check if execCommand actually worked by comparing the value\n if (canInsertText) {\n const expectedValue = before + text + after\n const actualValue = textarea.value\n \n if (debugMode) {\n console.log('Expected length:', expectedValue.length);\n console.log('Actual length:', actualValue.length);\n }\n \n if (actualValue !== expectedValue) {\n if (debugMode) {\n console.log('execCommand changed the value but not as expected');\n console.log('Expected:', JSON.stringify(expectedValue.slice(0, 100)));\n console.log('Actual:', JSON.stringify(actualValue.slice(0, 100)));\n }\n // Don't set canInsertText to false here - execCommand did work\n // We just need to not double-insert\n }\n }\n\n if (!canInsertText) {\n if (debugMode) console.log('Using manual insertion');\n // Only do manual insertion if execCommand didn't change the value\n if (textarea.value === originalValue) {\n if (debugMode) console.log('Value unchanged, doing manual replacement');\n try {\n document.execCommand('ms-beginUndoUnit')\n } catch (e) {\n // Do nothing.\n }\n textarea.value = before + text + after\n try {\n document.execCommand('ms-endUndoUnit')\n } catch (e) {\n // Do nothing.\n }\n textarea.dispatchEvent(new CustomEvent('input', { bubbles: true, cancelable: true }))\n } else {\n if (debugMode) console.log('Value was changed by execCommand, skipping manual insertion');\n }\n }\n\n if (debugMode) console.log('Setting selection range:', selectionStart, selectionEnd);\n if (selectionStart != null && selectionEnd != null) {\n textarea.setSelectionRange(selectionStart, selectionEnd)\n } else {\n textarea.setSelectionRange(originalSelectionStart, textarea.selectionEnd)\n }\n \n if (debugMode) {\n console.log('Final value length:', textarea.value.length);\n console.groupEnd();\n }\n}\n\n/**\n * Configure undo method\n * @param {'native' | 'manual' | 'auto'} method - Undo method to use\n */\nexport function setUndoMethod(method) {\n switch (method) {\n case 'native':\n canInsertText = true\n break\n case 'manual':\n canInsertText = false\n break\n case 'auto':\n canInsertText = null\n break\n }\n}", "/**\n * Core selection utilities extracted and adapted from GitHub's markdown-toolbar-element\n */\n\n/**\n * Check if string contains multiple lines\n */\nexport function isMultipleLines(string) {\n return string.trim().split('\\n').length > 1\n}\n\n/**\n * Find the start of the word at position i\n */\nexport function wordSelectionStart(text, i) {\n let index = i\n while (text[index] && text[index - 1] != null && !text[index - 1].match(/\\s/)) {\n index--\n }\n return index\n}\n\n/**\n * Find the end of the word at position i\n */\nexport function wordSelectionEnd(text, i, multiline) {\n let index = i\n const breakpoint = multiline ? /\\n/ : /\\s/\n while (text[index] && !text[index].match(breakpoint)) {\n index++\n }\n return index\n}\n\n/**\n * Expand selection to line boundaries\n */\nexport function expandSelectionToLine(textarea) {\n const lines = textarea.value.split('\\n')\n let counter = 0\n for (let index = 0; index < lines.length; index++) {\n const lineLength = lines[index].length + 1\n if (textarea.selectionStart >= counter && textarea.selectionStart < counter + lineLength) {\n textarea.selectionStart = counter\n }\n if (textarea.selectionEnd >= counter && textarea.selectionEnd < counter + lineLength) {\n // For the last line, don't go past the actual text length\n if (index === lines.length - 1) {\n textarea.selectionEnd = Math.min(counter + lines[index].length, textarea.value.length)\n } else {\n textarea.selectionEnd = counter + lineLength - 1\n }\n }\n counter += lineLength\n }\n}\n\n/**\n * Expand selected text with smart boundary detection\n */\nexport function expandSelectedText(textarea, prefixToUse, suffixToUse, multiline = false) {\n if (textarea.selectionStart === textarea.selectionEnd) {\n textarea.selectionStart = wordSelectionStart(textarea.value, textarea.selectionStart)\n textarea.selectionEnd = wordSelectionEnd(textarea.value, textarea.selectionEnd, multiline)\n } else {\n const expandedSelectionStart = textarea.selectionStart - prefixToUse.length\n const expandedSelectionEnd = textarea.selectionEnd + suffixToUse.length\n const beginsWithPrefix = textarea.value.slice(expandedSelectionStart, textarea.selectionStart) === prefixToUse\n const endsWithSuffix = textarea.value.slice(textarea.selectionEnd, expandedSelectionEnd) === suffixToUse\n if (beginsWithPrefix && endsWithSuffix) {\n textarea.selectionStart = expandedSelectionStart\n textarea.selectionEnd = expandedSelectionEnd\n }\n }\n return textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n}\n\n/**\n * Calculate newlines needed to surround selected text\n */\nexport function newlinesToSurroundSelectedText(textarea) {\n const beforeSelection = textarea.value.slice(0, textarea.selectionStart)\n const afterSelection = textarea.value.slice(textarea.selectionEnd)\n\n const breaksBefore = beforeSelection.match(/\\n*$/)\n const breaksAfter = afterSelection.match(/^\\n*/)\n const newlinesBeforeSelection = breaksBefore ? breaksBefore[0].length : 0\n const newlinesAfterSelection = breaksAfter ? breaksAfter[0].length : 0\n\n let newlinesToAppend = ''\n let newlinesToPrepend = ''\n\n if (beforeSelection.match(/\\S/) && newlinesBeforeSelection < 2) {\n newlinesToAppend = '\\n'.repeat(2 - newlinesBeforeSelection)\n }\n\n if (afterSelection.match(/\\S/) && newlinesAfterSelection < 2) {\n newlinesToPrepend = '\\n'.repeat(2 - newlinesAfterSelection)\n }\n\n return { newlinesToAppend, newlinesToPrepend }\n}\n\n/**\n * Utility to preserve selection during operations\n */\nexport function preserveSelection(textarea, callback) {\n const start = textarea.selectionStart\n const end = textarea.selectionEnd\n const scrollTop = textarea.scrollTop\n \n callback()\n \n textarea.selectionStart = start\n textarea.selectionEnd = end\n textarea.scrollTop = scrollTop\n}\n\n/**\n * Apply a line-based operation with cursor preservation\n * This function handles expanding to line boundaries and preserving cursor position\n * @param {HTMLTextAreaElement} textarea - The textarea element\n * @param {Function} operation - The operation to perform (receives textarea and returns result)\n * @param {Object} options - Options for the operation\n * @param {string} options.prefix - The prefix being added/removed (for cursor adjustment)\n * @param {Function} options.adjustSelection - Custom selection adjustment function\n * @returns {Object} The result from the operation with adjusted cursor position\n */\nexport function applyLineOperation(textarea, operation, options = {}) {\n // Save original cursor position AND selection before any expansion\n const originalStart = textarea.selectionStart\n const originalEnd = textarea.selectionEnd\n const noInitialSelection = originalStart === originalEnd\n \n // Store the line start position to calculate offset later\n const value = textarea.value\n let lineStart = originalStart\n \n // Find start of the line containing the selection start\n while (lineStart > 0 && value[lineStart - 1] !== '\\n') {\n lineStart--\n }\n \n // Expand selection to line boundaries for the operation\n if (noInitialSelection) {\n // Expand to current line when no selection\n let lineEnd = originalStart\n \n // Find end of current line\n while (lineEnd < value.length && value[lineEnd] !== '\\n') {\n lineEnd++\n }\n \n textarea.selectionStart = lineStart\n textarea.selectionEnd = lineEnd\n } else {\n // For selections, expand to full lines\n expandSelectionToLine(textarea)\n }\n \n // Apply the operation\n const result = operation(textarea)\n \n // Restore original selection/cursor with prefix adjustment\n if (options.adjustSelection) {\n // Use custom selection adjustment logic\n const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n const isRemoving = selectedText.startsWith(options.prefix)\n const adjusted = options.adjustSelection(isRemoving, originalStart, originalEnd, lineStart)\n result.selectionStart = adjusted.start\n result.selectionEnd = adjusted.end\n } else if (options.prefix) {\n // Use default prefix-based adjustment\n const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n const isRemoving = selectedText.startsWith(options.prefix)\n \n if (noInitialSelection) {\n // No selection - just restore cursor position\n if (isRemoving) {\n // When removing prefix, adjust cursor position\n result.selectionStart = Math.max(originalStart - options.prefix.length, lineStart)\n result.selectionEnd = result.selectionStart\n } else {\n // When adding prefix, adjust cursor position\n result.selectionStart = originalStart + options.prefix.length\n result.selectionEnd = result.selectionStart\n }\n } else {\n // Had a selection - restore it with adjustment\n if (isRemoving) {\n // When removing prefix, shift selection back\n result.selectionStart = Math.max(originalStart - options.prefix.length, lineStart)\n result.selectionEnd = Math.max(originalEnd - options.prefix.length, lineStart)\n } else {\n // When adding prefix, shift selection forward\n result.selectionStart = originalStart + options.prefix.length\n result.selectionEnd = originalEnd + options.prefix.length\n }\n }\n }\n \n return result\n}", "/**\n * Block-level text formatting operations\n * Handles inline formats like bold, italic, code, and links\n */\n\nimport { expandSelectedText, newlinesToSurroundSelectedText, isMultipleLines } from '../core/selection.js'\nimport { insertText } from '../core/insertion.js'\n\n/**\n * Apply block-level styling to selected text\n */\nexport function blockStyle(textarea, style) {\n let newlinesToAppend\n let newlinesToPrepend\n\n const { prefix, suffix, blockPrefix, blockSuffix, replaceNext, prefixSpace, scanFor, surroundWithNewlines, trimFirst } = style\n const originalSelectionStart = textarea.selectionStart\n const originalSelectionEnd = textarea.selectionEnd\n\n let selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n let prefixToUse = isMultipleLines(selectedText) && blockPrefix && blockPrefix.length > 0 ? `${blockPrefix}\\n` : prefix\n let suffixToUse = isMultipleLines(selectedText) && blockSuffix && blockSuffix.length > 0 ? `\\n${blockSuffix}` : suffix\n\n if (prefixSpace) {\n const beforeSelection = textarea.value[textarea.selectionStart - 1]\n if (textarea.selectionStart !== 0 && beforeSelection != null && !beforeSelection.match(/\\s/)) {\n prefixToUse = ` ${prefixToUse}`\n }\n }\n \n selectedText = expandSelectedText(textarea, prefixToUse, suffixToUse, style.multiline)\n let selectionStart = textarea.selectionStart\n let selectionEnd = textarea.selectionEnd\n const hasReplaceNext = replaceNext && replaceNext.length > 0 && suffixToUse.indexOf(replaceNext) > -1 && selectedText.length > 0\n \n if (surroundWithNewlines) {\n const ref = newlinesToSurroundSelectedText(textarea)\n newlinesToAppend = ref.newlinesToAppend\n newlinesToPrepend = ref.newlinesToPrepend\n prefixToUse = newlinesToAppend + prefix\n suffixToUse += newlinesToPrepend\n }\n\n // Check if we should remove formatting (toggle off)\n if (selectedText.startsWith(prefixToUse) && selectedText.endsWith(suffixToUse)) {\n const replacementText = selectedText.slice(prefixToUse.length, selectedText.length - suffixToUse.length)\n if (originalSelectionStart === originalSelectionEnd) {\n let position = originalSelectionStart - prefixToUse.length\n position = Math.max(position, selectionStart)\n position = Math.min(position, selectionStart + replacementText.length)\n selectionStart = selectionEnd = position\n } else {\n selectionEnd = selectionStart + replacementText.length\n }\n return { text: replacementText, selectionStart, selectionEnd }\n } else if (!hasReplaceNext) {\n // Add formatting\n let replacementText = prefixToUse + selectedText + suffixToUse\n selectionStart = originalSelectionStart + prefixToUse.length\n selectionEnd = originalSelectionEnd + prefixToUse.length\n const whitespaceEdges = selectedText.match(/^\\s*|\\s*$/g)\n if (trimFirst && whitespaceEdges) {\n const leadingWhitespace = whitespaceEdges[0] || ''\n const trailingWhitespace = whitespaceEdges[1] || ''\n replacementText = leadingWhitespace + prefixToUse + selectedText.trim() + suffixToUse + trailingWhitespace\n selectionStart += leadingWhitespace.length\n selectionEnd -= trailingWhitespace.length\n }\n return { text: replacementText, selectionStart, selectionEnd }\n } else if (scanFor && scanFor.length > 0 && selectedText.match(scanFor)) {\n // Handle link/image with URL detection\n suffixToUse = suffixToUse.replace(replaceNext, selectedText)\n const replacementText = prefixToUse + suffixToUse\n selectionStart = selectionEnd = selectionStart + prefixToUse.length\n return { text: replacementText, selectionStart, selectionEnd }\n } else {\n // Handle link/image with placeholder\n const replacementText = prefixToUse + selectedText + suffixToUse\n selectionStart = selectionStart + prefixToUse.length + selectedText.length + suffixToUse.indexOf(replaceNext)\n selectionEnd = selectionStart + replaceNext.length\n return { text: replacementText, selectionStart, selectionEnd }\n }\n}\n\n/**\n * Apply style to selected text in textarea\n */\nexport function styleSelectedText(textarea, style) {\n const text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n \n let result\n if (style.orderedList || style.unorderedList) {\n // Will be handled by list operations\n return\n } else if (style.multiline && isMultipleLines(text)) {\n result = multilineStyle(textarea, style)\n } else {\n result = blockStyle(textarea, style)\n }\n\n insertText(textarea, result)\n}\n\n/**\n * Apply multiline styling (quotes, task lists, etc)\n * Note: This does NOT expand selection to line - that should be done by the caller if needed\n */\nexport function multilineStyle(textarea, style) {\n const { prefix, suffix, surroundWithNewlines } = style\n let text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n let selectionStart = textarea.selectionStart\n let selectionEnd = textarea.selectionEnd\n const lines = text.split('\\n')\n \n // Check if we need to undo (all lines have the format)\n const undoStyle = lines.every(line => line.startsWith(prefix) && (!suffix || line.endsWith(suffix)))\n\n if (undoStyle) {\n // Remove the formatting\n text = lines.map(line => {\n let result = line.slice(prefix.length)\n if (suffix) {\n result = result.slice(0, result.length - suffix.length)\n }\n return result\n }).join('\\n')\n selectionEnd = selectionStart + text.length\n } else {\n // Apply the formatting\n text = lines.map(line => prefix + line + (suffix || '')).join('\\n')\n if (surroundWithNewlines) {\n const { newlinesToAppend, newlinesToPrepend } = newlinesToSurroundSelectedText(textarea)\n selectionStart += newlinesToAppend.length\n selectionEnd = selectionStart + text.length\n text = newlinesToAppend + text + newlinesToPrepend\n }\n }\n\n return { text, selectionStart, selectionEnd }\n}", "/**\n * List operations for bullet and numbered lists\n */\n\nimport { expandSelectionToLine, newlinesToSurroundSelectedText, applyLineOperation } from '../core/selection.js'\nimport { insertText } from '../core/insertion.js'\n\n/**\n * Undo ordered list formatting\n */\nfunction undoOrderedListStyle(text) {\n const lines = text.split('\\n')\n const orderedListRegex = /^\\d+\\.\\s+/\n const shouldUndoOrderedList = lines.every(line => orderedListRegex.test(line))\n let result = lines\n if (shouldUndoOrderedList) {\n result = lines.map(line => line.replace(orderedListRegex, ''))\n }\n\n return {\n text: result.join('\\n'),\n processed: shouldUndoOrderedList\n }\n}\n\n/**\n * Undo unordered list formatting\n */\nfunction undoUnorderedListStyle(text) {\n const lines = text.split('\\n')\n const unorderedListPrefix = '- '\n const shouldUndoUnorderedList = lines.every(line => line.startsWith(unorderedListPrefix))\n let result = lines\n if (shouldUndoUnorderedList) {\n result = lines.map(line => line.slice(unorderedListPrefix.length))\n }\n\n return {\n text: result.join('\\n'),\n processed: shouldUndoUnorderedList\n }\n}\n\n/**\n * Make prefix for list item\n */\nfunction makePrefix(index, unorderedList) {\n if (unorderedList) {\n return '- '\n } else {\n return `${index + 1}. `\n }\n}\n\n/**\n * Clear existing list style\n */\nfunction clearExistingListStyle(style, selectedText) {\n let undoResult\n let undoResultOppositeList\n let pristineText\n \n if (style.orderedList) {\n undoResult = undoOrderedListStyle(selectedText)\n undoResultOppositeList = undoUnorderedListStyle(undoResult.text)\n pristineText = undoResultOppositeList.text\n } else {\n undoResult = undoUnorderedListStyle(selectedText)\n undoResultOppositeList = undoOrderedListStyle(undoResult.text)\n pristineText = undoResultOppositeList.text\n }\n \n return [undoResult, undoResultOppositeList, pristineText]\n}\n\n/**\n * Apply list styling to selected text\n */\nexport function listStyle(textarea, style) {\n const noInitialSelection = textarea.selectionStart === textarea.selectionEnd\n let selectionStart = textarea.selectionStart\n let selectionEnd = textarea.selectionEnd\n\n // Select whole line\n expandSelectionToLine(textarea)\n\n const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n\n // Clear any existing list formatting\n const [undoResult, undoResultOppositeList, pristineText] = clearExistingListStyle(style, selectedText)\n\n const prefixedLines = pristineText.split('\\n').map((value, index) => {\n return `${makePrefix(index, style.unorderedList)}${value}`\n })\n\n const totalPrefixLength = prefixedLines.reduce((previousValue, _currentValue, currentIndex) => {\n return previousValue + makePrefix(currentIndex, style.unorderedList).length\n }, 0)\n\n const totalPrefixLengthOppositeList = prefixedLines.reduce((previousValue, _currentValue, currentIndex) => {\n return previousValue + makePrefix(currentIndex, !style.unorderedList).length\n }, 0)\n\n // If we're undoing the same list type, just return the pristine text\n if (undoResult.processed) {\n if (noInitialSelection) {\n selectionStart = Math.max(selectionStart - makePrefix(0, style.unorderedList).length, 0)\n selectionEnd = selectionStart\n } else {\n selectionStart = textarea.selectionStart\n selectionEnd = textarea.selectionEnd - totalPrefixLength\n }\n return { text: pristineText, selectionStart, selectionEnd }\n }\n\n // Apply new list formatting\n const { newlinesToAppend, newlinesToPrepend } = newlinesToSurroundSelectedText(textarea)\n const text = newlinesToAppend + prefixedLines.join('\\n') + newlinesToPrepend\n\n if (noInitialSelection) {\n selectionStart = Math.max(selectionStart + makePrefix(0, style.unorderedList).length + newlinesToAppend.length, 0)\n selectionEnd = selectionStart\n } else {\n if (undoResultOppositeList.processed) {\n // Converting from one list type to another\n selectionStart = Math.max(textarea.selectionStart + newlinesToAppend.length, 0)\n selectionEnd = textarea.selectionEnd + newlinesToAppend.length + totalPrefixLength - totalPrefixLengthOppositeList\n } else {\n // Adding list formatting to plain text\n selectionStart = Math.max(textarea.selectionStart + newlinesToAppend.length, 0)\n selectionEnd = textarea.selectionEnd + newlinesToAppend.length + totalPrefixLength\n }\n }\n\n return { text, selectionStart, selectionEnd }\n}\n\n/**\n * Apply list style to textarea\n */\nexport function applyListStyle(textarea, style) {\n // Use applyLineOperation for consistent selection preservation\n const result = applyLineOperation(\n textarea,\n (ta) => listStyle(ta, style),\n {\n // Custom selection adjustment for lists\n adjustSelection: (isRemoving, selStart, selEnd, lineStart) => {\n // Get the current line to check if we're removing\n const currentLine = textarea.value.slice(lineStart, textarea.selectionEnd)\n const orderedListRegex = /^\\d+\\.\\s+/\n const unorderedListRegex = /^- /\n \n // Check if we're removing a list\n const hasOrderedList = orderedListRegex.test(currentLine)\n const hasUnorderedList = unorderedListRegex.test(currentLine)\n const isRemovingCurrent = (style.orderedList && hasOrderedList) || (style.unorderedList && hasUnorderedList)\n \n if (selStart === selEnd) {\n // No selection - cursor position\n if (isRemovingCurrent) {\n // Removing list - adjust cursor back\n const prefixMatch = currentLine.match(style.orderedList ? orderedListRegex : unorderedListRegex)\n const prefixLength = prefixMatch ? prefixMatch[0].length : 0\n return {\n start: Math.max(selStart - prefixLength, lineStart),\n end: Math.max(selStart - prefixLength, lineStart)\n }\n } else if (hasOrderedList || hasUnorderedList) {\n // Converting from one list type to another\n const oldPrefixMatch = currentLine.match(hasOrderedList ? orderedListRegex : unorderedListRegex)\n const oldPrefixLength = oldPrefixMatch ? oldPrefixMatch[0].length : 0\n const newPrefixLength = style.unorderedList ? 2 : 3 // \"- \" or \"1. \"\n const adjustment = newPrefixLength - oldPrefixLength\n return {\n start: selStart + adjustment,\n end: selStart + adjustment\n }\n } else {\n // Adding new list\n const prefixLength = style.unorderedList ? 2 : 3 // \"- \" or \"1. \"\n return {\n start: selStart + prefixLength,\n end: selStart + prefixLength\n }\n }\n } else {\n // Has selection - preserve it\n if (isRemovingCurrent) {\n // Removing current list type\n const prefixMatch = currentLine.match(style.orderedList ? orderedListRegex : unorderedListRegex)\n const prefixLength = prefixMatch ? prefixMatch[0].length : 0\n return {\n start: Math.max(selStart - prefixLength, lineStart),\n end: Math.max(selEnd - prefixLength, lineStart)\n }\n } else if (hasOrderedList || hasUnorderedList) {\n // Converting from one list type to another\n const oldPrefixMatch = currentLine.match(hasOrderedList ? orderedListRegex : unorderedListRegex)\n const oldPrefixLength = oldPrefixMatch ? oldPrefixMatch[0].length : 0\n const newPrefixLength = style.unorderedList ? 2 : 3 // \"- \" or \"1. \"\n const adjustment = newPrefixLength - oldPrefixLength\n return {\n start: selStart + adjustment,\n end: selEnd + adjustment\n }\n } else {\n // Adding new list\n const prefixLength = style.unorderedList ? 2 : 3 // \"- \" or \"1. \"\n return {\n start: selStart + prefixLength,\n end: selEnd + prefixLength\n }\n }\n }\n }\n }\n )\n \n insertText(textarea, result)\n}", "/**\n * Format detection utilities\n */\n\nimport { FORMATS } from './formats.js'\n\n/**\n * Check if text has a specific format applied\n */\nfunction hasFormatApplied(text, format) {\n if (!format.prefix) return false\n \n if (format.suffix) {\n return text.startsWith(format.prefix) && text.endsWith(format.suffix)\n } else {\n return text.startsWith(format.prefix)\n }\n}\n\n/**\n * Get active formats at cursor position\n */\nexport function getActiveFormats(textarea) {\n if (!textarea) return []\n \n const formats = []\n const { selectionStart, selectionEnd, value } = textarea\n \n // Get current line for line-based formats\n const lines = value.split('\\n')\n let lineStart = 0\n let currentLine = ''\n \n for (const line of lines) {\n if (selectionStart >= lineStart && selectionStart <= lineStart + line.length) {\n currentLine = line\n break\n }\n lineStart += line.length + 1\n }\n \n // Check line-based formats\n if (currentLine.startsWith('- ')) {\n if (currentLine.startsWith('- [ ] ') || currentLine.startsWith('- [x] ')) {\n formats.push('task-list')\n } else {\n formats.push('bullet-list')\n }\n }\n \n if (/^\\d+\\.\\s/.test(currentLine)) {\n formats.push('numbered-list')\n }\n \n if (currentLine.startsWith('> ')) {\n formats.push('quote')\n }\n \n if (currentLine.startsWith('# ')) formats.push('header')\n if (currentLine.startsWith('## ')) formats.push('header-2')\n if (currentLine.startsWith('### ')) formats.push('header-3')\n \n // Check inline formats by looking around cursor\n const lookBehind = Math.max(0, selectionStart - 10)\n const lookAhead = Math.min(value.length, selectionEnd + 10)\n const surrounding = value.slice(lookBehind, lookAhead)\n \n // Check for bold\n if (surrounding.includes('**')) {\n const beforeCursor = value.slice(Math.max(0, selectionStart - 100), selectionStart)\n const afterCursor = value.slice(selectionEnd, Math.min(value.length, selectionEnd + 100))\n const lastOpenBold = beforeCursor.lastIndexOf('**')\n const nextCloseBold = afterCursor.indexOf('**')\n if (lastOpenBold !== -1 && nextCloseBold !== -1) {\n formats.push('bold')\n }\n }\n \n // Check for italic\n if (surrounding.includes('_')) {\n const beforeCursor = value.slice(Math.max(0, selectionStart - 100), selectionStart)\n const afterCursor = value.slice(selectionEnd, Math.min(value.length, selectionEnd + 100))\n const lastOpenItalic = beforeCursor.lastIndexOf('_')\n const nextCloseItalic = afterCursor.indexOf('_')\n if (lastOpenItalic !== -1 && nextCloseItalic !== -1) {\n formats.push('italic')\n }\n }\n \n // Check for code\n if (surrounding.includes('`')) {\n const beforeCursor = value.slice(Math.max(0, selectionStart - 100), selectionStart)\n const afterCursor = value.slice(selectionEnd, Math.min(value.length, selectionEnd + 100))\n if (beforeCursor.includes('`') && afterCursor.includes('`')) {\n formats.push('code')\n }\n }\n \n // Check for link\n if (surrounding.includes('[') && surrounding.includes(']')) {\n const beforeCursor = value.slice(Math.max(0, selectionStart - 100), selectionStart)\n const afterCursor = value.slice(selectionEnd, Math.min(value.length, selectionEnd + 100))\n const lastOpenBracket = beforeCursor.lastIndexOf('[')\n const nextCloseBracket = afterCursor.indexOf(']')\n if (lastOpenBracket !== -1 && nextCloseBracket !== -1) {\n const afterBracket = value.slice(selectionEnd + nextCloseBracket + 1, selectionEnd + nextCloseBracket + 10)\n if (afterBracket.startsWith('(')) {\n formats.push('link')\n }\n }\n }\n \n return formats\n}\n\n/**\n * Check if specific format is active at cursor\n */\nexport function hasFormat(textarea, format) {\n const activeFormats = getActiveFormats(textarea)\n return activeFormats.includes(format)\n}\n\n/**\n * Expand selection based on options\n */\nexport function expandSelection(textarea, options = {}) {\n if (!textarea) return\n \n const { toWord, toLine, toFormat } = options\n const { selectionStart, selectionEnd, value } = textarea\n \n if (toLine) {\n // Find line boundaries\n const lines = value.split('\\n')\n let lineStart = 0\n let lineEnd = 0\n let currentPos = 0\n \n for (const line of lines) {\n if (selectionStart >= currentPos && selectionStart <= currentPos + line.length) {\n lineStart = currentPos\n lineEnd = currentPos + line.length\n break\n }\n currentPos += line.length + 1\n }\n \n textarea.selectionStart = lineStart\n textarea.selectionEnd = lineEnd\n } else if (toWord && selectionStart === selectionEnd) {\n // Find word boundaries\n let start = selectionStart\n let end = selectionEnd\n \n // Move start back to word boundary\n while (start > 0 && !/\\s/.test(value[start - 1])) {\n start--\n }\n \n // Move end forward to word boundary\n while (end < value.length && !/\\s/.test(value[end])) {\n end++\n }\n \n textarea.selectionStart = start\n textarea.selectionEnd = end\n }\n}", "/**\n * markdown-actions - Lightweight markdown toolbar functionality\n * Based on GitHub's markdown-toolbar-element\n */\n\nimport { FORMATS, mergeWithDefaults } from './core/formats.js'\nimport { insertText, setUndoMethod } from './core/insertion.js'\nimport { preserveSelection, isMultipleLines, expandSelectionToLine, applyLineOperation } from './core/selection.js'\nimport { blockStyle, multilineStyle } from './operations/block.js'\nimport { applyListStyle } from './operations/list.js'\nimport { getActiveFormats as getActive, hasFormat as has, expandSelection as expand } from './core/detection.js'\nimport { debugLog, debugSelection, debugResult, setDebugMode, getDebugMode } from './debug.js'\n\n/**\n * Toggle bold formatting\n */\nexport function toggleBold(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n \n debugLog('toggleBold', 'Starting');\n debugSelection(textarea, 'Before');\n \n const style = mergeWithDefaults(FORMATS.bold)\n const result = blockStyle(textarea, style)\n \n debugResult(result);\n \n insertText(textarea, result)\n \n debugSelection(textarea, 'After');\n}\n\n/**\n * Toggle italic formatting\n */\nexport function toggleItalic(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n const style = mergeWithDefaults(FORMATS.italic)\n const result = blockStyle(textarea, style)\n insertText(textarea, result)\n}\n\n/**\n * Toggle code formatting\n */\nexport function toggleCode(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n \n // blockStyle already handles both inline and block code correctly\n const style = mergeWithDefaults(FORMATS.code)\n const result = blockStyle(textarea, style)\n insertText(textarea, result)\n}\n\n/**\n * Insert or toggle link formatting\n */\nexport function insertLink(textarea, options = {}) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n \n const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n let style = mergeWithDefaults(FORMATS.link)\n \n // Check if selected text is a URL\n const isURL = selectedText && selectedText.match(/^https?:\\/\\//)\n \n if (isURL && !options.url) {\n // If selected text is a URL, use it as both link text and URL\n style.suffix = `](${selectedText})`\n style.replaceNext = ''\n // Don't change the selected text, it becomes the link text\n } else if (options.url) {\n // Override with custom URL if provided\n style.suffix = `](${options.url})`\n style.replaceNext = ''\n }\n \n // Override with custom text if provided\n if (options.text && !selectedText) {\n // Insert the text and select it\n const pos = textarea.selectionStart\n textarea.value = textarea.value.slice(0, pos) + options.text + textarea.value.slice(pos)\n textarea.selectionStart = pos\n textarea.selectionEnd = pos + options.text.length\n }\n \n const result = blockStyle(textarea, style)\n insertText(textarea, result)\n}\n\n/**\n * Toggle bullet list formatting\n */\nexport function toggleBulletList(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n const style = mergeWithDefaults(FORMATS.bulletList)\n applyListStyle(textarea, style)\n}\n\n/**\n * Toggle numbered list formatting\n */\nexport function toggleNumberedList(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n const style = mergeWithDefaults(FORMATS.numberedList)\n applyListStyle(textarea, style)\n}\n\n/**\n * Toggle quote formatting\n * Matches GitHub's implementation for quotes\n */\nexport function toggleQuote(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n \n debugLog('toggleQuote', 'Starting');\n debugSelection(textarea, 'Initial');\n \n const style = mergeWithDefaults(FORMATS.quote)\n \n // Use the reusable line operation helper\n const result = applyLineOperation(\n textarea,\n (ta) => multilineStyle(ta, style),\n { prefix: style.prefix }\n )\n \n debugResult(result);\n insertText(textarea, result)\n debugSelection(textarea, 'Final');\n}\n\n/**\n * Toggle task list formatting\n * Matches GitHub's implementation for task lists\n */\nexport function toggleTaskList(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n \n const style = mergeWithDefaults(FORMATS.taskList)\n \n // Use the reusable line operation helper\n const result = applyLineOperation(\n textarea,\n (ta) => multilineStyle(ta, style),\n { prefix: style.prefix }\n )\n \n insertText(textarea, result)\n}\n\n/**\n * Insert or toggle header with specific level\n */\nexport function insertHeader(textarea, level = 1, toggle = false) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n if (level < 1 || level > 6) level = 1\n \n debugLog('insertHeader', `Level: ${level}, Toggle: ${toggle}`);\n \n const headerKey = `header${level === 1 ? '1' : level}`\n const style = mergeWithDefaults(FORMATS[headerKey] || FORMATS.header1)\n \n // Save original cursor position\n const originalStart = textarea.selectionStart\n const originalEnd = textarea.selectionEnd\n const value = textarea.value\n \n // Find line boundaries\n let lineStart = originalStart\n while (lineStart > 0 && value[lineStart - 1] !== '\\n') {\n lineStart--\n }\n \n let lineEnd = originalEnd\n while (lineEnd < value.length && value[lineEnd] !== '\\n') {\n lineEnd++\n }\n \n // Get the current line\n const currentLine = value.slice(lineStart, lineEnd)\n debugLog('insertHeader', `Current line: \"${currentLine}\"`);\n \n // Check for existing header\n const existingHeaderMatch = currentLine.match(/^(#{1,6})\\s*/)\n const existingLevel = existingHeaderMatch ? existingHeaderMatch[1].length : 0\n const existingPrefixLength = existingHeaderMatch ? existingHeaderMatch[0].length : 0\n \n debugLog('insertHeader', `Existing level: ${existingLevel}, Target level: ${level}`);\n \n // Determine the new line content\n let newLine\n let prefixChange = 0\n \n if (toggle && existingLevel === level) {\n // Toggle off - remove the header\n debugLog('insertHeader', 'Toggling OFF header');\n newLine = currentLine.replace(/^#{1,6}\\s*/, '')\n prefixChange = -existingPrefixLength\n } else if (existingLevel > 0) {\n // Replace existing header with new one\n debugLog('insertHeader', 'Replacing header');\n const cleanedLine = currentLine.replace(/^#{1,6}\\s*/, '')\n newLine = style.prefix + cleanedLine\n prefixChange = style.prefix.length - existingPrefixLength\n } else {\n // Add new header\n debugLog('insertHeader', 'Adding new header');\n newLine = style.prefix + currentLine\n prefixChange = style.prefix.length\n }\n \n // Build the result\n const result = {\n text: newLine,\n selectionStart: lineStart,\n selectionEnd: lineEnd\n }\n \n // Adjust cursor position based on prefix change\n if (originalStart === originalEnd) {\n // No selection - adjust cursor position\n result.selectionStart = Math.max(originalStart + prefixChange, lineStart)\n result.selectionEnd = result.selectionStart\n } else {\n // Has selection - preserve it with adjustment\n result.selectionStart = Math.max(originalStart + prefixChange, lineStart)\n result.selectionEnd = Math.max(originalEnd + prefixChange, lineStart)\n }\n \n debugLog('insertHeader', `Result: \"${result.text}\" (${result.selectionStart}, ${result.selectionEnd})`);\n \n // Expand selection to full line for replacement\n textarea.selectionStart = lineStart\n textarea.selectionEnd = lineEnd\n \n insertText(textarea, result)\n}\n\n/**\n * Toggle H1 header\n */\nexport function toggleH1(textarea) {\n insertHeader(textarea, 1, true)\n}\n\n/**\n * Toggle H2 header\n */\nexport function toggleH2(textarea) {\n insertHeader(textarea, 2, true)\n}\n\n/**\n * Toggle H3 header\n */\nexport function toggleH3(textarea) {\n insertHeader(textarea, 3, true)\n}\n\n/**\n * Get active formats at cursor position\n */\nexport function getActiveFormats(textarea) {\n return getActive(textarea)\n}\n\n/**\n * Check if format is active at cursor\n */\nexport function hasFormat(textarea, format) {\n return has(textarea, format)\n}\n\n/**\n * Expand selection based on options\n */\nexport function expandSelection(textarea, options = {}) {\n expand(textarea, options)\n}\n\n/**\n * Apply custom format\n */\nexport function applyCustomFormat(textarea, format) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n \n const style = mergeWithDefaults(format)\n let result\n \n if (style.multiline) {\n const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n if (isMultipleLines(selectedText)) {\n result = multilineStyle(textarea, style)\n } else {\n result = blockStyle(textarea, style)\n }\n } else {\n result = blockStyle(textarea, style)\n }\n \n insertText(textarea, result)\n}\n\n/**\n * Preserve selection during callback\n */\nexport { preserveSelection }\n\n/**\n * Configure undo method\n */\nexport { setUndoMethod }\n\n/**\n * Debug mode control\n */\nexport { setDebugMode, getDebugMode }\n\n/**\n * Default export with all functions\n */\nexport default {\n toggleBold,\n toggleItalic,\n toggleCode,\n insertLink,\n toggleBulletList,\n toggleNumberedList,\n toggleQuote,\n toggleTaskList,\n insertHeader,\n toggleH1,\n toggleH2,\n toggleH3,\n getActiveFormats,\n hasFormat,\n expandSelection,\n applyCustomFormat,\n preserveSelection,\n setUndoMethod,\n setDebugMode,\n getDebugMode\n}"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["debugMode", "getActiveFormats", "hasFormat", "expandSelection", "getActiveFormats", "hasFormat", "expandSelection"]
|
|
7
7
|
}
|
package/dist/markdown-actions.js
CHANGED
|
@@ -856,11 +856,12 @@ ${blockSuffix}` : suffix;
|
|
|
856
856
|
return;
|
|
857
857
|
if (level < 1 || level > 6)
|
|
858
858
|
level = 1;
|
|
859
|
+
debugLog("insertHeader", `Level: ${level}, Toggle: ${toggle}`);
|
|
859
860
|
const headerKey = `header${level === 1 ? "1" : level}`;
|
|
860
861
|
const style = mergeWithDefaults(FORMATS[headerKey] || FORMATS.header1);
|
|
861
|
-
const value = textarea.value;
|
|
862
862
|
const originalStart = textarea.selectionStart;
|
|
863
863
|
const originalEnd = textarea.selectionEnd;
|
|
864
|
+
const value = textarea.value;
|
|
864
865
|
let lineStart = originalStart;
|
|
865
866
|
while (lineStart > 0 && value[lineStart - 1] !== "\n") {
|
|
866
867
|
lineStart--;
|
|
@@ -869,54 +870,43 @@ ${blockSuffix}` : suffix;
|
|
|
869
870
|
while (lineEnd < value.length && value[lineEnd] !== "\n") {
|
|
870
871
|
lineEnd++;
|
|
871
872
|
}
|
|
872
|
-
const
|
|
873
|
-
|
|
873
|
+
const currentLine = value.slice(lineStart, lineEnd);
|
|
874
|
+
debugLog("insertHeader", `Current line: "${currentLine}"`);
|
|
875
|
+
const existingHeaderMatch = currentLine.match(/^(#{1,6})\s*/);
|
|
874
876
|
const existingLevel = existingHeaderMatch ? existingHeaderMatch[1].length : 0;
|
|
875
|
-
const
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
start: selStart + prefixDiff,
|
|
909
|
-
end: selEnd + prefixDiff
|
|
910
|
-
};
|
|
911
|
-
} else {
|
|
912
|
-
return {
|
|
913
|
-
start: selStart + style.prefix.length,
|
|
914
|
-
end: selEnd + style.prefix.length
|
|
915
|
-
};
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
);
|
|
877
|
+
const existingPrefixLength = existingHeaderMatch ? existingHeaderMatch[0].length : 0;
|
|
878
|
+
debugLog("insertHeader", `Existing level: ${existingLevel}, Target level: ${level}`);
|
|
879
|
+
let newLine;
|
|
880
|
+
let prefixChange = 0;
|
|
881
|
+
if (toggle && existingLevel === level) {
|
|
882
|
+
debugLog("insertHeader", "Toggling OFF header");
|
|
883
|
+
newLine = currentLine.replace(/^#{1,6}\s*/, "");
|
|
884
|
+
prefixChange = -existingPrefixLength;
|
|
885
|
+
} else if (existingLevel > 0) {
|
|
886
|
+
debugLog("insertHeader", "Replacing header");
|
|
887
|
+
const cleanedLine = currentLine.replace(/^#{1,6}\s*/, "");
|
|
888
|
+
newLine = style.prefix + cleanedLine;
|
|
889
|
+
prefixChange = style.prefix.length - existingPrefixLength;
|
|
890
|
+
} else {
|
|
891
|
+
debugLog("insertHeader", "Adding new header");
|
|
892
|
+
newLine = style.prefix + currentLine;
|
|
893
|
+
prefixChange = style.prefix.length;
|
|
894
|
+
}
|
|
895
|
+
const result = {
|
|
896
|
+
text: newLine,
|
|
897
|
+
selectionStart: lineStart,
|
|
898
|
+
selectionEnd: lineEnd
|
|
899
|
+
};
|
|
900
|
+
if (originalStart === originalEnd) {
|
|
901
|
+
result.selectionStart = Math.max(originalStart + prefixChange, lineStart);
|
|
902
|
+
result.selectionEnd = result.selectionStart;
|
|
903
|
+
} else {
|
|
904
|
+
result.selectionStart = Math.max(originalStart + prefixChange, lineStart);
|
|
905
|
+
result.selectionEnd = Math.max(originalEnd + prefixChange, lineStart);
|
|
906
|
+
}
|
|
907
|
+
debugLog("insertHeader", `Result: "${result.text}" (${result.selectionStart}, ${result.selectionEnd})`);
|
|
908
|
+
textarea.selectionStart = lineStart;
|
|
909
|
+
textarea.selectionEnd = lineEnd;
|
|
920
910
|
insertText(textarea, result);
|
|
921
911
|
}
|
|
922
912
|
function toggleH1(textarea) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.js", "../src/core/formats.js", "../src/debug.js", "../src/core/insertion.js", "../src/core/selection.js", "../src/operations/block.js", "../src/operations/list.js", "../src/core/detection.js"],
|
|
4
|
-
"sourcesContent": ["/**\n * markdown-actions - Lightweight markdown toolbar functionality\n * Based on GitHub's markdown-toolbar-element\n */\n\nimport { FORMATS, mergeWithDefaults } from './core/formats.js'\nimport { insertText, setUndoMethod } from './core/insertion.js'\nimport { preserveSelection, isMultipleLines, expandSelectionToLine, applyLineOperation } from './core/selection.js'\nimport { blockStyle, multilineStyle } from './operations/block.js'\nimport { applyListStyle } from './operations/list.js'\nimport { getActiveFormats as getActive, hasFormat as has, expandSelection as expand } from './core/detection.js'\nimport { debugLog, debugSelection, debugResult, setDebugMode, getDebugMode } from './debug.js'\n\n/**\n * Toggle bold formatting\n */\nexport function toggleBold(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n \n debugLog('toggleBold', 'Starting');\n debugSelection(textarea, 'Before');\n \n const style = mergeWithDefaults(FORMATS.bold)\n const result = blockStyle(textarea, style)\n \n debugResult(result);\n \n insertText(textarea, result)\n \n debugSelection(textarea, 'After');\n}\n\n/**\n * Toggle italic formatting\n */\nexport function toggleItalic(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n const style = mergeWithDefaults(FORMATS.italic)\n const result = blockStyle(textarea, style)\n insertText(textarea, result)\n}\n\n/**\n * Toggle code formatting\n */\nexport function toggleCode(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n \n // blockStyle already handles both inline and block code correctly\n const style = mergeWithDefaults(FORMATS.code)\n const result = blockStyle(textarea, style)\n insertText(textarea, result)\n}\n\n/**\n * Insert or toggle link formatting\n */\nexport function insertLink(textarea, options = {}) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n \n const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n let style = mergeWithDefaults(FORMATS.link)\n \n // Check if selected text is a URL\n const isURL = selectedText && selectedText.match(/^https?:\\/\\//)\n \n if (isURL && !options.url) {\n // If selected text is a URL, use it as both link text and URL\n style.suffix = `](${selectedText})`\n style.replaceNext = ''\n // Don't change the selected text, it becomes the link text\n } else if (options.url) {\n // Override with custom URL if provided\n style.suffix = `](${options.url})`\n style.replaceNext = ''\n }\n \n // Override with custom text if provided\n if (options.text && !selectedText) {\n // Insert the text and select it\n const pos = textarea.selectionStart\n textarea.value = textarea.value.slice(0, pos) + options.text + textarea.value.slice(pos)\n textarea.selectionStart = pos\n textarea.selectionEnd = pos + options.text.length\n }\n \n const result = blockStyle(textarea, style)\n insertText(textarea, result)\n}\n\n/**\n * Toggle bullet list formatting\n */\nexport function toggleBulletList(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n const style = mergeWithDefaults(FORMATS.bulletList)\n applyListStyle(textarea, style)\n}\n\n/**\n * Toggle numbered list formatting\n */\nexport function toggleNumberedList(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n const style = mergeWithDefaults(FORMATS.numberedList)\n applyListStyle(textarea, style)\n}\n\n/**\n * Toggle quote formatting\n * Matches GitHub's implementation for quotes\n */\nexport function toggleQuote(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n \n debugLog('toggleQuote', 'Starting');\n debugSelection(textarea, 'Initial');\n \n const style = mergeWithDefaults(FORMATS.quote)\n \n // Use the reusable line operation helper\n const result = applyLineOperation(\n textarea,\n (ta) => multilineStyle(ta, style),\n { prefix: style.prefix }\n )\n \n debugResult(result);\n insertText(textarea, result)\n debugSelection(textarea, 'Final');\n}\n\n/**\n * Toggle task list formatting\n * Matches GitHub's implementation for task lists\n */\nexport function toggleTaskList(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n \n const style = mergeWithDefaults(FORMATS.taskList)\n \n // Use the reusable line operation helper\n const result = applyLineOperation(\n textarea,\n (ta) => multilineStyle(ta, style),\n { prefix: style.prefix }\n )\n \n insertText(textarea, result)\n}\n\n/**\n * Insert or toggle header with specific level\n */\nexport function insertHeader(textarea, level = 1, toggle = false) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n if (level < 1 || level > 6) level = 1\n \n const headerKey = `header${level === 1 ? '1' : level}`\n const style = mergeWithDefaults(FORMATS[headerKey] || FORMATS.header1)\n \n // Get the current line to check existing header BEFORE any operations\n const value = textarea.value\n const originalStart = textarea.selectionStart\n const originalEnd = textarea.selectionEnd\n \n // Find the start of the current line\n let lineStart = originalStart\n while (lineStart > 0 && value[lineStart - 1] !== '\\n') {\n lineStart--\n }\n \n // Find the end of the current line \n let lineEnd = originalEnd\n while (lineEnd < value.length && value[lineEnd] !== '\\n') {\n lineEnd++\n }\n \n // Get current line content\n const currentLineContent = value.slice(lineStart, lineEnd)\n const existingHeaderMatch = currentLineContent.match(/^(#{1,6})\\s*/)\n const existingLevel = existingHeaderMatch ? existingHeaderMatch[1].length : 0\n \n // Use applyLineOperation for consistent behavior\n const result = applyLineOperation(\n textarea,\n (ta) => {\n const currentLine = ta.value.slice(ta.selectionStart, ta.selectionEnd)\n \n // Remove any existing header formatting\n const cleanedLine = currentLine.replace(/^#{1,6}\\s*/, '')\n \n let newLine\n \n // If toggle mode and current line has the same header level, remove it\n if (toggle && existingLevel === level) {\n newLine = cleanedLine\n } else if (existingLevel > 0) {\n // Replace existing header with new one\n newLine = style.prefix + cleanedLine\n } else {\n // Apply new header\n newLine = style.prefix + cleanedLine\n }\n \n return {\n text: newLine,\n selectionStart: ta.selectionStart,\n selectionEnd: ta.selectionEnd\n }\n },\n {\n prefix: style.prefix,\n // Custom handler for header-specific logic\n adjustSelection: (isRemoving, selStart, selEnd, lineStart) => {\n const existingPrefixLength = existingHeaderMatch ? existingHeaderMatch[0].length : 0\n \n // Check if we're actually removing (toggle off)\n const actuallyRemoving = toggle && existingLevel === level\n \n if (actuallyRemoving) {\n // Removing the header entirely\n return {\n start: Math.max(selStart - existingPrefixLength, lineStart),\n end: Math.max(selEnd - existingPrefixLength, lineStart)\n }\n } else if (existingPrefixLength > 0) {\n // Replacing existing header with new one\n const prefixDiff = style.prefix.length - existingPrefixLength\n return {\n start: selStart + prefixDiff,\n end: selEnd + prefixDiff\n }\n } else {\n // Adding new header\n return {\n start: selStart + style.prefix.length,\n end: selEnd + style.prefix.length\n }\n }\n }\n }\n )\n \n insertText(textarea, result)\n}\n\n/**\n * Toggle H1 header\n */\nexport function toggleH1(textarea) {\n insertHeader(textarea, 1, true)\n}\n\n/**\n * Toggle H2 header\n */\nexport function toggleH2(textarea) {\n insertHeader(textarea, 2, true)\n}\n\n/**\n * Toggle H3 header\n */\nexport function toggleH3(textarea) {\n insertHeader(textarea, 3, true)\n}\n\n/**\n * Get active formats at cursor position\n */\nexport function getActiveFormats(textarea) {\n return getActive(textarea)\n}\n\n/**\n * Check if format is active at cursor\n */\nexport function hasFormat(textarea, format) {\n return has(textarea, format)\n}\n\n/**\n * Expand selection based on options\n */\nexport function expandSelection(textarea, options = {}) {\n expand(textarea, options)\n}\n\n/**\n * Apply custom format\n */\nexport function applyCustomFormat(textarea, format) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n \n const style = mergeWithDefaults(format)\n let result\n \n if (style.multiline) {\n const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n if (isMultipleLines(selectedText)) {\n result = multilineStyle(textarea, style)\n } else {\n result = blockStyle(textarea, style)\n }\n } else {\n result = blockStyle(textarea, style)\n }\n \n insertText(textarea, result)\n}\n\n/**\n * Preserve selection during callback\n */\nexport { preserveSelection }\n\n/**\n * Configure undo method\n */\nexport { setUndoMethod }\n\n/**\n * Debug mode control\n */\nexport { setDebugMode, getDebugMode }\n\n/**\n * Default export with all functions\n */\nexport default {\n toggleBold,\n toggleItalic,\n toggleCode,\n insertLink,\n toggleBulletList,\n toggleNumberedList,\n toggleQuote,\n toggleTaskList,\n insertHeader,\n toggleH1,\n toggleH2,\n toggleH3,\n getActiveFormats,\n hasFormat,\n expandSelection,\n applyCustomFormat,\n preserveSelection,\n setUndoMethod,\n setDebugMode,\n getDebugMode\n}", "/**\n * Format definitions for markdown syntax\n */\n\nexport const FORMATS = {\n bold: {\n prefix: '**',\n suffix: '**',\n trimFirst: true\n },\n italic: {\n prefix: '_',\n suffix: '_',\n trimFirst: true\n },\n code: {\n prefix: '`',\n suffix: '`',\n blockPrefix: '```',\n blockSuffix: '```'\n },\n link: {\n prefix: '[',\n suffix: '](url)',\n replaceNext: 'url',\n scanFor: 'https?://'\n },\n bulletList: {\n prefix: '- ',\n multiline: true,\n unorderedList: true\n },\n numberedList: {\n prefix: '1. ',\n multiline: true,\n orderedList: true\n },\n quote: {\n prefix: '> ',\n multiline: true,\n surroundWithNewlines: true\n },\n taskList: {\n prefix: '- [ ] ',\n multiline: true,\n surroundWithNewlines: true\n },\n header1: { prefix: '# ' },\n header2: { prefix: '## ' },\n header3: { prefix: '### ' },\n header4: { prefix: '#### ' },\n header5: { prefix: '##### ' },\n header6: { prefix: '###### ' }\n}\n\n/**\n * Default style configuration\n */\nexport function getDefaultStyle() {\n return {\n prefix: '',\n suffix: '',\n blockPrefix: '',\n blockSuffix: '',\n multiline: false,\n replaceNext: '',\n prefixSpace: false,\n scanFor: '',\n surroundWithNewlines: false,\n orderedList: false,\n unorderedList: false,\n trimFirst: false\n }\n}\n\n/**\n * Merge format with defaults\n */\nexport function mergeWithDefaults(format) {\n return { ...getDefaultStyle(), ...format }\n}", "/**\n * Debug utilities for markdown-actions\n * Add console logging to track what's happening\n */\n\n// Debug mode flag - disabled by default\nlet debugMode = false;\n\n/**\n * Enable or disable debug mode\n * @param {boolean} enabled - Whether to enable debug mode\n */\nexport function setDebugMode(enabled) {\n debugMode = enabled;\n}\n\n/**\n * Get current debug mode status\n * @returns {boolean} Whether debug mode is enabled\n */\nexport function getDebugMode() {\n return debugMode;\n}\n\nexport function debugLog(funcName, message, data) {\n if (!debugMode) return;\n \n console.group(`\uD83D\uDD0D ${funcName}`);\n console.log(message);\n if (data) {\n console.log('Data:', data);\n }\n console.groupEnd();\n}\n\nexport function debugSelection(textarea, label) {\n if (!debugMode) return;\n \n const selected = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);\n console.group(`\uD83D\uDCCD Selection: ${label}`);\n console.log('Position:', `${textarea.selectionStart}-${textarea.selectionEnd}`);\n console.log('Selected text:', JSON.stringify(selected));\n console.log('Length:', selected.length);\n \n // Show context around selection\n const before = textarea.value.slice(Math.max(0, textarea.selectionStart - 10), textarea.selectionStart);\n const after = textarea.value.slice(textarea.selectionEnd, Math.min(textarea.value.length, textarea.selectionEnd + 10));\n console.log('Context:', JSON.stringify(before) + '[SELECTION]' + JSON.stringify(after));\n console.groupEnd();\n}\n\nexport function debugResult(result) {\n if (!debugMode) return;\n \n console.group('\uD83D\uDCDD Result');\n console.log('Text to insert:', JSON.stringify(result.text));\n console.log('New selection:', `${result.selectionStart}-${result.selectionEnd}`);\n console.groupEnd();\n}", "/**\n * Text insertion system with undo/redo support\n * Extracted and adapted from GitHub's markdown-toolbar-element\n */\n\nimport { getDebugMode } from '../debug.js'\n\nlet canInsertText = null\n\n/**\n * Insert text at current position with undo/redo support\n * @param {HTMLTextAreaElement} textarea - Target textarea\n * @param {Object} options - Text and selection options\n * @param {string} options.text - Text to insert\n * @param {number} [options.selectionStart] - New selection start\n * @param {number} [options.selectionEnd] - New selection end\n */\nexport function insertText(textarea, { text, selectionStart, selectionEnd }) {\n const debugMode = getDebugMode();\n \n if (debugMode) {\n console.group('\uD83D\uDD27 insertText');\n console.log('Current selection:', `${textarea.selectionStart}-${textarea.selectionEnd}`);\n console.log('Text to insert:', JSON.stringify(text));\n console.log('New selection to set:', selectionStart, '-', selectionEnd);\n }\n \n // Make sure the textarea is focused\n textarea.focus();\n \n const originalSelectionStart = textarea.selectionStart\n const originalSelectionEnd = textarea.selectionEnd\n const before = textarea.value.slice(0, originalSelectionStart)\n const after = textarea.value.slice(originalSelectionEnd)\n \n if (debugMode) {\n console.log('Before text (last 20):', JSON.stringify(before.slice(-20)));\n console.log('After text (first 20):', JSON.stringify(after.slice(0, 20)));\n console.log('Selected text being replaced:', JSON.stringify(textarea.value.slice(originalSelectionStart, originalSelectionEnd)));\n }\n \n // Store the original value to check if execCommand actually changed it\n const originalValue = textarea.value\n\n // Only try execCommand if there's no selection (just inserting at cursor)\n // For replacements, we should use manual mode\n const hasSelection = originalSelectionStart !== originalSelectionEnd\n \n if (!hasSelection && (canInsertText === null || canInsertText === true)) {\n textarea.contentEditable = 'true'\n try {\n canInsertText = document.execCommand('insertText', false, text)\n } catch (error) {\n canInsertText = false\n }\n textarea.contentEditable = 'false'\n } else if (hasSelection) {\n if (debugMode) console.log('Has selection, skipping execCommand and using manual mode');\n canInsertText = false\n }\n\n if (debugMode) {\n console.log('canInsertText before:', canInsertText);\n console.log('execCommand result:', canInsertText);\n }\n \n // Check if execCommand actually worked by comparing the value\n if (canInsertText) {\n const expectedValue = before + text + after\n const actualValue = textarea.value\n \n if (debugMode) {\n console.log('Expected length:', expectedValue.length);\n console.log('Actual length:', actualValue.length);\n }\n \n if (actualValue !== expectedValue) {\n if (debugMode) {\n console.log('execCommand changed the value but not as expected');\n console.log('Expected:', JSON.stringify(expectedValue.slice(0, 100)));\n console.log('Actual:', JSON.stringify(actualValue.slice(0, 100)));\n }\n // Don't set canInsertText to false here - execCommand did work\n // We just need to not double-insert\n }\n }\n\n if (!canInsertText) {\n if (debugMode) console.log('Using manual insertion');\n // Only do manual insertion if execCommand didn't change the value\n if (textarea.value === originalValue) {\n if (debugMode) console.log('Value unchanged, doing manual replacement');\n try {\n document.execCommand('ms-beginUndoUnit')\n } catch (e) {\n // Do nothing.\n }\n textarea.value = before + text + after\n try {\n document.execCommand('ms-endUndoUnit')\n } catch (e) {\n // Do nothing.\n }\n textarea.dispatchEvent(new CustomEvent('input', { bubbles: true, cancelable: true }))\n } else {\n if (debugMode) console.log('Value was changed by execCommand, skipping manual insertion');\n }\n }\n\n if (debugMode) console.log('Setting selection range:', selectionStart, selectionEnd);\n if (selectionStart != null && selectionEnd != null) {\n textarea.setSelectionRange(selectionStart, selectionEnd)\n } else {\n textarea.setSelectionRange(originalSelectionStart, textarea.selectionEnd)\n }\n \n if (debugMode) {\n console.log('Final value length:', textarea.value.length);\n console.groupEnd();\n }\n}\n\n/**\n * Configure undo method\n * @param {'native' | 'manual' | 'auto'} method - Undo method to use\n */\nexport function setUndoMethod(method) {\n switch (method) {\n case 'native':\n canInsertText = true\n break\n case 'manual':\n canInsertText = false\n break\n case 'auto':\n canInsertText = null\n break\n }\n}", "/**\n * Core selection utilities extracted and adapted from GitHub's markdown-toolbar-element\n */\n\n/**\n * Check if string contains multiple lines\n */\nexport function isMultipleLines(string) {\n return string.trim().split('\\n').length > 1\n}\n\n/**\n * Find the start of the word at position i\n */\nexport function wordSelectionStart(text, i) {\n let index = i\n while (text[index] && text[index - 1] != null && !text[index - 1].match(/\\s/)) {\n index--\n }\n return index\n}\n\n/**\n * Find the end of the word at position i\n */\nexport function wordSelectionEnd(text, i, multiline) {\n let index = i\n const breakpoint = multiline ? /\\n/ : /\\s/\n while (text[index] && !text[index].match(breakpoint)) {\n index++\n }\n return index\n}\n\n/**\n * Expand selection to line boundaries\n */\nexport function expandSelectionToLine(textarea) {\n const lines = textarea.value.split('\\n')\n let counter = 0\n for (let index = 0; index < lines.length; index++) {\n const lineLength = lines[index].length + 1\n if (textarea.selectionStart >= counter && textarea.selectionStart < counter + lineLength) {\n textarea.selectionStart = counter\n }\n if (textarea.selectionEnd >= counter && textarea.selectionEnd < counter + lineLength) {\n // For the last line, don't go past the actual text length\n if (index === lines.length - 1) {\n textarea.selectionEnd = Math.min(counter + lines[index].length, textarea.value.length)\n } else {\n textarea.selectionEnd = counter + lineLength - 1\n }\n }\n counter += lineLength\n }\n}\n\n/**\n * Expand selected text with smart boundary detection\n */\nexport function expandSelectedText(textarea, prefixToUse, suffixToUse, multiline = false) {\n if (textarea.selectionStart === textarea.selectionEnd) {\n textarea.selectionStart = wordSelectionStart(textarea.value, textarea.selectionStart)\n textarea.selectionEnd = wordSelectionEnd(textarea.value, textarea.selectionEnd, multiline)\n } else {\n const expandedSelectionStart = textarea.selectionStart - prefixToUse.length\n const expandedSelectionEnd = textarea.selectionEnd + suffixToUse.length\n const beginsWithPrefix = textarea.value.slice(expandedSelectionStart, textarea.selectionStart) === prefixToUse\n const endsWithSuffix = textarea.value.slice(textarea.selectionEnd, expandedSelectionEnd) === suffixToUse\n if (beginsWithPrefix && endsWithSuffix) {\n textarea.selectionStart = expandedSelectionStart\n textarea.selectionEnd = expandedSelectionEnd\n }\n }\n return textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n}\n\n/**\n * Calculate newlines needed to surround selected text\n */\nexport function newlinesToSurroundSelectedText(textarea) {\n const beforeSelection = textarea.value.slice(0, textarea.selectionStart)\n const afterSelection = textarea.value.slice(textarea.selectionEnd)\n\n const breaksBefore = beforeSelection.match(/\\n*$/)\n const breaksAfter = afterSelection.match(/^\\n*/)\n const newlinesBeforeSelection = breaksBefore ? breaksBefore[0].length : 0\n const newlinesAfterSelection = breaksAfter ? breaksAfter[0].length : 0\n\n let newlinesToAppend = ''\n let newlinesToPrepend = ''\n\n if (beforeSelection.match(/\\S/) && newlinesBeforeSelection < 2) {\n newlinesToAppend = '\\n'.repeat(2 - newlinesBeforeSelection)\n }\n\n if (afterSelection.match(/\\S/) && newlinesAfterSelection < 2) {\n newlinesToPrepend = '\\n'.repeat(2 - newlinesAfterSelection)\n }\n\n return { newlinesToAppend, newlinesToPrepend }\n}\n\n/**\n * Utility to preserve selection during operations\n */\nexport function preserveSelection(textarea, callback) {\n const start = textarea.selectionStart\n const end = textarea.selectionEnd\n const scrollTop = textarea.scrollTop\n \n callback()\n \n textarea.selectionStart = start\n textarea.selectionEnd = end\n textarea.scrollTop = scrollTop\n}\n\n/**\n * Apply a line-based operation with cursor preservation\n * This function handles expanding to line boundaries and preserving cursor position\n * @param {HTMLTextAreaElement} textarea - The textarea element\n * @param {Function} operation - The operation to perform (receives textarea and returns result)\n * @param {Object} options - Options for the operation\n * @param {string} options.prefix - The prefix being added/removed (for cursor adjustment)\n * @param {Function} options.adjustSelection - Custom selection adjustment function\n * @returns {Object} The result from the operation with adjusted cursor position\n */\nexport function applyLineOperation(textarea, operation, options = {}) {\n // Save original cursor position AND selection before any expansion\n const originalStart = textarea.selectionStart\n const originalEnd = textarea.selectionEnd\n const noInitialSelection = originalStart === originalEnd\n \n // Store the line start position to calculate offset later\n const value = textarea.value\n let lineStart = originalStart\n \n // Find start of the line containing the selection start\n while (lineStart > 0 && value[lineStart - 1] !== '\\n') {\n lineStart--\n }\n \n // Expand selection to line boundaries for the operation\n if (noInitialSelection) {\n // Expand to current line when no selection\n let lineEnd = originalStart\n \n // Find end of current line\n while (lineEnd < value.length && value[lineEnd] !== '\\n') {\n lineEnd++\n }\n \n textarea.selectionStart = lineStart\n textarea.selectionEnd = lineEnd\n } else {\n // For selections, expand to full lines\n expandSelectionToLine(textarea)\n }\n \n // Apply the operation\n const result = operation(textarea)\n \n // Restore original selection/cursor with prefix adjustment\n if (options.adjustSelection) {\n // Use custom selection adjustment logic\n const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n const isRemoving = selectedText.startsWith(options.prefix)\n const adjusted = options.adjustSelection(isRemoving, originalStart, originalEnd, lineStart)\n result.selectionStart = adjusted.start\n result.selectionEnd = adjusted.end\n } else if (options.prefix) {\n // Use default prefix-based adjustment\n const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n const isRemoving = selectedText.startsWith(options.prefix)\n \n if (noInitialSelection) {\n // No selection - just restore cursor position\n if (isRemoving) {\n // When removing prefix, adjust cursor position\n result.selectionStart = Math.max(originalStart - options.prefix.length, lineStart)\n result.selectionEnd = result.selectionStart\n } else {\n // When adding prefix, adjust cursor position\n result.selectionStart = originalStart + options.prefix.length\n result.selectionEnd = result.selectionStart\n }\n } else {\n // Had a selection - restore it with adjustment\n if (isRemoving) {\n // When removing prefix, shift selection back\n result.selectionStart = Math.max(originalStart - options.prefix.length, lineStart)\n result.selectionEnd = Math.max(originalEnd - options.prefix.length, lineStart)\n } else {\n // When adding prefix, shift selection forward\n result.selectionStart = originalStart + options.prefix.length\n result.selectionEnd = originalEnd + options.prefix.length\n }\n }\n }\n \n return result\n}", "/**\n * Block-level text formatting operations\n * Handles inline formats like bold, italic, code, and links\n */\n\nimport { expandSelectedText, newlinesToSurroundSelectedText, isMultipleLines } from '../core/selection.js'\nimport { insertText } from '../core/insertion.js'\n\n/**\n * Apply block-level styling to selected text\n */\nexport function blockStyle(textarea, style) {\n let newlinesToAppend\n let newlinesToPrepend\n\n const { prefix, suffix, blockPrefix, blockSuffix, replaceNext, prefixSpace, scanFor, surroundWithNewlines, trimFirst } = style\n const originalSelectionStart = textarea.selectionStart\n const originalSelectionEnd = textarea.selectionEnd\n\n let selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n let prefixToUse = isMultipleLines(selectedText) && blockPrefix && blockPrefix.length > 0 ? `${blockPrefix}\\n` : prefix\n let suffixToUse = isMultipleLines(selectedText) && blockSuffix && blockSuffix.length > 0 ? `\\n${blockSuffix}` : suffix\n\n if (prefixSpace) {\n const beforeSelection = textarea.value[textarea.selectionStart - 1]\n if (textarea.selectionStart !== 0 && beforeSelection != null && !beforeSelection.match(/\\s/)) {\n prefixToUse = ` ${prefixToUse}`\n }\n }\n \n selectedText = expandSelectedText(textarea, prefixToUse, suffixToUse, style.multiline)\n let selectionStart = textarea.selectionStart\n let selectionEnd = textarea.selectionEnd\n const hasReplaceNext = replaceNext && replaceNext.length > 0 && suffixToUse.indexOf(replaceNext) > -1 && selectedText.length > 0\n \n if (surroundWithNewlines) {\n const ref = newlinesToSurroundSelectedText(textarea)\n newlinesToAppend = ref.newlinesToAppend\n newlinesToPrepend = ref.newlinesToPrepend\n prefixToUse = newlinesToAppend + prefix\n suffixToUse += newlinesToPrepend\n }\n\n // Check if we should remove formatting (toggle off)\n if (selectedText.startsWith(prefixToUse) && selectedText.endsWith(suffixToUse)) {\n const replacementText = selectedText.slice(prefixToUse.length, selectedText.length - suffixToUse.length)\n if (originalSelectionStart === originalSelectionEnd) {\n let position = originalSelectionStart - prefixToUse.length\n position = Math.max(position, selectionStart)\n position = Math.min(position, selectionStart + replacementText.length)\n selectionStart = selectionEnd = position\n } else {\n selectionEnd = selectionStart + replacementText.length\n }\n return { text: replacementText, selectionStart, selectionEnd }\n } else if (!hasReplaceNext) {\n // Add formatting\n let replacementText = prefixToUse + selectedText + suffixToUse\n selectionStart = originalSelectionStart + prefixToUse.length\n selectionEnd = originalSelectionEnd + prefixToUse.length\n const whitespaceEdges = selectedText.match(/^\\s*|\\s*$/g)\n if (trimFirst && whitespaceEdges) {\n const leadingWhitespace = whitespaceEdges[0] || ''\n const trailingWhitespace = whitespaceEdges[1] || ''\n replacementText = leadingWhitespace + prefixToUse + selectedText.trim() + suffixToUse + trailingWhitespace\n selectionStart += leadingWhitespace.length\n selectionEnd -= trailingWhitespace.length\n }\n return { text: replacementText, selectionStart, selectionEnd }\n } else if (scanFor && scanFor.length > 0 && selectedText.match(scanFor)) {\n // Handle link/image with URL detection\n suffixToUse = suffixToUse.replace(replaceNext, selectedText)\n const replacementText = prefixToUse + suffixToUse\n selectionStart = selectionEnd = selectionStart + prefixToUse.length\n return { text: replacementText, selectionStart, selectionEnd }\n } else {\n // Handle link/image with placeholder\n const replacementText = prefixToUse + selectedText + suffixToUse\n selectionStart = selectionStart + prefixToUse.length + selectedText.length + suffixToUse.indexOf(replaceNext)\n selectionEnd = selectionStart + replaceNext.length\n return { text: replacementText, selectionStart, selectionEnd }\n }\n}\n\n/**\n * Apply style to selected text in textarea\n */\nexport function styleSelectedText(textarea, style) {\n const text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n \n let result\n if (style.orderedList || style.unorderedList) {\n // Will be handled by list operations\n return\n } else if (style.multiline && isMultipleLines(text)) {\n result = multilineStyle(textarea, style)\n } else {\n result = blockStyle(textarea, style)\n }\n\n insertText(textarea, result)\n}\n\n/**\n * Apply multiline styling (quotes, task lists, etc)\n * Note: This does NOT expand selection to line - that should be done by the caller if needed\n */\nexport function multilineStyle(textarea, style) {\n const { prefix, suffix, surroundWithNewlines } = style\n let text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n let selectionStart = textarea.selectionStart\n let selectionEnd = textarea.selectionEnd\n const lines = text.split('\\n')\n \n // Check if we need to undo (all lines have the format)\n const undoStyle = lines.every(line => line.startsWith(prefix) && (!suffix || line.endsWith(suffix)))\n\n if (undoStyle) {\n // Remove the formatting\n text = lines.map(line => {\n let result = line.slice(prefix.length)\n if (suffix) {\n result = result.slice(0, result.length - suffix.length)\n }\n return result\n }).join('\\n')\n selectionEnd = selectionStart + text.length\n } else {\n // Apply the formatting\n text = lines.map(line => prefix + line + (suffix || '')).join('\\n')\n if (surroundWithNewlines) {\n const { newlinesToAppend, newlinesToPrepend } = newlinesToSurroundSelectedText(textarea)\n selectionStart += newlinesToAppend.length\n selectionEnd = selectionStart + text.length\n text = newlinesToAppend + text + newlinesToPrepend\n }\n }\n\n return { text, selectionStart, selectionEnd }\n}", "/**\n * List operations for bullet and numbered lists\n */\n\nimport { expandSelectionToLine, newlinesToSurroundSelectedText, applyLineOperation } from '../core/selection.js'\nimport { insertText } from '../core/insertion.js'\n\n/**\n * Undo ordered list formatting\n */\nfunction undoOrderedListStyle(text) {\n const lines = text.split('\\n')\n const orderedListRegex = /^\\d+\\.\\s+/\n const shouldUndoOrderedList = lines.every(line => orderedListRegex.test(line))\n let result = lines\n if (shouldUndoOrderedList) {\n result = lines.map(line => line.replace(orderedListRegex, ''))\n }\n\n return {\n text: result.join('\\n'),\n processed: shouldUndoOrderedList\n }\n}\n\n/**\n * Undo unordered list formatting\n */\nfunction undoUnorderedListStyle(text) {\n const lines = text.split('\\n')\n const unorderedListPrefix = '- '\n const shouldUndoUnorderedList = lines.every(line => line.startsWith(unorderedListPrefix))\n let result = lines\n if (shouldUndoUnorderedList) {\n result = lines.map(line => line.slice(unorderedListPrefix.length))\n }\n\n return {\n text: result.join('\\n'),\n processed: shouldUndoUnorderedList\n }\n}\n\n/**\n * Make prefix for list item\n */\nfunction makePrefix(index, unorderedList) {\n if (unorderedList) {\n return '- '\n } else {\n return `${index + 1}. `\n }\n}\n\n/**\n * Clear existing list style\n */\nfunction clearExistingListStyle(style, selectedText) {\n let undoResult\n let undoResultOppositeList\n let pristineText\n \n if (style.orderedList) {\n undoResult = undoOrderedListStyle(selectedText)\n undoResultOppositeList = undoUnorderedListStyle(undoResult.text)\n pristineText = undoResultOppositeList.text\n } else {\n undoResult = undoUnorderedListStyle(selectedText)\n undoResultOppositeList = undoOrderedListStyle(undoResult.text)\n pristineText = undoResultOppositeList.text\n }\n \n return [undoResult, undoResultOppositeList, pristineText]\n}\n\n/**\n * Apply list styling to selected text\n */\nexport function listStyle(textarea, style) {\n const noInitialSelection = textarea.selectionStart === textarea.selectionEnd\n let selectionStart = textarea.selectionStart\n let selectionEnd = textarea.selectionEnd\n\n // Select whole line\n expandSelectionToLine(textarea)\n\n const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n\n // Clear any existing list formatting\n const [undoResult, undoResultOppositeList, pristineText] = clearExistingListStyle(style, selectedText)\n\n const prefixedLines = pristineText.split('\\n').map((value, index) => {\n return `${makePrefix(index, style.unorderedList)}${value}`\n })\n\n const totalPrefixLength = prefixedLines.reduce((previousValue, _currentValue, currentIndex) => {\n return previousValue + makePrefix(currentIndex, style.unorderedList).length\n }, 0)\n\n const totalPrefixLengthOppositeList = prefixedLines.reduce((previousValue, _currentValue, currentIndex) => {\n return previousValue + makePrefix(currentIndex, !style.unorderedList).length\n }, 0)\n\n // If we're undoing the same list type, just return the pristine text\n if (undoResult.processed) {\n if (noInitialSelection) {\n selectionStart = Math.max(selectionStart - makePrefix(0, style.unorderedList).length, 0)\n selectionEnd = selectionStart\n } else {\n selectionStart = textarea.selectionStart\n selectionEnd = textarea.selectionEnd - totalPrefixLength\n }\n return { text: pristineText, selectionStart, selectionEnd }\n }\n\n // Apply new list formatting\n const { newlinesToAppend, newlinesToPrepend } = newlinesToSurroundSelectedText(textarea)\n const text = newlinesToAppend + prefixedLines.join('\\n') + newlinesToPrepend\n\n if (noInitialSelection) {\n selectionStart = Math.max(selectionStart + makePrefix(0, style.unorderedList).length + newlinesToAppend.length, 0)\n selectionEnd = selectionStart\n } else {\n if (undoResultOppositeList.processed) {\n // Converting from one list type to another\n selectionStart = Math.max(textarea.selectionStart + newlinesToAppend.length, 0)\n selectionEnd = textarea.selectionEnd + newlinesToAppend.length + totalPrefixLength - totalPrefixLengthOppositeList\n } else {\n // Adding list formatting to plain text\n selectionStart = Math.max(textarea.selectionStart + newlinesToAppend.length, 0)\n selectionEnd = textarea.selectionEnd + newlinesToAppend.length + totalPrefixLength\n }\n }\n\n return { text, selectionStart, selectionEnd }\n}\n\n/**\n * Apply list style to textarea\n */\nexport function applyListStyle(textarea, style) {\n // Use applyLineOperation for consistent selection preservation\n const result = applyLineOperation(\n textarea,\n (ta) => listStyle(ta, style),\n {\n // Custom selection adjustment for lists\n adjustSelection: (isRemoving, selStart, selEnd, lineStart) => {\n // Get the current line to check if we're removing\n const currentLine = textarea.value.slice(lineStart, textarea.selectionEnd)\n const orderedListRegex = /^\\d+\\.\\s+/\n const unorderedListRegex = /^- /\n \n // Check if we're removing a list\n const hasOrderedList = orderedListRegex.test(currentLine)\n const hasUnorderedList = unorderedListRegex.test(currentLine)\n const isRemovingCurrent = (style.orderedList && hasOrderedList) || (style.unorderedList && hasUnorderedList)\n \n if (selStart === selEnd) {\n // No selection - cursor position\n if (isRemovingCurrent) {\n // Removing list - adjust cursor back\n const prefixMatch = currentLine.match(style.orderedList ? orderedListRegex : unorderedListRegex)\n const prefixLength = prefixMatch ? prefixMatch[0].length : 0\n return {\n start: Math.max(selStart - prefixLength, lineStart),\n end: Math.max(selStart - prefixLength, lineStart)\n }\n } else if (hasOrderedList || hasUnorderedList) {\n // Converting from one list type to another\n const oldPrefixMatch = currentLine.match(hasOrderedList ? orderedListRegex : unorderedListRegex)\n const oldPrefixLength = oldPrefixMatch ? oldPrefixMatch[0].length : 0\n const newPrefixLength = style.unorderedList ? 2 : 3 // \"- \" or \"1. \"\n const adjustment = newPrefixLength - oldPrefixLength\n return {\n start: selStart + adjustment,\n end: selStart + adjustment\n }\n } else {\n // Adding new list\n const prefixLength = style.unorderedList ? 2 : 3 // \"- \" or \"1. \"\n return {\n start: selStart + prefixLength,\n end: selStart + prefixLength\n }\n }\n } else {\n // Has selection - preserve it\n if (isRemovingCurrent) {\n // Removing current list type\n const prefixMatch = currentLine.match(style.orderedList ? orderedListRegex : unorderedListRegex)\n const prefixLength = prefixMatch ? prefixMatch[0].length : 0\n return {\n start: Math.max(selStart - prefixLength, lineStart),\n end: Math.max(selEnd - prefixLength, lineStart)\n }\n } else if (hasOrderedList || hasUnorderedList) {\n // Converting from one list type to another\n const oldPrefixMatch = currentLine.match(hasOrderedList ? orderedListRegex : unorderedListRegex)\n const oldPrefixLength = oldPrefixMatch ? oldPrefixMatch[0].length : 0\n const newPrefixLength = style.unorderedList ? 2 : 3 // \"- \" or \"1. \"\n const adjustment = newPrefixLength - oldPrefixLength\n return {\n start: selStart + adjustment,\n end: selEnd + adjustment\n }\n } else {\n // Adding new list\n const prefixLength = style.unorderedList ? 2 : 3 // \"- \" or \"1. \"\n return {\n start: selStart + prefixLength,\n end: selEnd + prefixLength\n }\n }\n }\n }\n }\n )\n \n insertText(textarea, result)\n}", "/**\n * Format detection utilities\n */\n\nimport { FORMATS } from './formats.js'\n\n/**\n * Check if text has a specific format applied\n */\nfunction hasFormatApplied(text, format) {\n if (!format.prefix) return false\n \n if (format.suffix) {\n return text.startsWith(format.prefix) && text.endsWith(format.suffix)\n } else {\n return text.startsWith(format.prefix)\n }\n}\n\n/**\n * Get active formats at cursor position\n */\nexport function getActiveFormats(textarea) {\n if (!textarea) return []\n \n const formats = []\n const { selectionStart, selectionEnd, value } = textarea\n \n // Get current line for line-based formats\n const lines = value.split('\\n')\n let lineStart = 0\n let currentLine = ''\n \n for (const line of lines) {\n if (selectionStart >= lineStart && selectionStart <= lineStart + line.length) {\n currentLine = line\n break\n }\n lineStart += line.length + 1\n }\n \n // Check line-based formats\n if (currentLine.startsWith('- ')) {\n if (currentLine.startsWith('- [ ] ') || currentLine.startsWith('- [x] ')) {\n formats.push('task-list')\n } else {\n formats.push('bullet-list')\n }\n }\n \n if (/^\\d+\\.\\s/.test(currentLine)) {\n formats.push('numbered-list')\n }\n \n if (currentLine.startsWith('> ')) {\n formats.push('quote')\n }\n \n if (currentLine.startsWith('# ')) formats.push('header')\n if (currentLine.startsWith('## ')) formats.push('header-2')\n if (currentLine.startsWith('### ')) formats.push('header-3')\n \n // Check inline formats by looking around cursor\n const lookBehind = Math.max(0, selectionStart - 10)\n const lookAhead = Math.min(value.length, selectionEnd + 10)\n const surrounding = value.slice(lookBehind, lookAhead)\n \n // Check for bold\n if (surrounding.includes('**')) {\n const beforeCursor = value.slice(Math.max(0, selectionStart - 100), selectionStart)\n const afterCursor = value.slice(selectionEnd, Math.min(value.length, selectionEnd + 100))\n const lastOpenBold = beforeCursor.lastIndexOf('**')\n const nextCloseBold = afterCursor.indexOf('**')\n if (lastOpenBold !== -1 && nextCloseBold !== -1) {\n formats.push('bold')\n }\n }\n \n // Check for italic\n if (surrounding.includes('_')) {\n const beforeCursor = value.slice(Math.max(0, selectionStart - 100), selectionStart)\n const afterCursor = value.slice(selectionEnd, Math.min(value.length, selectionEnd + 100))\n const lastOpenItalic = beforeCursor.lastIndexOf('_')\n const nextCloseItalic = afterCursor.indexOf('_')\n if (lastOpenItalic !== -1 && nextCloseItalic !== -1) {\n formats.push('italic')\n }\n }\n \n // Check for code\n if (surrounding.includes('`')) {\n const beforeCursor = value.slice(Math.max(0, selectionStart - 100), selectionStart)\n const afterCursor = value.slice(selectionEnd, Math.min(value.length, selectionEnd + 100))\n if (beforeCursor.includes('`') && afterCursor.includes('`')) {\n formats.push('code')\n }\n }\n \n // Check for link\n if (surrounding.includes('[') && surrounding.includes(']')) {\n const beforeCursor = value.slice(Math.max(0, selectionStart - 100), selectionStart)\n const afterCursor = value.slice(selectionEnd, Math.min(value.length, selectionEnd + 100))\n const lastOpenBracket = beforeCursor.lastIndexOf('[')\n const nextCloseBracket = afterCursor.indexOf(']')\n if (lastOpenBracket !== -1 && nextCloseBracket !== -1) {\n const afterBracket = value.slice(selectionEnd + nextCloseBracket + 1, selectionEnd + nextCloseBracket + 10)\n if (afterBracket.startsWith('(')) {\n formats.push('link')\n }\n }\n }\n \n return formats\n}\n\n/**\n * Check if specific format is active at cursor\n */\nexport function hasFormat(textarea, format) {\n const activeFormats = getActiveFormats(textarea)\n return activeFormats.includes(format)\n}\n\n/**\n * Expand selection based on options\n */\nexport function expandSelection(textarea, options = {}) {\n if (!textarea) return\n \n const { toWord, toLine, toFormat } = options\n const { selectionStart, selectionEnd, value } = textarea\n \n if (toLine) {\n // Find line boundaries\n const lines = value.split('\\n')\n let lineStart = 0\n let lineEnd = 0\n let currentPos = 0\n \n for (const line of lines) {\n if (selectionStart >= currentPos && selectionStart <= currentPos + line.length) {\n lineStart = currentPos\n lineEnd = currentPos + line.length\n break\n }\n currentPos += line.length + 1\n }\n \n textarea.selectionStart = lineStart\n textarea.selectionEnd = lineEnd\n } else if (toWord && selectionStart === selectionEnd) {\n // Find word boundaries\n let start = selectionStart\n let end = selectionEnd\n \n // Move start back to word boundary\n while (start > 0 && !/\\s/.test(value[start - 1])) {\n start--\n }\n \n // Move end forward to word boundary\n while (end < value.length && !/\\s/.test(value[end])) {\n end++\n }\n \n textarea.selectionStart = start\n textarea.selectionEnd = end\n }\n}"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["expandSelection", "getActiveFormats", "hasFormat", "debugMode", "
|
|
4
|
+
"sourcesContent": ["/**\n * markdown-actions - Lightweight markdown toolbar functionality\n * Based on GitHub's markdown-toolbar-element\n */\n\nimport { FORMATS, mergeWithDefaults } from './core/formats.js'\nimport { insertText, setUndoMethod } from './core/insertion.js'\nimport { preserveSelection, isMultipleLines, expandSelectionToLine, applyLineOperation } from './core/selection.js'\nimport { blockStyle, multilineStyle } from './operations/block.js'\nimport { applyListStyle } from './operations/list.js'\nimport { getActiveFormats as getActive, hasFormat as has, expandSelection as expand } from './core/detection.js'\nimport { debugLog, debugSelection, debugResult, setDebugMode, getDebugMode } from './debug.js'\n\n/**\n * Toggle bold formatting\n */\nexport function toggleBold(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n \n debugLog('toggleBold', 'Starting');\n debugSelection(textarea, 'Before');\n \n const style = mergeWithDefaults(FORMATS.bold)\n const result = blockStyle(textarea, style)\n \n debugResult(result);\n \n insertText(textarea, result)\n \n debugSelection(textarea, 'After');\n}\n\n/**\n * Toggle italic formatting\n */\nexport function toggleItalic(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n const style = mergeWithDefaults(FORMATS.italic)\n const result = blockStyle(textarea, style)\n insertText(textarea, result)\n}\n\n/**\n * Toggle code formatting\n */\nexport function toggleCode(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n \n // blockStyle already handles both inline and block code correctly\n const style = mergeWithDefaults(FORMATS.code)\n const result = blockStyle(textarea, style)\n insertText(textarea, result)\n}\n\n/**\n * Insert or toggle link formatting\n */\nexport function insertLink(textarea, options = {}) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n \n const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n let style = mergeWithDefaults(FORMATS.link)\n \n // Check if selected text is a URL\n const isURL = selectedText && selectedText.match(/^https?:\\/\\//)\n \n if (isURL && !options.url) {\n // If selected text is a URL, use it as both link text and URL\n style.suffix = `](${selectedText})`\n style.replaceNext = ''\n // Don't change the selected text, it becomes the link text\n } else if (options.url) {\n // Override with custom URL if provided\n style.suffix = `](${options.url})`\n style.replaceNext = ''\n }\n \n // Override with custom text if provided\n if (options.text && !selectedText) {\n // Insert the text and select it\n const pos = textarea.selectionStart\n textarea.value = textarea.value.slice(0, pos) + options.text + textarea.value.slice(pos)\n textarea.selectionStart = pos\n textarea.selectionEnd = pos + options.text.length\n }\n \n const result = blockStyle(textarea, style)\n insertText(textarea, result)\n}\n\n/**\n * Toggle bullet list formatting\n */\nexport function toggleBulletList(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n const style = mergeWithDefaults(FORMATS.bulletList)\n applyListStyle(textarea, style)\n}\n\n/**\n * Toggle numbered list formatting\n */\nexport function toggleNumberedList(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n const style = mergeWithDefaults(FORMATS.numberedList)\n applyListStyle(textarea, style)\n}\n\n/**\n * Toggle quote formatting\n * Matches GitHub's implementation for quotes\n */\nexport function toggleQuote(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n \n debugLog('toggleQuote', 'Starting');\n debugSelection(textarea, 'Initial');\n \n const style = mergeWithDefaults(FORMATS.quote)\n \n // Use the reusable line operation helper\n const result = applyLineOperation(\n textarea,\n (ta) => multilineStyle(ta, style),\n { prefix: style.prefix }\n )\n \n debugResult(result);\n insertText(textarea, result)\n debugSelection(textarea, 'Final');\n}\n\n/**\n * Toggle task list formatting\n * Matches GitHub's implementation for task lists\n */\nexport function toggleTaskList(textarea) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n \n const style = mergeWithDefaults(FORMATS.taskList)\n \n // Use the reusable line operation helper\n const result = applyLineOperation(\n textarea,\n (ta) => multilineStyle(ta, style),\n { prefix: style.prefix }\n )\n \n insertText(textarea, result)\n}\n\n/**\n * Insert or toggle header with specific level\n */\nexport function insertHeader(textarea, level = 1, toggle = false) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n if (level < 1 || level > 6) level = 1\n \n debugLog('insertHeader', `Level: ${level}, Toggle: ${toggle}`);\n \n const headerKey = `header${level === 1 ? '1' : level}`\n const style = mergeWithDefaults(FORMATS[headerKey] || FORMATS.header1)\n \n // Save original cursor position\n const originalStart = textarea.selectionStart\n const originalEnd = textarea.selectionEnd\n const value = textarea.value\n \n // Find line boundaries\n let lineStart = originalStart\n while (lineStart > 0 && value[lineStart - 1] !== '\\n') {\n lineStart--\n }\n \n let lineEnd = originalEnd\n while (lineEnd < value.length && value[lineEnd] !== '\\n') {\n lineEnd++\n }\n \n // Get the current line\n const currentLine = value.slice(lineStart, lineEnd)\n debugLog('insertHeader', `Current line: \"${currentLine}\"`);\n \n // Check for existing header\n const existingHeaderMatch = currentLine.match(/^(#{1,6})\\s*/)\n const existingLevel = existingHeaderMatch ? existingHeaderMatch[1].length : 0\n const existingPrefixLength = existingHeaderMatch ? existingHeaderMatch[0].length : 0\n \n debugLog('insertHeader', `Existing level: ${existingLevel}, Target level: ${level}`);\n \n // Determine the new line content\n let newLine\n let prefixChange = 0\n \n if (toggle && existingLevel === level) {\n // Toggle off - remove the header\n debugLog('insertHeader', 'Toggling OFF header');\n newLine = currentLine.replace(/^#{1,6}\\s*/, '')\n prefixChange = -existingPrefixLength\n } else if (existingLevel > 0) {\n // Replace existing header with new one\n debugLog('insertHeader', 'Replacing header');\n const cleanedLine = currentLine.replace(/^#{1,6}\\s*/, '')\n newLine = style.prefix + cleanedLine\n prefixChange = style.prefix.length - existingPrefixLength\n } else {\n // Add new header\n debugLog('insertHeader', 'Adding new header');\n newLine = style.prefix + currentLine\n prefixChange = style.prefix.length\n }\n \n // Build the result\n const result = {\n text: newLine,\n selectionStart: lineStart,\n selectionEnd: lineEnd\n }\n \n // Adjust cursor position based on prefix change\n if (originalStart === originalEnd) {\n // No selection - adjust cursor position\n result.selectionStart = Math.max(originalStart + prefixChange, lineStart)\n result.selectionEnd = result.selectionStart\n } else {\n // Has selection - preserve it with adjustment\n result.selectionStart = Math.max(originalStart + prefixChange, lineStart)\n result.selectionEnd = Math.max(originalEnd + prefixChange, lineStart)\n }\n \n debugLog('insertHeader', `Result: \"${result.text}\" (${result.selectionStart}, ${result.selectionEnd})`);\n \n // Expand selection to full line for replacement\n textarea.selectionStart = lineStart\n textarea.selectionEnd = lineEnd\n \n insertText(textarea, result)\n}\n\n/**\n * Toggle H1 header\n */\nexport function toggleH1(textarea) {\n insertHeader(textarea, 1, true)\n}\n\n/**\n * Toggle H2 header\n */\nexport function toggleH2(textarea) {\n insertHeader(textarea, 2, true)\n}\n\n/**\n * Toggle H3 header\n */\nexport function toggleH3(textarea) {\n insertHeader(textarea, 3, true)\n}\n\n/**\n * Get active formats at cursor position\n */\nexport function getActiveFormats(textarea) {\n return getActive(textarea)\n}\n\n/**\n * Check if format is active at cursor\n */\nexport function hasFormat(textarea, format) {\n return has(textarea, format)\n}\n\n/**\n * Expand selection based on options\n */\nexport function expandSelection(textarea, options = {}) {\n expand(textarea, options)\n}\n\n/**\n * Apply custom format\n */\nexport function applyCustomFormat(textarea, format) {\n if (!textarea || textarea.disabled || textarea.readOnly) return\n \n const style = mergeWithDefaults(format)\n let result\n \n if (style.multiline) {\n const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n if (isMultipleLines(selectedText)) {\n result = multilineStyle(textarea, style)\n } else {\n result = blockStyle(textarea, style)\n }\n } else {\n result = blockStyle(textarea, style)\n }\n \n insertText(textarea, result)\n}\n\n/**\n * Preserve selection during callback\n */\nexport { preserveSelection }\n\n/**\n * Configure undo method\n */\nexport { setUndoMethod }\n\n/**\n * Debug mode control\n */\nexport { setDebugMode, getDebugMode }\n\n/**\n * Default export with all functions\n */\nexport default {\n toggleBold,\n toggleItalic,\n toggleCode,\n insertLink,\n toggleBulletList,\n toggleNumberedList,\n toggleQuote,\n toggleTaskList,\n insertHeader,\n toggleH1,\n toggleH2,\n toggleH3,\n getActiveFormats,\n hasFormat,\n expandSelection,\n applyCustomFormat,\n preserveSelection,\n setUndoMethod,\n setDebugMode,\n getDebugMode\n}", "/**\n * Format definitions for markdown syntax\n */\n\nexport const FORMATS = {\n bold: {\n prefix: '**',\n suffix: '**',\n trimFirst: true\n },\n italic: {\n prefix: '_',\n suffix: '_',\n trimFirst: true\n },\n code: {\n prefix: '`',\n suffix: '`',\n blockPrefix: '```',\n blockSuffix: '```'\n },\n link: {\n prefix: '[',\n suffix: '](url)',\n replaceNext: 'url',\n scanFor: 'https?://'\n },\n bulletList: {\n prefix: '- ',\n multiline: true,\n unorderedList: true\n },\n numberedList: {\n prefix: '1. ',\n multiline: true,\n orderedList: true\n },\n quote: {\n prefix: '> ',\n multiline: true,\n surroundWithNewlines: true\n },\n taskList: {\n prefix: '- [ ] ',\n multiline: true,\n surroundWithNewlines: true\n },\n header1: { prefix: '# ' },\n header2: { prefix: '## ' },\n header3: { prefix: '### ' },\n header4: { prefix: '#### ' },\n header5: { prefix: '##### ' },\n header6: { prefix: '###### ' }\n}\n\n/**\n * Default style configuration\n */\nexport function getDefaultStyle() {\n return {\n prefix: '',\n suffix: '',\n blockPrefix: '',\n blockSuffix: '',\n multiline: false,\n replaceNext: '',\n prefixSpace: false,\n scanFor: '',\n surroundWithNewlines: false,\n orderedList: false,\n unorderedList: false,\n trimFirst: false\n }\n}\n\n/**\n * Merge format with defaults\n */\nexport function mergeWithDefaults(format) {\n return { ...getDefaultStyle(), ...format }\n}", "/**\n * Debug utilities for markdown-actions\n * Add console logging to track what's happening\n */\n\n// Debug mode flag - disabled by default\nlet debugMode = false;\n\n/**\n * Enable or disable debug mode\n * @param {boolean} enabled - Whether to enable debug mode\n */\nexport function setDebugMode(enabled) {\n debugMode = enabled;\n}\n\n/**\n * Get current debug mode status\n * @returns {boolean} Whether debug mode is enabled\n */\nexport function getDebugMode() {\n return debugMode;\n}\n\nexport function debugLog(funcName, message, data) {\n if (!debugMode) return;\n \n console.group(`\uD83D\uDD0D ${funcName}`);\n console.log(message);\n if (data) {\n console.log('Data:', data);\n }\n console.groupEnd();\n}\n\nexport function debugSelection(textarea, label) {\n if (!debugMode) return;\n \n const selected = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);\n console.group(`\uD83D\uDCCD Selection: ${label}`);\n console.log('Position:', `${textarea.selectionStart}-${textarea.selectionEnd}`);\n console.log('Selected text:', JSON.stringify(selected));\n console.log('Length:', selected.length);\n \n // Show context around selection\n const before = textarea.value.slice(Math.max(0, textarea.selectionStart - 10), textarea.selectionStart);\n const after = textarea.value.slice(textarea.selectionEnd, Math.min(textarea.value.length, textarea.selectionEnd + 10));\n console.log('Context:', JSON.stringify(before) + '[SELECTION]' + JSON.stringify(after));\n console.groupEnd();\n}\n\nexport function debugResult(result) {\n if (!debugMode) return;\n \n console.group('\uD83D\uDCDD Result');\n console.log('Text to insert:', JSON.stringify(result.text));\n console.log('New selection:', `${result.selectionStart}-${result.selectionEnd}`);\n console.groupEnd();\n}", "/**\n * Text insertion system with undo/redo support\n * Extracted and adapted from GitHub's markdown-toolbar-element\n */\n\nimport { getDebugMode } from '../debug.js'\n\nlet canInsertText = null\n\n/**\n * Insert text at current position with undo/redo support\n * @param {HTMLTextAreaElement} textarea - Target textarea\n * @param {Object} options - Text and selection options\n * @param {string} options.text - Text to insert\n * @param {number} [options.selectionStart] - New selection start\n * @param {number} [options.selectionEnd] - New selection end\n */\nexport function insertText(textarea, { text, selectionStart, selectionEnd }) {\n const debugMode = getDebugMode();\n \n if (debugMode) {\n console.group('\uD83D\uDD27 insertText');\n console.log('Current selection:', `${textarea.selectionStart}-${textarea.selectionEnd}`);\n console.log('Text to insert:', JSON.stringify(text));\n console.log('New selection to set:', selectionStart, '-', selectionEnd);\n }\n \n // Make sure the textarea is focused\n textarea.focus();\n \n const originalSelectionStart = textarea.selectionStart\n const originalSelectionEnd = textarea.selectionEnd\n const before = textarea.value.slice(0, originalSelectionStart)\n const after = textarea.value.slice(originalSelectionEnd)\n \n if (debugMode) {\n console.log('Before text (last 20):', JSON.stringify(before.slice(-20)));\n console.log('After text (first 20):', JSON.stringify(after.slice(0, 20)));\n console.log('Selected text being replaced:', JSON.stringify(textarea.value.slice(originalSelectionStart, originalSelectionEnd)));\n }\n \n // Store the original value to check if execCommand actually changed it\n const originalValue = textarea.value\n\n // Only try execCommand if there's no selection (just inserting at cursor)\n // For replacements, we should use manual mode\n const hasSelection = originalSelectionStart !== originalSelectionEnd\n \n if (!hasSelection && (canInsertText === null || canInsertText === true)) {\n textarea.contentEditable = 'true'\n try {\n canInsertText = document.execCommand('insertText', false, text)\n } catch (error) {\n canInsertText = false\n }\n textarea.contentEditable = 'false'\n } else if (hasSelection) {\n if (debugMode) console.log('Has selection, skipping execCommand and using manual mode');\n canInsertText = false\n }\n\n if (debugMode) {\n console.log('canInsertText before:', canInsertText);\n console.log('execCommand result:', canInsertText);\n }\n \n // Check if execCommand actually worked by comparing the value\n if (canInsertText) {\n const expectedValue = before + text + after\n const actualValue = textarea.value\n \n if (debugMode) {\n console.log('Expected length:', expectedValue.length);\n console.log('Actual length:', actualValue.length);\n }\n \n if (actualValue !== expectedValue) {\n if (debugMode) {\n console.log('execCommand changed the value but not as expected');\n console.log('Expected:', JSON.stringify(expectedValue.slice(0, 100)));\n console.log('Actual:', JSON.stringify(actualValue.slice(0, 100)));\n }\n // Don't set canInsertText to false here - execCommand did work\n // We just need to not double-insert\n }\n }\n\n if (!canInsertText) {\n if (debugMode) console.log('Using manual insertion');\n // Only do manual insertion if execCommand didn't change the value\n if (textarea.value === originalValue) {\n if (debugMode) console.log('Value unchanged, doing manual replacement');\n try {\n document.execCommand('ms-beginUndoUnit')\n } catch (e) {\n // Do nothing.\n }\n textarea.value = before + text + after\n try {\n document.execCommand('ms-endUndoUnit')\n } catch (e) {\n // Do nothing.\n }\n textarea.dispatchEvent(new CustomEvent('input', { bubbles: true, cancelable: true }))\n } else {\n if (debugMode) console.log('Value was changed by execCommand, skipping manual insertion');\n }\n }\n\n if (debugMode) console.log('Setting selection range:', selectionStart, selectionEnd);\n if (selectionStart != null && selectionEnd != null) {\n textarea.setSelectionRange(selectionStart, selectionEnd)\n } else {\n textarea.setSelectionRange(originalSelectionStart, textarea.selectionEnd)\n }\n \n if (debugMode) {\n console.log('Final value length:', textarea.value.length);\n console.groupEnd();\n }\n}\n\n/**\n * Configure undo method\n * @param {'native' | 'manual' | 'auto'} method - Undo method to use\n */\nexport function setUndoMethod(method) {\n switch (method) {\n case 'native':\n canInsertText = true\n break\n case 'manual':\n canInsertText = false\n break\n case 'auto':\n canInsertText = null\n break\n }\n}", "/**\n * Core selection utilities extracted and adapted from GitHub's markdown-toolbar-element\n */\n\n/**\n * Check if string contains multiple lines\n */\nexport function isMultipleLines(string) {\n return string.trim().split('\\n').length > 1\n}\n\n/**\n * Find the start of the word at position i\n */\nexport function wordSelectionStart(text, i) {\n let index = i\n while (text[index] && text[index - 1] != null && !text[index - 1].match(/\\s/)) {\n index--\n }\n return index\n}\n\n/**\n * Find the end of the word at position i\n */\nexport function wordSelectionEnd(text, i, multiline) {\n let index = i\n const breakpoint = multiline ? /\\n/ : /\\s/\n while (text[index] && !text[index].match(breakpoint)) {\n index++\n }\n return index\n}\n\n/**\n * Expand selection to line boundaries\n */\nexport function expandSelectionToLine(textarea) {\n const lines = textarea.value.split('\\n')\n let counter = 0\n for (let index = 0; index < lines.length; index++) {\n const lineLength = lines[index].length + 1\n if (textarea.selectionStart >= counter && textarea.selectionStart < counter + lineLength) {\n textarea.selectionStart = counter\n }\n if (textarea.selectionEnd >= counter && textarea.selectionEnd < counter + lineLength) {\n // For the last line, don't go past the actual text length\n if (index === lines.length - 1) {\n textarea.selectionEnd = Math.min(counter + lines[index].length, textarea.value.length)\n } else {\n textarea.selectionEnd = counter + lineLength - 1\n }\n }\n counter += lineLength\n }\n}\n\n/**\n * Expand selected text with smart boundary detection\n */\nexport function expandSelectedText(textarea, prefixToUse, suffixToUse, multiline = false) {\n if (textarea.selectionStart === textarea.selectionEnd) {\n textarea.selectionStart = wordSelectionStart(textarea.value, textarea.selectionStart)\n textarea.selectionEnd = wordSelectionEnd(textarea.value, textarea.selectionEnd, multiline)\n } else {\n const expandedSelectionStart = textarea.selectionStart - prefixToUse.length\n const expandedSelectionEnd = textarea.selectionEnd + suffixToUse.length\n const beginsWithPrefix = textarea.value.slice(expandedSelectionStart, textarea.selectionStart) === prefixToUse\n const endsWithSuffix = textarea.value.slice(textarea.selectionEnd, expandedSelectionEnd) === suffixToUse\n if (beginsWithPrefix && endsWithSuffix) {\n textarea.selectionStart = expandedSelectionStart\n textarea.selectionEnd = expandedSelectionEnd\n }\n }\n return textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n}\n\n/**\n * Calculate newlines needed to surround selected text\n */\nexport function newlinesToSurroundSelectedText(textarea) {\n const beforeSelection = textarea.value.slice(0, textarea.selectionStart)\n const afterSelection = textarea.value.slice(textarea.selectionEnd)\n\n const breaksBefore = beforeSelection.match(/\\n*$/)\n const breaksAfter = afterSelection.match(/^\\n*/)\n const newlinesBeforeSelection = breaksBefore ? breaksBefore[0].length : 0\n const newlinesAfterSelection = breaksAfter ? breaksAfter[0].length : 0\n\n let newlinesToAppend = ''\n let newlinesToPrepend = ''\n\n if (beforeSelection.match(/\\S/) && newlinesBeforeSelection < 2) {\n newlinesToAppend = '\\n'.repeat(2 - newlinesBeforeSelection)\n }\n\n if (afterSelection.match(/\\S/) && newlinesAfterSelection < 2) {\n newlinesToPrepend = '\\n'.repeat(2 - newlinesAfterSelection)\n }\n\n return { newlinesToAppend, newlinesToPrepend }\n}\n\n/**\n * Utility to preserve selection during operations\n */\nexport function preserveSelection(textarea, callback) {\n const start = textarea.selectionStart\n const end = textarea.selectionEnd\n const scrollTop = textarea.scrollTop\n \n callback()\n \n textarea.selectionStart = start\n textarea.selectionEnd = end\n textarea.scrollTop = scrollTop\n}\n\n/**\n * Apply a line-based operation with cursor preservation\n * This function handles expanding to line boundaries and preserving cursor position\n * @param {HTMLTextAreaElement} textarea - The textarea element\n * @param {Function} operation - The operation to perform (receives textarea and returns result)\n * @param {Object} options - Options for the operation\n * @param {string} options.prefix - The prefix being added/removed (for cursor adjustment)\n * @param {Function} options.adjustSelection - Custom selection adjustment function\n * @returns {Object} The result from the operation with adjusted cursor position\n */\nexport function applyLineOperation(textarea, operation, options = {}) {\n // Save original cursor position AND selection before any expansion\n const originalStart = textarea.selectionStart\n const originalEnd = textarea.selectionEnd\n const noInitialSelection = originalStart === originalEnd\n \n // Store the line start position to calculate offset later\n const value = textarea.value\n let lineStart = originalStart\n \n // Find start of the line containing the selection start\n while (lineStart > 0 && value[lineStart - 1] !== '\\n') {\n lineStart--\n }\n \n // Expand selection to line boundaries for the operation\n if (noInitialSelection) {\n // Expand to current line when no selection\n let lineEnd = originalStart\n \n // Find end of current line\n while (lineEnd < value.length && value[lineEnd] !== '\\n') {\n lineEnd++\n }\n \n textarea.selectionStart = lineStart\n textarea.selectionEnd = lineEnd\n } else {\n // For selections, expand to full lines\n expandSelectionToLine(textarea)\n }\n \n // Apply the operation\n const result = operation(textarea)\n \n // Restore original selection/cursor with prefix adjustment\n if (options.adjustSelection) {\n // Use custom selection adjustment logic\n const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n const isRemoving = selectedText.startsWith(options.prefix)\n const adjusted = options.adjustSelection(isRemoving, originalStart, originalEnd, lineStart)\n result.selectionStart = adjusted.start\n result.selectionEnd = adjusted.end\n } else if (options.prefix) {\n // Use default prefix-based adjustment\n const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n const isRemoving = selectedText.startsWith(options.prefix)\n \n if (noInitialSelection) {\n // No selection - just restore cursor position\n if (isRemoving) {\n // When removing prefix, adjust cursor position\n result.selectionStart = Math.max(originalStart - options.prefix.length, lineStart)\n result.selectionEnd = result.selectionStart\n } else {\n // When adding prefix, adjust cursor position\n result.selectionStart = originalStart + options.prefix.length\n result.selectionEnd = result.selectionStart\n }\n } else {\n // Had a selection - restore it with adjustment\n if (isRemoving) {\n // When removing prefix, shift selection back\n result.selectionStart = Math.max(originalStart - options.prefix.length, lineStart)\n result.selectionEnd = Math.max(originalEnd - options.prefix.length, lineStart)\n } else {\n // When adding prefix, shift selection forward\n result.selectionStart = originalStart + options.prefix.length\n result.selectionEnd = originalEnd + options.prefix.length\n }\n }\n }\n \n return result\n}", "/**\n * Block-level text formatting operations\n * Handles inline formats like bold, italic, code, and links\n */\n\nimport { expandSelectedText, newlinesToSurroundSelectedText, isMultipleLines } from '../core/selection.js'\nimport { insertText } from '../core/insertion.js'\n\n/**\n * Apply block-level styling to selected text\n */\nexport function blockStyle(textarea, style) {\n let newlinesToAppend\n let newlinesToPrepend\n\n const { prefix, suffix, blockPrefix, blockSuffix, replaceNext, prefixSpace, scanFor, surroundWithNewlines, trimFirst } = style\n const originalSelectionStart = textarea.selectionStart\n const originalSelectionEnd = textarea.selectionEnd\n\n let selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n let prefixToUse = isMultipleLines(selectedText) && blockPrefix && blockPrefix.length > 0 ? `${blockPrefix}\\n` : prefix\n let suffixToUse = isMultipleLines(selectedText) && blockSuffix && blockSuffix.length > 0 ? `\\n${blockSuffix}` : suffix\n\n if (prefixSpace) {\n const beforeSelection = textarea.value[textarea.selectionStart - 1]\n if (textarea.selectionStart !== 0 && beforeSelection != null && !beforeSelection.match(/\\s/)) {\n prefixToUse = ` ${prefixToUse}`\n }\n }\n \n selectedText = expandSelectedText(textarea, prefixToUse, suffixToUse, style.multiline)\n let selectionStart = textarea.selectionStart\n let selectionEnd = textarea.selectionEnd\n const hasReplaceNext = replaceNext && replaceNext.length > 0 && suffixToUse.indexOf(replaceNext) > -1 && selectedText.length > 0\n \n if (surroundWithNewlines) {\n const ref = newlinesToSurroundSelectedText(textarea)\n newlinesToAppend = ref.newlinesToAppend\n newlinesToPrepend = ref.newlinesToPrepend\n prefixToUse = newlinesToAppend + prefix\n suffixToUse += newlinesToPrepend\n }\n\n // Check if we should remove formatting (toggle off)\n if (selectedText.startsWith(prefixToUse) && selectedText.endsWith(suffixToUse)) {\n const replacementText = selectedText.slice(prefixToUse.length, selectedText.length - suffixToUse.length)\n if (originalSelectionStart === originalSelectionEnd) {\n let position = originalSelectionStart - prefixToUse.length\n position = Math.max(position, selectionStart)\n position = Math.min(position, selectionStart + replacementText.length)\n selectionStart = selectionEnd = position\n } else {\n selectionEnd = selectionStart + replacementText.length\n }\n return { text: replacementText, selectionStart, selectionEnd }\n } else if (!hasReplaceNext) {\n // Add formatting\n let replacementText = prefixToUse + selectedText + suffixToUse\n selectionStart = originalSelectionStart + prefixToUse.length\n selectionEnd = originalSelectionEnd + prefixToUse.length\n const whitespaceEdges = selectedText.match(/^\\s*|\\s*$/g)\n if (trimFirst && whitespaceEdges) {\n const leadingWhitespace = whitespaceEdges[0] || ''\n const trailingWhitespace = whitespaceEdges[1] || ''\n replacementText = leadingWhitespace + prefixToUse + selectedText.trim() + suffixToUse + trailingWhitespace\n selectionStart += leadingWhitespace.length\n selectionEnd -= trailingWhitespace.length\n }\n return { text: replacementText, selectionStart, selectionEnd }\n } else if (scanFor && scanFor.length > 0 && selectedText.match(scanFor)) {\n // Handle link/image with URL detection\n suffixToUse = suffixToUse.replace(replaceNext, selectedText)\n const replacementText = prefixToUse + suffixToUse\n selectionStart = selectionEnd = selectionStart + prefixToUse.length\n return { text: replacementText, selectionStart, selectionEnd }\n } else {\n // Handle link/image with placeholder\n const replacementText = prefixToUse + selectedText + suffixToUse\n selectionStart = selectionStart + prefixToUse.length + selectedText.length + suffixToUse.indexOf(replaceNext)\n selectionEnd = selectionStart + replaceNext.length\n return { text: replacementText, selectionStart, selectionEnd }\n }\n}\n\n/**\n * Apply style to selected text in textarea\n */\nexport function styleSelectedText(textarea, style) {\n const text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n \n let result\n if (style.orderedList || style.unorderedList) {\n // Will be handled by list operations\n return\n } else if (style.multiline && isMultipleLines(text)) {\n result = multilineStyle(textarea, style)\n } else {\n result = blockStyle(textarea, style)\n }\n\n insertText(textarea, result)\n}\n\n/**\n * Apply multiline styling (quotes, task lists, etc)\n * Note: This does NOT expand selection to line - that should be done by the caller if needed\n */\nexport function multilineStyle(textarea, style) {\n const { prefix, suffix, surroundWithNewlines } = style\n let text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n let selectionStart = textarea.selectionStart\n let selectionEnd = textarea.selectionEnd\n const lines = text.split('\\n')\n \n // Check if we need to undo (all lines have the format)\n const undoStyle = lines.every(line => line.startsWith(prefix) && (!suffix || line.endsWith(suffix)))\n\n if (undoStyle) {\n // Remove the formatting\n text = lines.map(line => {\n let result = line.slice(prefix.length)\n if (suffix) {\n result = result.slice(0, result.length - suffix.length)\n }\n return result\n }).join('\\n')\n selectionEnd = selectionStart + text.length\n } else {\n // Apply the formatting\n text = lines.map(line => prefix + line + (suffix || '')).join('\\n')\n if (surroundWithNewlines) {\n const { newlinesToAppend, newlinesToPrepend } = newlinesToSurroundSelectedText(textarea)\n selectionStart += newlinesToAppend.length\n selectionEnd = selectionStart + text.length\n text = newlinesToAppend + text + newlinesToPrepend\n }\n }\n\n return { text, selectionStart, selectionEnd }\n}", "/**\n * List operations for bullet and numbered lists\n */\n\nimport { expandSelectionToLine, newlinesToSurroundSelectedText, applyLineOperation } from '../core/selection.js'\nimport { insertText } from '../core/insertion.js'\n\n/**\n * Undo ordered list formatting\n */\nfunction undoOrderedListStyle(text) {\n const lines = text.split('\\n')\n const orderedListRegex = /^\\d+\\.\\s+/\n const shouldUndoOrderedList = lines.every(line => orderedListRegex.test(line))\n let result = lines\n if (shouldUndoOrderedList) {\n result = lines.map(line => line.replace(orderedListRegex, ''))\n }\n\n return {\n text: result.join('\\n'),\n processed: shouldUndoOrderedList\n }\n}\n\n/**\n * Undo unordered list formatting\n */\nfunction undoUnorderedListStyle(text) {\n const lines = text.split('\\n')\n const unorderedListPrefix = '- '\n const shouldUndoUnorderedList = lines.every(line => line.startsWith(unorderedListPrefix))\n let result = lines\n if (shouldUndoUnorderedList) {\n result = lines.map(line => line.slice(unorderedListPrefix.length))\n }\n\n return {\n text: result.join('\\n'),\n processed: shouldUndoUnorderedList\n }\n}\n\n/**\n * Make prefix for list item\n */\nfunction makePrefix(index, unorderedList) {\n if (unorderedList) {\n return '- '\n } else {\n return `${index + 1}. `\n }\n}\n\n/**\n * Clear existing list style\n */\nfunction clearExistingListStyle(style, selectedText) {\n let undoResult\n let undoResultOppositeList\n let pristineText\n \n if (style.orderedList) {\n undoResult = undoOrderedListStyle(selectedText)\n undoResultOppositeList = undoUnorderedListStyle(undoResult.text)\n pristineText = undoResultOppositeList.text\n } else {\n undoResult = undoUnorderedListStyle(selectedText)\n undoResultOppositeList = undoOrderedListStyle(undoResult.text)\n pristineText = undoResultOppositeList.text\n }\n \n return [undoResult, undoResultOppositeList, pristineText]\n}\n\n/**\n * Apply list styling to selected text\n */\nexport function listStyle(textarea, style) {\n const noInitialSelection = textarea.selectionStart === textarea.selectionEnd\n let selectionStart = textarea.selectionStart\n let selectionEnd = textarea.selectionEnd\n\n // Select whole line\n expandSelectionToLine(textarea)\n\n const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)\n\n // Clear any existing list formatting\n const [undoResult, undoResultOppositeList, pristineText] = clearExistingListStyle(style, selectedText)\n\n const prefixedLines = pristineText.split('\\n').map((value, index) => {\n return `${makePrefix(index, style.unorderedList)}${value}`\n })\n\n const totalPrefixLength = prefixedLines.reduce((previousValue, _currentValue, currentIndex) => {\n return previousValue + makePrefix(currentIndex, style.unorderedList).length\n }, 0)\n\n const totalPrefixLengthOppositeList = prefixedLines.reduce((previousValue, _currentValue, currentIndex) => {\n return previousValue + makePrefix(currentIndex, !style.unorderedList).length\n }, 0)\n\n // If we're undoing the same list type, just return the pristine text\n if (undoResult.processed) {\n if (noInitialSelection) {\n selectionStart = Math.max(selectionStart - makePrefix(0, style.unorderedList).length, 0)\n selectionEnd = selectionStart\n } else {\n selectionStart = textarea.selectionStart\n selectionEnd = textarea.selectionEnd - totalPrefixLength\n }\n return { text: pristineText, selectionStart, selectionEnd }\n }\n\n // Apply new list formatting\n const { newlinesToAppend, newlinesToPrepend } = newlinesToSurroundSelectedText(textarea)\n const text = newlinesToAppend + prefixedLines.join('\\n') + newlinesToPrepend\n\n if (noInitialSelection) {\n selectionStart = Math.max(selectionStart + makePrefix(0, style.unorderedList).length + newlinesToAppend.length, 0)\n selectionEnd = selectionStart\n } else {\n if (undoResultOppositeList.processed) {\n // Converting from one list type to another\n selectionStart = Math.max(textarea.selectionStart + newlinesToAppend.length, 0)\n selectionEnd = textarea.selectionEnd + newlinesToAppend.length + totalPrefixLength - totalPrefixLengthOppositeList\n } else {\n // Adding list formatting to plain text\n selectionStart = Math.max(textarea.selectionStart + newlinesToAppend.length, 0)\n selectionEnd = textarea.selectionEnd + newlinesToAppend.length + totalPrefixLength\n }\n }\n\n return { text, selectionStart, selectionEnd }\n}\n\n/**\n * Apply list style to textarea\n */\nexport function applyListStyle(textarea, style) {\n // Use applyLineOperation for consistent selection preservation\n const result = applyLineOperation(\n textarea,\n (ta) => listStyle(ta, style),\n {\n // Custom selection adjustment for lists\n adjustSelection: (isRemoving, selStart, selEnd, lineStart) => {\n // Get the current line to check if we're removing\n const currentLine = textarea.value.slice(lineStart, textarea.selectionEnd)\n const orderedListRegex = /^\\d+\\.\\s+/\n const unorderedListRegex = /^- /\n \n // Check if we're removing a list\n const hasOrderedList = orderedListRegex.test(currentLine)\n const hasUnorderedList = unorderedListRegex.test(currentLine)\n const isRemovingCurrent = (style.orderedList && hasOrderedList) || (style.unorderedList && hasUnorderedList)\n \n if (selStart === selEnd) {\n // No selection - cursor position\n if (isRemovingCurrent) {\n // Removing list - adjust cursor back\n const prefixMatch = currentLine.match(style.orderedList ? orderedListRegex : unorderedListRegex)\n const prefixLength = prefixMatch ? prefixMatch[0].length : 0\n return {\n start: Math.max(selStart - prefixLength, lineStart),\n end: Math.max(selStart - prefixLength, lineStart)\n }\n } else if (hasOrderedList || hasUnorderedList) {\n // Converting from one list type to another\n const oldPrefixMatch = currentLine.match(hasOrderedList ? orderedListRegex : unorderedListRegex)\n const oldPrefixLength = oldPrefixMatch ? oldPrefixMatch[0].length : 0\n const newPrefixLength = style.unorderedList ? 2 : 3 // \"- \" or \"1. \"\n const adjustment = newPrefixLength - oldPrefixLength\n return {\n start: selStart + adjustment,\n end: selStart + adjustment\n }\n } else {\n // Adding new list\n const prefixLength = style.unorderedList ? 2 : 3 // \"- \" or \"1. \"\n return {\n start: selStart + prefixLength,\n end: selStart + prefixLength\n }\n }\n } else {\n // Has selection - preserve it\n if (isRemovingCurrent) {\n // Removing current list type\n const prefixMatch = currentLine.match(style.orderedList ? orderedListRegex : unorderedListRegex)\n const prefixLength = prefixMatch ? prefixMatch[0].length : 0\n return {\n start: Math.max(selStart - prefixLength, lineStart),\n end: Math.max(selEnd - prefixLength, lineStart)\n }\n } else if (hasOrderedList || hasUnorderedList) {\n // Converting from one list type to another\n const oldPrefixMatch = currentLine.match(hasOrderedList ? orderedListRegex : unorderedListRegex)\n const oldPrefixLength = oldPrefixMatch ? oldPrefixMatch[0].length : 0\n const newPrefixLength = style.unorderedList ? 2 : 3 // \"- \" or \"1. \"\n const adjustment = newPrefixLength - oldPrefixLength\n return {\n start: selStart + adjustment,\n end: selEnd + adjustment\n }\n } else {\n // Adding new list\n const prefixLength = style.unorderedList ? 2 : 3 // \"- \" or \"1. \"\n return {\n start: selStart + prefixLength,\n end: selEnd + prefixLength\n }\n }\n }\n }\n }\n )\n \n insertText(textarea, result)\n}", "/**\n * Format detection utilities\n */\n\nimport { FORMATS } from './formats.js'\n\n/**\n * Check if text has a specific format applied\n */\nfunction hasFormatApplied(text, format) {\n if (!format.prefix) return false\n \n if (format.suffix) {\n return text.startsWith(format.prefix) && text.endsWith(format.suffix)\n } else {\n return text.startsWith(format.prefix)\n }\n}\n\n/**\n * Get active formats at cursor position\n */\nexport function getActiveFormats(textarea) {\n if (!textarea) return []\n \n const formats = []\n const { selectionStart, selectionEnd, value } = textarea\n \n // Get current line for line-based formats\n const lines = value.split('\\n')\n let lineStart = 0\n let currentLine = ''\n \n for (const line of lines) {\n if (selectionStart >= lineStart && selectionStart <= lineStart + line.length) {\n currentLine = line\n break\n }\n lineStart += line.length + 1\n }\n \n // Check line-based formats\n if (currentLine.startsWith('- ')) {\n if (currentLine.startsWith('- [ ] ') || currentLine.startsWith('- [x] ')) {\n formats.push('task-list')\n } else {\n formats.push('bullet-list')\n }\n }\n \n if (/^\\d+\\.\\s/.test(currentLine)) {\n formats.push('numbered-list')\n }\n \n if (currentLine.startsWith('> ')) {\n formats.push('quote')\n }\n \n if (currentLine.startsWith('# ')) formats.push('header')\n if (currentLine.startsWith('## ')) formats.push('header-2')\n if (currentLine.startsWith('### ')) formats.push('header-3')\n \n // Check inline formats by looking around cursor\n const lookBehind = Math.max(0, selectionStart - 10)\n const lookAhead = Math.min(value.length, selectionEnd + 10)\n const surrounding = value.slice(lookBehind, lookAhead)\n \n // Check for bold\n if (surrounding.includes('**')) {\n const beforeCursor = value.slice(Math.max(0, selectionStart - 100), selectionStart)\n const afterCursor = value.slice(selectionEnd, Math.min(value.length, selectionEnd + 100))\n const lastOpenBold = beforeCursor.lastIndexOf('**')\n const nextCloseBold = afterCursor.indexOf('**')\n if (lastOpenBold !== -1 && nextCloseBold !== -1) {\n formats.push('bold')\n }\n }\n \n // Check for italic\n if (surrounding.includes('_')) {\n const beforeCursor = value.slice(Math.max(0, selectionStart - 100), selectionStart)\n const afterCursor = value.slice(selectionEnd, Math.min(value.length, selectionEnd + 100))\n const lastOpenItalic = beforeCursor.lastIndexOf('_')\n const nextCloseItalic = afterCursor.indexOf('_')\n if (lastOpenItalic !== -1 && nextCloseItalic !== -1) {\n formats.push('italic')\n }\n }\n \n // Check for code\n if (surrounding.includes('`')) {\n const beforeCursor = value.slice(Math.max(0, selectionStart - 100), selectionStart)\n const afterCursor = value.slice(selectionEnd, Math.min(value.length, selectionEnd + 100))\n if (beforeCursor.includes('`') && afterCursor.includes('`')) {\n formats.push('code')\n }\n }\n \n // Check for link\n if (surrounding.includes('[') && surrounding.includes(']')) {\n const beforeCursor = value.slice(Math.max(0, selectionStart - 100), selectionStart)\n const afterCursor = value.slice(selectionEnd, Math.min(value.length, selectionEnd + 100))\n const lastOpenBracket = beforeCursor.lastIndexOf('[')\n const nextCloseBracket = afterCursor.indexOf(']')\n if (lastOpenBracket !== -1 && nextCloseBracket !== -1) {\n const afterBracket = value.slice(selectionEnd + nextCloseBracket + 1, selectionEnd + nextCloseBracket + 10)\n if (afterBracket.startsWith('(')) {\n formats.push('link')\n }\n }\n }\n \n return formats\n}\n\n/**\n * Check if specific format is active at cursor\n */\nexport function hasFormat(textarea, format) {\n const activeFormats = getActiveFormats(textarea)\n return activeFormats.includes(format)\n}\n\n/**\n * Expand selection based on options\n */\nexport function expandSelection(textarea, options = {}) {\n if (!textarea) return\n \n const { toWord, toLine, toFormat } = options\n const { selectionStart, selectionEnd, value } = textarea\n \n if (toLine) {\n // Find line boundaries\n const lines = value.split('\\n')\n let lineStart = 0\n let lineEnd = 0\n let currentPos = 0\n \n for (const line of lines) {\n if (selectionStart >= currentPos && selectionStart <= currentPos + line.length) {\n lineStart = currentPos\n lineEnd = currentPos + line.length\n break\n }\n currentPos += line.length + 1\n }\n \n textarea.selectionStart = lineStart\n textarea.selectionEnd = lineEnd\n } else if (toWord && selectionStart === selectionEnd) {\n // Find word boundaries\n let start = selectionStart\n let end = selectionEnd\n \n // Move start back to word boundary\n while (start > 0 && !/\\s/.test(value[start - 1])) {\n start--\n }\n \n // Move end forward to word boundary\n while (end < value.length && !/\\s/.test(value[end])) {\n end++\n }\n \n textarea.selectionStart = start\n textarea.selectionEnd = end\n }\n}"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["expandSelection", "getActiveFormats", "hasFormat", "debugMode", "getActiveFormats", "hasFormat", "expandSelection", "getActiveFormats", "hasFormat", "expandSelection"]
|
|
7
7
|
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
var markdownActions=(()=>{var
|
|
2
|
-
`).length>1}function Oe(e,n){let t=n;for(;e[t]&&e[t-1]!=null&&!e[t-1].match(/\s/);)t--;return t}function
|
|
3
|
-
`),t=0;for(let i=0;i<n.length;i++){let l=n[i].length+1;e.selectionStart>=t&&e.selectionStart<t+l&&(e.selectionStart=t),e.selectionEnd>=t&&e.selectionEnd<t+l&&(i===n.length-1?e.selectionEnd=Math.min(t+n[i].length,e.value.length):e.selectionEnd=t+l-1),t+=l}}function
|
|
4
|
-
`.repeat(2-
|
|
5
|
-
`.repeat(2-
|
|
6
|
-
`;)
|
|
7
|
-
`;)f++;e.selectionStart=
|
|
8
|
-
`:l,
|
|
9
|
-
${
|
|
10
|
-
`);if(
|
|
11
|
-
`),
|
|
12
|
-
`),l){let{newlinesToAppend:
|
|
13
|
-
`),t=/^\d+\.\s+/,i=n.every(
|
|
14
|
-
`),processed:i}}function
|
|
15
|
-
`),t="- ",i=n.every(
|
|
16
|
-
`),processed:i}}function P(e,n){return n?"- ":`${e+1}. `}function
|
|
17
|
-
`).map((
|
|
18
|
-
`)+
|
|
19
|
-
`),
|
|
20
|
-
`),f=0,
|
|
21
|
-
`;)
|
|
22
|
-
`;)f++;let
|
|
1
|
+
var markdownActions=(()=>{var A=Object.defineProperty;var Le=Object.getOwnPropertyDescriptor;var Ee=Object.getOwnPropertyNames,K=Object.getOwnPropertySymbols;var G=Object.prototype.hasOwnProperty,be=Object.prototype.propertyIsEnumerable;var z=(e,n,t)=>n in e?A(e,n,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[n]=t,U=(e,n)=>{for(var t in n||(n={}))G.call(n,t)&&z(e,t,n[t]);if(K)for(var t of K(n))be.call(n,t)&&z(e,t,n[t]);return e};var xe=(e,n)=>{for(var t in n)A(e,t,{get:n[t],enumerable:!0})},ve=(e,n,t,i)=>{if(n&&typeof n=="object"||typeof n=="function")for(let l of Ee(n))!G.call(e,l)&&l!==t&&A(e,l,{get:()=>n[l],enumerable:!(i=Le(n,l))||i.enumerable});return e};var Te=e=>ve(A({},"__esModule",{value:!0}),e);var Ce={};xe(Ce,{applyCustomFormat:()=>Se,default:()=>We,expandSelection:()=>me,getActiveFormats:()=>he,getDebugMode:()=>W,hasFormat:()=>pe,insertHeader:()=>R,insertLink:()=>se,preserveSelection:()=>D,setDebugMode:()=>H,setUndoMethod:()=>j,toggleBold:()=>te,toggleBulletList:()=>oe,toggleCode:()=>le,toggleH1:()=>de,toggleH2:()=>fe,toggleH3:()=>ge,toggleItalic:()=>ie,toggleNumberedList:()=>ce,toggleQuote:()=>re,toggleTaskList:()=>ue});var v={bold:{prefix:"**",suffix:"**",trimFirst:!0},italic:{prefix:"_",suffix:"_",trimFirst:!0},code:{prefix:"`",suffix:"`",blockPrefix:"```",blockSuffix:"```"},link:{prefix:"[",suffix:"](url)",replaceNext:"url",scanFor:"https?://"},bulletList:{prefix:"- ",multiline:!0,unorderedList:!0},numberedList:{prefix:"1. ",multiline:!0,orderedList:!0},quote:{prefix:"> ",multiline:!0,surroundWithNewlines:!0},taskList:{prefix:"- [ ] ",multiline:!0,surroundWithNewlines:!0},header1:{prefix:"# "},header2:{prefix:"## "},header3:{prefix:"### "},header4:{prefix:"#### "},header5:{prefix:"##### "},header6:{prefix:"###### "}};function Me(){return{prefix:"",suffix:"",blockPrefix:"",blockSuffix:"",multiline:!1,replaceNext:"",prefixSpace:!1,scanFor:"",surroundWithNewlines:!1,orderedList:!1,unorderedList:!1,trimFirst:!1}}function T(e){return U(U({},Me()),e)}var k=!1;function H(e){k=e}function W(){return k}function O(e,n,t){k&&(console.group(`\u{1F50D} ${e}`),console.log(n),t&&console.log("Data:",t),console.groupEnd())}function C(e,n){if(!k)return;let t=e.value.slice(e.selectionStart,e.selectionEnd);console.group(`\u{1F4CD} Selection: ${n}`),console.log("Position:",`${e.selectionStart}-${e.selectionEnd}`),console.log("Selected text:",JSON.stringify(t)),console.log("Length:",t.length);let i=e.value.slice(Math.max(0,e.selectionStart-10),e.selectionStart),l=e.value.slice(e.selectionEnd,Math.min(e.value.length,e.selectionEnd+10));console.log("Context:",JSON.stringify(i)+"[SELECTION]"+JSON.stringify(l)),console.groupEnd()}function I(e){k&&(console.group("\u{1F4DD} Result"),console.log("Text to insert:",JSON.stringify(e.text)),console.log("New selection:",`${e.selectionStart}-${e.selectionEnd}`),console.groupEnd())}var b=null;function x(e,{text:n,selectionStart:t,selectionEnd:i}){let l=W();l&&(console.group("\u{1F527} insertText"),console.log("Current selection:",`${e.selectionStart}-${e.selectionEnd}`),console.log("Text to insert:",JSON.stringify(n)),console.log("New selection to set:",t,"-",i)),e.focus();let c=e.selectionStart,d=e.selectionEnd,o=e.value.slice(0,c),s=e.value.slice(d);l&&(console.log("Before text (last 20):",JSON.stringify(o.slice(-20))),console.log("After text (first 20):",JSON.stringify(s.slice(0,20))),console.log("Selected text being replaced:",JSON.stringify(e.value.slice(c,d))));let f=e.value,u=c!==d;if(!u&&(b===null||b===!0)){e.contentEditable="true";try{b=document.execCommand("insertText",!1,n)}catch(r){b=!1}e.contentEditable="false"}else u&&(l&&console.log("Has selection, skipping execCommand and using manual mode"),b=!1);if(l&&(console.log("canInsertText before:",b),console.log("execCommand result:",b)),b){let r=o+n+s,p=e.value;l&&(console.log("Expected length:",r.length),console.log("Actual length:",p.length)),p!==r&&l&&(console.log("execCommand changed the value but not as expected"),console.log("Expected:",JSON.stringify(r.slice(0,100))),console.log("Actual:",JSON.stringify(p.slice(0,100))))}if(!b)if(l&&console.log("Using manual insertion"),e.value===f){l&&console.log("Value unchanged, doing manual replacement");try{document.execCommand("ms-beginUndoUnit")}catch(r){}e.value=o+n+s;try{document.execCommand("ms-endUndoUnit")}catch(r){}e.dispatchEvent(new CustomEvent("input",{bubbles:!0,cancelable:!0}))}else l&&console.log("Value was changed by execCommand, skipping manual insertion");l&&console.log("Setting selection range:",t,i),t!=null&&i!=null?e.setSelectionRange(t,i):e.setSelectionRange(c,e.selectionEnd),l&&(console.log("Final value length:",e.value.length),console.groupEnd())}function j(e){switch(e){case"native":b=!0;break;case"manual":b=!1;break;case"auto":b=null;break}}function $(e){return e.trim().split(`
|
|
2
|
+
`).length>1}function Oe(e,n){let t=n;for(;e[t]&&e[t-1]!=null&&!e[t-1].match(/\s/);)t--;return t}function we(e,n,t){let i=n,l=t?/\n/:/\s/;for(;e[i]&&!e[i].match(l);)i++;return i}function J(e){let n=e.value.split(`
|
|
3
|
+
`),t=0;for(let i=0;i<n.length;i++){let l=n[i].length+1;e.selectionStart>=t&&e.selectionStart<t+l&&(e.selectionStart=t),e.selectionEnd>=t&&e.selectionEnd<t+l&&(i===n.length-1?e.selectionEnd=Math.min(t+n[i].length,e.value.length):e.selectionEnd=t+l-1),t+=l}}function X(e,n,t,i=!1){if(e.selectionStart===e.selectionEnd)e.selectionStart=Oe(e.value,e.selectionStart),e.selectionEnd=we(e.value,e.selectionEnd,i);else{let l=e.selectionStart-n.length,c=e.selectionEnd+t.length,d=e.value.slice(l,e.selectionStart)===n,o=e.value.slice(e.selectionEnd,c)===t;d&&o&&(e.selectionStart=l,e.selectionEnd=c)}return e.value.slice(e.selectionStart,e.selectionEnd)}function F(e){let n=e.value.slice(0,e.selectionStart),t=e.value.slice(e.selectionEnd),i=n.match(/\n*$/),l=t.match(/^\n*/),c=i?i[0].length:0,d=l?l[0].length:0,o="",s="";return n.match(/\S/)&&c<2&&(o=`
|
|
4
|
+
`.repeat(2-c)),t.match(/\S/)&&d<2&&(s=`
|
|
5
|
+
`.repeat(2-d)),{newlinesToAppend:o,newlinesToPrepend:s}}function D(e,n){let t=e.selectionStart,i=e.selectionEnd,l=e.scrollTop;n(),e.selectionStart=t,e.selectionEnd=i,e.scrollTop=l}function N(e,n,t={}){let i=e.selectionStart,l=e.selectionEnd,c=i===l,d=e.value,o=i;for(;o>0&&d[o-1]!==`
|
|
6
|
+
`;)o--;if(c){let f=i;for(;f<d.length&&d[f]!==`
|
|
7
|
+
`;)f++;e.selectionStart=o,e.selectionEnd=f}else J(e);let s=n(e);if(t.adjustSelection){let u=e.value.slice(e.selectionStart,e.selectionEnd).startsWith(t.prefix),r=t.adjustSelection(u,i,l,o);s.selectionStart=r.start,s.selectionEnd=r.end}else if(t.prefix){let u=e.value.slice(e.selectionStart,e.selectionEnd).startsWith(t.prefix);c?u?(s.selectionStart=Math.max(i-t.prefix.length,o),s.selectionEnd=s.selectionStart):(s.selectionStart=i+t.prefix.length,s.selectionEnd=s.selectionStart):u?(s.selectionStart=Math.max(i-t.prefix.length,o),s.selectionEnd=Math.max(l-t.prefix.length,o)):(s.selectionStart=i+t.prefix.length,s.selectionEnd=l+t.prefix.length)}return s}function y(e,n){let t,i,{prefix:l,suffix:c,blockPrefix:d,blockSuffix:o,replaceNext:s,prefixSpace:f,scanFor:u,surroundWithNewlines:r,trimFirst:p}=n,h=e.selectionStart,S=e.selectionEnd,m=e.value.slice(e.selectionStart,e.selectionEnd),g=$(m)&&d&&d.length>0?`${d}
|
|
8
|
+
`:l,a=$(m)&&o&&o.length>0?`
|
|
9
|
+
${o}`:c;if(f){let L=e.value[e.selectionStart-1];e.selectionStart!==0&&L!=null&&!L.match(/\s/)&&(g=` ${g}`)}m=X(e,g,a,n.multiline);let E=e.selectionStart,M=e.selectionEnd,ae=s&&s.length>0&&a.indexOf(s)>-1&&m.length>0;if(r){let L=F(e);t=L.newlinesToAppend,i=L.newlinesToPrepend,g=t+l,a+=i}if(m.startsWith(g)&&m.endsWith(a)){let L=m.slice(g.length,m.length-a.length);if(h===S){let w=h-g.length;w=Math.max(w,E),w=Math.min(w,E+L.length),E=M=w}else M=E+L.length;return{text:L,selectionStart:E,selectionEnd:M}}else if(ae)if(u&&u.length>0&&m.match(u)){a=a.replace(s,m);let L=g+a;return E=M=E+g.length,{text:L,selectionStart:E,selectionEnd:M}}else{let L=g+m+a;return E=E+g.length+m.length+a.indexOf(s),M=E+s.length,{text:L,selectionStart:E,selectionEnd:M}}else{let L=g+m+a;E=h+g.length,M=S+g.length;let w=m.match(/^\s*|\s*$/g);if(p&&w){let q=w[0]||"",Q=w[1]||"";L=q+g+m.trim()+a+Q,E+=q.length,M-=Q.length}return{text:L,selectionStart:E,selectionEnd:M}}}function B(e,n){let{prefix:t,suffix:i,surroundWithNewlines:l}=n,c=e.value.slice(e.selectionStart,e.selectionEnd),d=e.selectionStart,o=e.selectionEnd,s=c.split(`
|
|
10
|
+
`);if(s.every(u=>u.startsWith(t)&&(!i||u.endsWith(i))))c=s.map(u=>{let r=u.slice(t.length);return i&&(r=r.slice(0,r.length-i.length)),r}).join(`
|
|
11
|
+
`),o=d+c.length;else if(c=s.map(u=>t+u+(i||"")).join(`
|
|
12
|
+
`),l){let{newlinesToAppend:u,newlinesToPrepend:r}=F(e);d+=u.length,o=d+c.length,c=u+c+r}return{text:c,selectionStart:d,selectionEnd:o}}function Y(e){let n=e.split(`
|
|
13
|
+
`),t=/^\d+\.\s+/,i=n.every(c=>t.test(c)),l=n;return i&&(l=n.map(c=>c.replace(t,""))),{text:l.join(`
|
|
14
|
+
`),processed:i}}function Z(e){let n=e.split(`
|
|
15
|
+
`),t="- ",i=n.every(c=>c.startsWith(t)),l=n;return i&&(l=n.map(c=>c.slice(t.length))),{text:l.join(`
|
|
16
|
+
`),processed:i}}function P(e,n){return n?"- ":`${e+1}. `}function ye(e,n){let t,i,l;return e.orderedList?(t=Y(n),i=Z(t.text),l=i.text):(t=Z(n),i=Y(t.text),l=i.text),[t,i,l]}function ke(e,n){let t=e.selectionStart===e.selectionEnd,i=e.selectionStart,l=e.selectionEnd;J(e);let c=e.value.slice(e.selectionStart,e.selectionEnd),[d,o,s]=ye(n,c),f=s.split(`
|
|
17
|
+
`).map((m,g)=>`${P(g,n.unorderedList)}${m}`),u=f.reduce((m,g,a)=>m+P(a,n.unorderedList).length,0),r=f.reduce((m,g,a)=>m+P(a,!n.unorderedList).length,0);if(d.processed)return t?(i=Math.max(i-P(0,n.unorderedList).length,0),l=i):(i=e.selectionStart,l=e.selectionEnd-u),{text:s,selectionStart:i,selectionEnd:l};let{newlinesToAppend:p,newlinesToPrepend:h}=F(e),S=p+f.join(`
|
|
18
|
+
`)+h;return t?(i=Math.max(i+P(0,n.unorderedList).length+p.length,0),l=i):o.processed?(i=Math.max(e.selectionStart+p.length,0),l=e.selectionEnd+p.length+u-r):(i=Math.max(e.selectionStart+p.length,0),l=e.selectionEnd+p.length+u),{text:S,selectionStart:i,selectionEnd:l}}function V(e,n){let t=N(e,i=>ke(i,n),{adjustSelection:(i,l,c,d)=>{let o=e.value.slice(d,e.selectionEnd),s=/^\d+\.\s+/,f=/^- /,u=s.test(o),r=f.test(o),p=n.orderedList&&u||n.unorderedList&&r;if(l===c)if(p){let h=o.match(n.orderedList?s:f),S=h?h[0].length:0;return{start:Math.max(l-S,d),end:Math.max(l-S,d)}}else if(u||r){let h=o.match(u?s:f),S=h?h[0].length:0,g=(n.unorderedList?2:3)-S;return{start:l+g,end:l+g}}else{let h=n.unorderedList?2:3;return{start:l+h,end:l+h}}else if(p){let h=o.match(n.orderedList?s:f),S=h?h[0].length:0;return{start:Math.max(l-S,d),end:Math.max(c-S,d)}}else if(u||r){let h=o.match(u?s:f),S=h?h[0].length:0,g=(n.unorderedList?2:3)-S;return{start:l+g,end:c+g}}else{let h=n.unorderedList?2:3;return{start:l+h,end:c+h}}}});x(e,t)}function _(e){if(!e)return[];let n=[],{selectionStart:t,selectionEnd:i,value:l}=e,c=l.split(`
|
|
19
|
+
`),d=0,o="";for(let r of c){if(t>=d&&t<=d+r.length){o=r;break}d+=r.length+1}o.startsWith("- ")&&(o.startsWith("- [ ] ")||o.startsWith("- [x] ")?n.push("task-list"):n.push("bullet-list")),/^\d+\.\s/.test(o)&&n.push("numbered-list"),o.startsWith("> ")&&n.push("quote"),o.startsWith("# ")&&n.push("header"),o.startsWith("## ")&&n.push("header-2"),o.startsWith("### ")&&n.push("header-3");let s=Math.max(0,t-10),f=Math.min(l.length,i+10),u=l.slice(s,f);if(u.includes("**")){let r=l.slice(Math.max(0,t-100),t),p=l.slice(i,Math.min(l.length,i+100)),h=r.lastIndexOf("**"),S=p.indexOf("**");h!==-1&&S!==-1&&n.push("bold")}if(u.includes("_")){let r=l.slice(Math.max(0,t-100),t),p=l.slice(i,Math.min(l.length,i+100)),h=r.lastIndexOf("_"),S=p.indexOf("_");h!==-1&&S!==-1&&n.push("italic")}if(u.includes("`")){let r=l.slice(Math.max(0,t-100),t),p=l.slice(i,Math.min(l.length,i+100));r.includes("`")&&p.includes("`")&&n.push("code")}if(u.includes("[")&&u.includes("]")){let r=l.slice(Math.max(0,t-100),t),p=l.slice(i,Math.min(l.length,i+100)),h=r.lastIndexOf("["),S=p.indexOf("]");h!==-1&&S!==-1&&l.slice(i+S+1,i+S+10).startsWith("(")&&n.push("link")}return n}function ee(e,n){return _(e).includes(n)}function ne(e,n={}){if(!e)return;let{toWord:t,toLine:i,toFormat:l}=n,{selectionStart:c,selectionEnd:d,value:o}=e;if(i){let s=o.split(`
|
|
20
|
+
`),f=0,u=0,r=0;for(let p of s){if(c>=r&&c<=r+p.length){f=r,u=r+p.length;break}r+=p.length+1}e.selectionStart=f,e.selectionEnd=u}else if(t&&c===d){let s=c,f=d;for(;s>0&&!/\s/.test(o[s-1]);)s--;for(;f<o.length&&!/\s/.test(o[f]);)f++;e.selectionStart=s,e.selectionEnd=f}}function te(e){if(!e||e.disabled||e.readOnly)return;O("toggleBold","Starting"),C(e,"Before");let n=T(v.bold),t=y(e,n);I(t),x(e,t),C(e,"After")}function ie(e){if(!e||e.disabled||e.readOnly)return;let n=T(v.italic),t=y(e,n);x(e,t)}function le(e){if(!e||e.disabled||e.readOnly)return;let n=T(v.code),t=y(e,n);x(e,t)}function se(e,n={}){if(!e||e.disabled||e.readOnly)return;let t=e.value.slice(e.selectionStart,e.selectionEnd),i=T(v.link);if(t&&t.match(/^https?:\/\//)&&!n.url?(i.suffix=`](${t})`,i.replaceNext=""):n.url&&(i.suffix=`](${n.url})`,i.replaceNext=""),n.text&&!t){let d=e.selectionStart;e.value=e.value.slice(0,d)+n.text+e.value.slice(d),e.selectionStart=d,e.selectionEnd=d+n.text.length}let c=y(e,i);x(e,c)}function oe(e){if(!e||e.disabled||e.readOnly)return;let n=T(v.bulletList);V(e,n)}function ce(e){if(!e||e.disabled||e.readOnly)return;let n=T(v.numberedList);V(e,n)}function re(e){if(!e||e.disabled||e.readOnly)return;O("toggleQuote","Starting"),C(e,"Initial");let n=T(v.quote),t=N(e,i=>B(i,n),{prefix:n.prefix});I(t),x(e,t),C(e,"Final")}function ue(e){if(!e||e.disabled||e.readOnly)return;let n=T(v.taskList),t=N(e,i=>B(i,n),{prefix:n.prefix});x(e,t)}function R(e,n=1,t=!1){if(!e||e.disabled||e.readOnly)return;(n<1||n>6)&&(n=1),O("insertHeader",`Level: ${n}, Toggle: ${t}`);let i=`header${n===1?"1":n}`,l=T(v[i]||v.header1),c=e.selectionStart,d=e.selectionEnd,o=e.value,s=c;for(;s>0&&o[s-1]!==`
|
|
21
|
+
`;)s--;let f=d;for(;f<o.length&&o[f]!==`
|
|
22
|
+
`;)f++;let u=o.slice(s,f);O("insertHeader",`Current line: "${u}"`);let r=u.match(/^(#{1,6})\s*/),p=r?r[1].length:0,h=r?r[0].length:0;O("insertHeader",`Existing level: ${p}, Target level: ${n}`);let S,m=0;if(t&&p===n)O("insertHeader","Toggling OFF header"),S=u.replace(/^#{1,6}\s*/,""),m=-h;else if(p>0){O("insertHeader","Replacing header");let a=u.replace(/^#{1,6}\s*/,"");S=l.prefix+a,m=l.prefix.length-h}else O("insertHeader","Adding new header"),S=l.prefix+u,m=l.prefix.length;let g={text:S,selectionStart:s,selectionEnd:f};c===d?(g.selectionStart=Math.max(c+m,s),g.selectionEnd=g.selectionStart):(g.selectionStart=Math.max(c+m,s),g.selectionEnd=Math.max(d+m,s)),O("insertHeader",`Result: "${g.text}" (${g.selectionStart}, ${g.selectionEnd})`),e.selectionStart=s,e.selectionEnd=f,x(e,g)}function de(e){R(e,1,!0)}function fe(e){R(e,2,!0)}function ge(e){R(e,3,!0)}function he(e){return _(e)}function pe(e,n){return ee(e,n)}function me(e,n={}){ne(e,n)}function Se(e,n){if(!e||e.disabled||e.readOnly)return;let t=T(n),i;if(t.multiline){let l=e.value.slice(e.selectionStart,e.selectionEnd);$(l)?i=B(e,t):i=y(e,t)}else i=y(e,t);x(e,i)}var We={toggleBold:te,toggleItalic:ie,toggleCode:le,insertLink:se,toggleBulletList:oe,toggleNumberedList:ce,toggleQuote:re,toggleTaskList:ue,insertHeader:R,toggleH1:de,toggleH2:fe,toggleH3:ge,getActiveFormats:he,hasFormat:pe,expandSelection:me,applyCustomFormat:Se,preserveSelection:D,setUndoMethod:j,setDebugMode:H,getDebugMode:W};return Te(Ce);})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "markdown-actions",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "A lightweight, zero-dependency JavaScript library for adding markdown formatting functionality to any textarea element",
|
|
5
5
|
"main": "dist/markdown-actions.js",
|
|
6
6
|
"module": "dist/markdown-actions.esm.js",
|
package/src/index.js
CHANGED
|
@@ -156,91 +156,83 @@ export function insertHeader(textarea, level = 1, toggle = false) {
|
|
|
156
156
|
if (!textarea || textarea.disabled || textarea.readOnly) return
|
|
157
157
|
if (level < 1 || level > 6) level = 1
|
|
158
158
|
|
|
159
|
+
debugLog('insertHeader', `Level: ${level}, Toggle: ${toggle}`);
|
|
160
|
+
|
|
159
161
|
const headerKey = `header${level === 1 ? '1' : level}`
|
|
160
162
|
const style = mergeWithDefaults(FORMATS[headerKey] || FORMATS.header1)
|
|
161
163
|
|
|
162
|
-
//
|
|
163
|
-
const value = textarea.value
|
|
164
|
+
// Save original cursor position
|
|
164
165
|
const originalStart = textarea.selectionStart
|
|
165
166
|
const originalEnd = textarea.selectionEnd
|
|
167
|
+
const value = textarea.value
|
|
166
168
|
|
|
167
|
-
// Find
|
|
169
|
+
// Find line boundaries
|
|
168
170
|
let lineStart = originalStart
|
|
169
171
|
while (lineStart > 0 && value[lineStart - 1] !== '\n') {
|
|
170
172
|
lineStart--
|
|
171
173
|
}
|
|
172
174
|
|
|
173
|
-
// Find the end of the current line
|
|
174
175
|
let lineEnd = originalEnd
|
|
175
176
|
while (lineEnd < value.length && value[lineEnd] !== '\n') {
|
|
176
177
|
lineEnd++
|
|
177
178
|
}
|
|
178
179
|
|
|
179
|
-
// Get current line
|
|
180
|
-
const
|
|
181
|
-
|
|
180
|
+
// Get the current line
|
|
181
|
+
const currentLine = value.slice(lineStart, lineEnd)
|
|
182
|
+
debugLog('insertHeader', `Current line: "${currentLine}"`);
|
|
183
|
+
|
|
184
|
+
// Check for existing header
|
|
185
|
+
const existingHeaderMatch = currentLine.match(/^(#{1,6})\s*/)
|
|
182
186
|
const existingLevel = existingHeaderMatch ? existingHeaderMatch[1].length : 0
|
|
187
|
+
const existingPrefixLength = existingHeaderMatch ? existingHeaderMatch[0].length : 0
|
|
183
188
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
start: selStart + prefixDiff,
|
|
232
|
-
end: selEnd + prefixDiff
|
|
233
|
-
}
|
|
234
|
-
} else {
|
|
235
|
-
// Adding new header
|
|
236
|
-
return {
|
|
237
|
-
start: selStart + style.prefix.length,
|
|
238
|
-
end: selEnd + style.prefix.length
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
)
|
|
189
|
+
debugLog('insertHeader', `Existing level: ${existingLevel}, Target level: ${level}`);
|
|
190
|
+
|
|
191
|
+
// Determine the new line content
|
|
192
|
+
let newLine
|
|
193
|
+
let prefixChange = 0
|
|
194
|
+
|
|
195
|
+
if (toggle && existingLevel === level) {
|
|
196
|
+
// Toggle off - remove the header
|
|
197
|
+
debugLog('insertHeader', 'Toggling OFF header');
|
|
198
|
+
newLine = currentLine.replace(/^#{1,6}\s*/, '')
|
|
199
|
+
prefixChange = -existingPrefixLength
|
|
200
|
+
} else if (existingLevel > 0) {
|
|
201
|
+
// Replace existing header with new one
|
|
202
|
+
debugLog('insertHeader', 'Replacing header');
|
|
203
|
+
const cleanedLine = currentLine.replace(/^#{1,6}\s*/, '')
|
|
204
|
+
newLine = style.prefix + cleanedLine
|
|
205
|
+
prefixChange = style.prefix.length - existingPrefixLength
|
|
206
|
+
} else {
|
|
207
|
+
// Add new header
|
|
208
|
+
debugLog('insertHeader', 'Adding new header');
|
|
209
|
+
newLine = style.prefix + currentLine
|
|
210
|
+
prefixChange = style.prefix.length
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Build the result
|
|
214
|
+
const result = {
|
|
215
|
+
text: newLine,
|
|
216
|
+
selectionStart: lineStart,
|
|
217
|
+
selectionEnd: lineEnd
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Adjust cursor position based on prefix change
|
|
221
|
+
if (originalStart === originalEnd) {
|
|
222
|
+
// No selection - adjust cursor position
|
|
223
|
+
result.selectionStart = Math.max(originalStart + prefixChange, lineStart)
|
|
224
|
+
result.selectionEnd = result.selectionStart
|
|
225
|
+
} else {
|
|
226
|
+
// Has selection - preserve it with adjustment
|
|
227
|
+
result.selectionStart = Math.max(originalStart + prefixChange, lineStart)
|
|
228
|
+
result.selectionEnd = Math.max(originalEnd + prefixChange, lineStart)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
debugLog('insertHeader', `Result: "${result.text}" (${result.selectionStart}, ${result.selectionEnd})`);
|
|
232
|
+
|
|
233
|
+
// Expand selection to full line for replacement
|
|
234
|
+
textarea.selectionStart = lineStart
|
|
235
|
+
textarea.selectionEnd = lineEnd
|
|
244
236
|
|
|
245
237
|
insertText(textarea, result)
|
|
246
238
|
}
|