You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Fipamo/src/com/ui/TextEditor.js

195 lines
6.1 KiB
JavaScript

import * as DataEvent from '../events/DataEvent';
import { position } from 'caret-pos';
import EventEmitter from '../events/EventEmitter';
import * as EditorEvent from '../events/EditorEvent';
import Prism from 'prismjs';
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.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'), '&lt;');
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
window.addEventListener('scroll', () => {
var fixLimit = scrollLimit;
if (window.pageYOffset + 5 >= fixLimit) {
document.getElementById('edit-control').style.position = 'fixed';
} else {
document.getElementById('edit-control').style.position = 'relative';
}
});
}
//--------------------------
// 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;