|
document.addEventListener('DOMContentLoaded', function() { |
|
|
|
initializeEditor(); |
|
}); |
|
|
|
|
|
|
|
|
|
function initializeEditor() { |
|
const editorContainer = document.querySelector('.editor-container'); |
|
|
|
if (!editorContainer) return; |
|
|
|
const textarea = editorContainer.querySelector('textarea'); |
|
const toolbar = editorContainer.querySelector('.editor-toolbar'); |
|
|
|
if (!textarea || !toolbar) return; |
|
|
|
|
|
setupToolbarButtons(toolbar, textarea); |
|
|
|
|
|
textarea.addEventListener('keydown', function(e) { |
|
|
|
if (e.key === 'Tab') { |
|
e.preventDefault(); |
|
|
|
const start = this.selectionStart; |
|
const end = this.selectionEnd; |
|
|
|
|
|
this.value = this.value.substring(0, start) + " " + this.value.substring(end); |
|
|
|
|
|
this.selectionStart = this.selectionEnd = start + 4; |
|
} |
|
}); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
function setupToolbarButtons(toolbar, textarea) { |
|
|
|
const buttons = [ |
|
{ |
|
name: 'bold', |
|
icon: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"></path><path d="M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"></path></svg>', |
|
action: (text) => wrapText(textarea, '[b]', '[/b]') |
|
}, |
|
{ |
|
name: 'italic', |
|
icon: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="19" y1="4" x2="10" y2="4"></line><line x1="14" y1="20" x2="5" y2="20"></line><line x1="15" y1="4" x2="9" y2="20"></line></svg>', |
|
action: (text) => wrapText(textarea, '[i]', '[/i]') |
|
}, |
|
{ |
|
name: 'underline', |
|
icon: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3v7a6 6 0 0 0 6 6 6 6 0 0 0 6-6V3"></path><line x1="4" y1="21" x2="20" y2="21"></line></svg>', |
|
action: (text) => wrapText(textarea, '[u]', '[/u]') |
|
}, |
|
{ |
|
name: 'link', |
|
icon: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>', |
|
action: (text) => insertLink(textarea) |
|
}, |
|
{ |
|
name: 'image', |
|
icon: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><circle cx="8.5" cy="8.5" r="1.5"></circle><polyline points="21 15 16 10 5 21"></polyline></svg>', |
|
action: (text) => insertImage(textarea) |
|
}, |
|
{ |
|
name: 'code', |
|
icon: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg>', |
|
action: (text) => wrapText(textarea, '[code]', '[/code]') |
|
}, |
|
{ |
|
name: 'quote', |
|
icon: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 21c3.87-7.05 5.02-13.54 5.02-13.54 0-3.31 2.67-5.99 5.98-6 3.31 0 6 2.68 6 5.99 0 3.31-2.69 6.01-6 6.01h-2c.73 2 2.97 3.02 5.02 3.02-1.59 1.38-3.09 2.51-5.02 3.53C9.08 21.42 6.24 21.43 3 21z"></path></svg>', |
|
action: (text) => wrapText(textarea, '[quote]', '[/quote]') |
|
} |
|
]; |
|
|
|
|
|
buttons.forEach(button => { |
|
const btn = document.createElement('button'); |
|
btn.type = 'button'; |
|
btn.setAttribute('aria-label', button.name); |
|
btn.innerHTML = button.icon; |
|
btn.classList.add('editor-button'); |
|
|
|
btn.addEventListener('click', () => { |
|
button.action(); |
|
textarea.focus(); |
|
}); |
|
|
|
toolbar.appendChild(btn); |
|
}); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function wrapText(textarea, openTag, closeTag) { |
|
const start = textarea.selectionStart; |
|
const end = textarea.selectionEnd; |
|
const selectedText = textarea.value.substring(start, end); |
|
const replacement = openTag + selectedText + closeTag; |
|
|
|
textarea.value = textarea.value.substring(0, start) + replacement + textarea.value.substring(end); |
|
|
|
|
|
textarea.selectionStart = start + openTag.length; |
|
textarea.selectionEnd = start + openTag.length + selectedText.length; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
function insertLink(textarea) { |
|
const selectedText = textarea.value.substring(textarea.selectionStart, textarea.selectionEnd); |
|
|
|
let url = prompt('Enter the URL:', 'http://'); |
|
if (!url) return; |
|
|
|
let text = selectedText || prompt('Enter the link text:', ''); |
|
if (!text) text = url; |
|
|
|
const linkBBCode = `[url=${url}]${text}[/url]`; |
|
|
|
insertAtCursor(textarea, linkBBCode); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
function insertImage(textarea) { |
|
const url = prompt('Enter the image URL:', 'http://'); |
|
if (!url) return; |
|
|
|
const imageBBCode = `[img]${url}[/img]`; |
|
|
|
insertAtCursor(textarea, imageBBCode); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
function insertAtCursor(textarea, text) { |
|
const start = textarea.selectionStart; |
|
const end = textarea.selectionEnd; |
|
|
|
textarea.value = textarea.value.substring(0, start) + text + textarea.value.substring(end); |
|
|
|
|
|
textarea.selectionStart = textarea.selectionEnd = start + text.length; |
|
} |
|
|