import * as DataEvent from '../events/DataEvent'; import DateUtils from '../utilities/DateUtils'; import { position, offset } 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.dateUtils = new DateUtils(); this.textEditor = textEditor; this.fixLimit = scrollLimit; this.caretPos = null; this.url = ''; let self = this; this.setInputs(); window.addEventListener("scroll", f => { 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(f => { 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, 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 self = this; 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