PHP Classes

File: public_html/js/markdown-editor.js

Recommend this page to a friend!
  Packages of Matthew Asham   Binkterm PHP   public_html/js/markdown-editor.js   Download  
File: public_html/js/markdown-editor.js
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: Binkterm PHP
Bulletin board system based on the Web
Author: By
Last change:
Date: 5 days ago
Size: 8,020 bytes
 

Contents

Class file image Download
(function(window) { 'use strict'; function sanitizeTuiMarkdown(md) { md = String(md || ''); const protectedSegments = []; const placeholderPrefix = '%%TUIESC'; md = md.replace(/```[\s\S]*?```|`[^`\n]+`|!?\[[^\]]*\]\([^)]+\)/g, function(segment) { const token = placeholderPrefix + protectedSegments.length + '%%'; protectedSegments.push(segment); return token; }); md = md .replace(/<br\s*\/?>/gi, '\n') .replace(/<[^>]+>/g, '') .replace(/^(>+[ ]*)((?:\\#)+)( )/gm, function(match, prefix, hashes, space) { return prefix + hashes.replace(/\\#/g, '#') + space; }) .replace(/\\([-_.~|])/g, '$1'); return md.replace(/%%TUIESC(\d+)%%/g, function(match, index) { return protectedSegments[parseInt(index, 10)] || match; }); } function resolveElement(value) { return typeof value === 'string' ? document.querySelector(value) : value; } function MarkdownEditor(options) { this.options = options || {}; this.editor = null; this.active = false; this.boundKeydown = null; this.boundPaste = null; } MarkdownEditor.prototype.init = function() { if (this.active) { return this.editor; } if (!window.toastui || !window.toastui.Editor) { throw new Error('Toast UI Editor is not loaded'); } const textarea = resolveElement(this.options.textarea); const editorEl = resolveElement(this.options.editorEl); const plainContainer = resolveElement(this.options.plainContainer); const editorContainer = resolveElement(this.options.editorContainer); const height = this.options.height || ((textarea && textarea.offsetHeight) ? textarea.offsetHeight + 'px' : '320px'); if (plainContainer) { plainContainer.style.display = 'none'; } else if (textarea) { textarea.style.display = 'none'; } if (editorContainer) { editorContainer.style.display = ''; } this.editor = new window.toastui.Editor({ el: editorEl, height: height, initialEditType: this.options.initialEditType || 'wysiwyg', previewStyle: this.options.previewStyle || 'tab', initialValue: textarea ? textarea.value : '', toolbarItems: this.options.toolbarItems || [], usageStatistics: false, events: { change: () => { const raw = this.editor ? this.editor.getMarkdown() : ''; const cleaned = sanitizeTuiMarkdown(raw); if (textarea) { textarea.value = cleaned; } if (this.editor && this.editor.isMarkdownMode && this.editor.isMarkdownMode() && cleaned !== raw) { this.editor.setMarkdown(cleaned, false); } if (typeof this.options.onChange === 'function') { this.options.onChange(cleaned, raw, this.editor); } } } }); const editorUI = editorEl ? editorEl.querySelector('.toastui-editor-defaultUI') : null; if (editorUI) { editorUI.classList.add('toastui-editor-dark'); } if (typeof this.options.onCtrlK === 'function' && editorEl) { this.boundKeydown = (event) => { if ((event.ctrlKey || event.metaKey) && event.key === 'k') { event.preventDefault(); event.stopPropagation(); this.options.onCtrlK(event, this.editor); } }; editorEl.addEventListener('keydown', this.boundKeydown, true); } if (typeof this.options.onBareUrlPaste === 'function' && editorEl) { this.boundPaste = (event) => { const data = event.clipboardData || window.clipboardData; const text = data && data.getData ? data.getData('text/plain').trim() : ''; if (/^https?:\/\/\S+$/.test(text)) { this.options.onBareUrlPaste(text, event, this.editor); } }; editorEl.addEventListener('paste', this.boundPaste, true); } this.active = true; if (this.options.focus !== false && this.editor) { this.editor.focus(); } return this.editor; }; MarkdownEditor.prototype.destroy = function(options) { options = options || {}; const sync = options.sync !== false; const textarea = resolveElement(this.options.textarea); const editorEl = resolveElement(this.options.editorEl); const plainContainer = resolveElement(this.options.plainContainer); const editorContainer = resolveElement(this.options.editorContainer); if (!this.active && !this.editor) { return; } if (sync) { this.sync(); } if (editorEl && this.boundKeydown) { editorEl.removeEventListener('keydown', this.boundKeydown, true); this.boundKeydown = null; } if (editorEl && this.boundPaste) { editorEl.removeEventListener('paste', this.boundPaste, true); this.boundPaste = null; } if (this.editor) { this.editor.destroy(); this.editor = null; } if (editorContainer) { editorContainer.style.display = 'none'; } if (plainContainer) { plainContainer.style.display = ''; } else if (textarea) { textarea.style.display = ''; } this.active = false; }; MarkdownEditor.prototype.sync = function() { const textarea = resolveElement(this.options.textarea); if (this.editor && textarea) { textarea.value = sanitizeTuiMarkdown(this.editor.getMarkdown()); } return textarea ? textarea.value : ''; }; MarkdownEditor.prototype.setMarkdown = function(markdown, cursorToEnd) { const textarea = resolveElement(this.options.textarea); if (textarea) { textarea.value = String(markdown || ''); } if (this.editor) { this.editor.setMarkdown(String(markdown || ''), cursorToEnd === true); } }; MarkdownEditor.prototype.getMarkdown = function() { return this.sync(); }; MarkdownEditor.prototype.exec = function(action, payload) { if (!this.editor) { return false; } const commandMap = { bold: 'bold', italic: 'italic', code: 'code', codeblock: 'codeBlock', ul: 'bulletList', ol: 'orderedList', quote: 'blockQuote', hr: 'hr' }; if (action === 'h1' || action === 'h2' || action === 'h3') { this.editor.exec('heading', { level: parseInt(action.substring(1), 10) }); } else if (commandMap[action]) { this.editor.exec(commandMap[action], payload); } else { this.editor.exec(action, payload); } this.editor.focus(); return true; }; MarkdownEditor.prototype.focus = function() { if (this.editor) { this.editor.focus(); } }; MarkdownEditor.prototype.getToastEditor = function() { return this.editor; }; window.BinkMarkdownEditor = { sanitize: sanitizeTuiMarkdown, create: function(options) { return new MarkdownEditor(options); }, mount: function(options) { const controller = new MarkdownEditor(options); controller.init(); return controller; } }; })(window);