fipamo/brain/tools/ui/TextEditor.js

157 lines
5 KiB
JavaScript

import * as DataEvent from '../events/DataEvent';
import DateUtils from '../utilities/DateUtils';
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.dateUtils = new DateUtils();
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'), '<br>');
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('<del>' + pulled + '</del>'));
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;