forked from projects/fipamo
ro
1e37580869
dropped in js from the old site to begin the process of wiring up the API, but this time around, scripts will be served directly in browswer rather than being transpiled through NPM/Babel, eliminating the need for NPM. also scripting will new modularized and served specifically for the requirements of the page loading it. no more front loading everything. only script that is needed for that page will be retrieved. if no scripting is needed, none will be loaded. The only casualty so far has been syntax highlighting due to prismjs still being a common js module, but either this will be replaced with another library or a custom syntax enginge will be created at a later date
207 lines
6.5 KiB
JavaScript
207 lines
6.5 KiB
JavaScript
import * as DataEvent from '../events/DataEvent.js';
|
|
import EventEmitter from '../events/EventEmitter.js';
|
|
import * as EditorEvent from '../events/EditorEvent.js';
|
|
import Prism from '../vendor/prism.js';
|
|
//import MarkdownLang from '../vendor/lang/prism-markdown.js';
|
|
//Prism.language.md = '../vendor/lang/prism-markdown.js';
|
|
//Prism.languauges['markdown'];
|
|
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();
|
|
|
|
document
|
|
.querySelector('[role="text-editor-control"]')
|
|
.addEventListener('scroll', e => {
|
|
console.log('HERE');
|
|
});
|
|
|
|
document.body.addEventListener('scroll', e => {
|
|
var fixLimit = scrollLimit;
|
|
//console.log('POSITION', document.body.scrollTop + ' : ' + fixLimit);
|
|
if (document.body.scrollTop + 5 >= fixLimit) {
|
|
document
|
|
.querySelector('[role="text-editor-control"]')
|
|
.classList.add('control-freeze');
|
|
} else {
|
|
document
|
|
.querySelector('[role="text-editor-control"]')
|
|
.classList.remove('control-freeze');
|
|
}
|
|
});
|
|
document.getElementById('edit').addEventListener('input', e => {
|
|
let result_element = document.querySelector('#highlight-content');
|
|
this.textEditor = textEditor;
|
|
|
|
// Update code
|
|
let text = e.target.value;
|
|
result_element.innerHTML = text
|
|
.replace(new RegExp('&', 'g'), '&')
|
|
.replace(new RegExp('<', 'g'), '<');
|
|
let editorHeight = document.getElementById('highlight').offsetHeight;
|
|
document.querySelector('[role="edit-post-wrapper"]').style.height =
|
|
editorHeight + 'px';
|
|
e.target.style.height = editorHeight + 30 + 'px'; //TODO: yeah, it's ugly but it works for now, fix soon
|
|
// Syntax Highlight
|
|
Prism.highlightElement(result_element);
|
|
});
|
|
document.getElementById('edit').addEventListener('scroll', e => {
|
|
/* Scroll result to scroll coords of event - sync with textarea */
|
|
let result_element = document.querySelector('#highlight');
|
|
// Get and set x and y
|
|
result_element.scrollTop = e.scrollTop;
|
|
result_element.scrollLeft = e.scrollLeft;
|
|
});
|
|
document.getElementById('edit').dispatchEvent(new Event('input'));
|
|
this.setInputs();
|
|
|
|
//freeze editor formatting so it doesn't scroll off screen
|
|
}
|
|
//--------------------------
|
|
// methods
|
|
//--------------------------
|
|
setInputs() {
|
|
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
|
|
);
|
|
}
|
|
}
|
|
notify(type, data) {
|
|
switch (type) {
|
|
case DataEvent.PAGE_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.PAGE_ADDED:
|
|
// do nothing
|
|
break;
|
|
case EditorEvent.EDITOR_UPLOAD_POST_IMAGE: {
|
|
let len = this.textEditor.value.length;
|
|
let start = this.textEditor.selectionStart;
|
|
let end = this.textEditor.selectionEnd;
|
|
let insert = '![image alt text](' + data + ')';
|
|
|
|
this.textEditor.value =
|
|
this.textEditor.value.substring(0, start) +
|
|
insert +
|
|
this.textEditor.value.substring(end, len);
|
|
document.getElementById('edit').dispatchEvent(new Event('input'));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
//--------------------------
|
|
// event handlers
|
|
//--------------------------
|
|
handleEditorOption(e) {
|
|
e.preventDefault();
|
|
let len = this.textEditor.value.length;
|
|
let start = this.textEditor.selectionStart;
|
|
let end = this.textEditor.selectionEnd;
|
|
|
|
let selectedText = this.textEditor.value.substring(start, end);
|
|
let insert = '';
|
|
switch (e.target.id) {
|
|
case 'edit-bold':
|
|
insert = '**' + selectedText + '**';
|
|
this.textEditor.value =
|
|
this.textEditor.value.substring(0, start) +
|
|
insert +
|
|
this.textEditor.value.substring(end, len);
|
|
|
|
break;
|
|
case 'edit-italic':
|
|
insert = '*' + selectedText + '*';
|
|
//console.log(this.textEditor);
|
|
this.textEditor.value =
|
|
this.textEditor.value.substring(0, start) +
|
|
insert +
|
|
this.textEditor.value.substring(end, len);
|
|
break;
|
|
case 'edit-strikethrough':
|
|
insert = '~~' + selectedText + '~~';
|
|
this.textEditor.value =
|
|
this.textEditor.value.substring(0, start) +
|
|
insert +
|
|
this.textEditor.value.substring(end, len);
|
|
break;
|
|
case 'edit-header1':
|
|
insert = '# ' + selectedText + '\n';
|
|
this.textEditor.value =
|
|
this.textEditor.value.substring(0, start) +
|
|
insert +
|
|
this.textEditor.value.substring(end, len);
|
|
break;
|
|
case 'edit-header2':
|
|
insert = '## ' + selectedText + '\n';
|
|
this.textEditor.value =
|
|
this.textEditor.value.substring(0, start) +
|
|
insert +
|
|
this.textEditor.value.substring(end, len);
|
|
break;
|
|
case 'edit-header3':
|
|
insert = '### ' + selectedText + '\n';
|
|
this.textEditor.value =
|
|
this.textEditor.value.substring(0, start) +
|
|
insert +
|
|
this.textEditor.value.substring(end, len);
|
|
break;
|
|
case 'edit-link':
|
|
{
|
|
let url = prompt("Let's get that url, boss");
|
|
let link = url.toLowerCase();
|
|
insert = '[' + selectedText + '](' + link + ')';
|
|
this.textEditor.value =
|
|
this.textEditor.value.substring(0, start) +
|
|
insert +
|
|
this.textEditor.value.substring(end, len);
|
|
}
|
|
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-delete':
|
|
this.emitEvent(EditorEvent.EDITOR_DELETE);
|
|
break;
|
|
default:
|
|
//do stuff
|
|
break;
|
|
}
|
|
document.getElementById('edit').dispatchEvent(new Event('input'));
|
|
}
|
|
}
|
|
export default TextEditor;
|