import * as DataEvent from '../events/DataEvent'; import { position } from 'caret-pos'; import EventEmitter from '../events/EventEmitter'; import * as EditorEvent from '../events/EditorEvent'; class TextEditor extends EventEmitter { /** * Text Editor UI Component * @constructor * @param {object} textEditor - Text area that will edit text * @param {number} scrollLimit - YPos where editor position will become fixed */ //-------------------------- // constructor //-------------------------- constructor(textEditor, scrollLimit) { super(); hljs.initHighlightingOnLoad(); this.textEditor = textEditor; this.fixLimit = scrollLimit; this.caretPos = null; this.url = ''; this.setInputs(); window.addEventListener('scroll', () => { var fixLimit = this.fixLimit; if (window.pageYOffset >= fixLimit) { document.getElementById('edit-control').style.position = 'fixed'; } else { document.getElementById('edit-control').style.position = 'relative'; } }); this.refresh(); } //-------------------------- // methods //-------------------------- setInputs() { let self = this; var editorButtons = document.querySelectorAll('.editor-button'); for (var i = 0, length = editorButtons.length; i < length; i++) { editorButtons[i].addEventListener('click', e => this.handleEditorOption(e), false); } this.textEditor.addEventListener('input', e => { let htmlTagRe = /<[a-z][\s\S]*>/g; let text = this.textEditor.innerText; if (e.inputType == 'insertParagraph') return; //cursor setting gets weird on return, so just back out if (text.search(htmlTagRe) > -1) { let caret = position(this.textEditor).pos; self.refresh(); position(this.textEditor, caret); } }); } refresh() { var spiffed = hljs.highlight('markdown', this.textEditor.innerText).value; spiffed = spiffed.replace(new RegExp('\r?\n', 'g'), '
'); var temp = document.createElement('div'); temp.innerText = spiffed; this.textEditor.innerHTML = temp.innerText; this.textEditor.style.maxWidth = '900px'; } notify(type, data) { switch (type) { case DataEvent.POST_UPDATED: document.getElementById('submit-update').classList.add('icon-hide'); document.getElementById('submit-good').classList.remove('icon-hide'); document.getElementById('edit-update').classList.remove('submit-start'); document.getElementById('edit-update').classList.add('submit-cool'); setTimeout(() => { document.getElementById('submit-update').classList.remove('icon-hide'); document.getElementById('submit-good').classList.add('icon-hide'); document.getElementById('edit-update').classList.add('submit-start'); document.getElementById('edit-update').classList.remove('submit-cool'); }, 2000); break; case DataEvent.POST_ADDED: // do nothing break; case EditorEvent.EDITOR_UPLOAD_POST_IMAGE: position(this.textEditor, this.caretPos); var sel, range; //var pulled; sel = window.getSelection(); //console.log(sel) //console.log(note.message) if (sel.rangeCount) { range = sel.getRangeAt(0); //pulled = sel.getRangeAt(0).toString(); range.deleteContents(); range.insertNode( document.createTextNode('![image alt text](' + data + " 'image title')") ); } this.refresh(); break; } } //-------------------------- // event handlers //-------------------------- handleEditorOption(e) { e.preventDefault(); var sel, range, pulled; sel = window.getSelection(); //console.log(sel) if (sel.rangeCount) { range = sel.getRangeAt(0); pulled = sel.getRangeAt(0).toString(); range.deleteContents(); switch (e.target.id) { case 'edit-bold': range.insertNode(document.createTextNode('**' + pulled + '**')); break; case 'edit-italic': range.insertNode(document.createTextNode('*' + pulled + '*')); break; case 'edit-strikethrough': range.insertNode(document.createTextNode('' + pulled + '')); break; case 'edit-header1': range.insertNode(document.createTextNode('# ' + pulled)); break; case 'edit-header2': range.insertNode(document.createTextNode('## ' + pulled)); break; case 'edit-header3': range.insertNode(document.createTextNode('### ' + pulled)); break; case 'edit-image': this.caretPos = position(this.textEditor).pos; this.emitEvent(EditorEvent.EDITOR_UPLOAD_POST_IMAGE); break; case 'submit-save': case 'edit-save': this.emitEvent(EditorEvent.EDITOR_SAVE); break; case 'submit-update': case 'edit-update': this.emitEvent(EditorEvent.EDITOR_UPDATE); break; case 'edit-link': range.insertNode(document.createTextNode('[' + pulled + '](PASTE URL HERE)')); break; case 'edit-delete': this.emitEvent(EditorEvent.EDITOR_DELETE); break; default: //range.insertNode(document.createTextNode("[" + self.url + "](PASTE URL HERE)")); break; } } this.refresh(); } } export default TextEditor;