233 lines
6.3 KiB
JavaScript
233 lines
6.3 KiB
JavaScript
/**
|
|
* app/js/wysiwyg.js
|
|
*
|
|
* This is css used in the debuging console.
|
|
*
|
|
* @version 3.0
|
|
* @author Joey Kimsey <Joey@thetempusproject.com>
|
|
* @link https://TheTempusProject.com
|
|
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
|
*/
|
|
// define vars
|
|
const editor = document.getElementsByClassName('wp-webdeasy-comment-editor')[0];
|
|
const toolbar = editor.getElementsByClassName('toolbar')[0];
|
|
const buttons = toolbar.querySelectorAll('.editor-btn:not(.has-submenu)');
|
|
const contentArea = editor.getElementsByClassName('content-area')[0];
|
|
const visuellView = contentArea.getElementsByClassName('visuell-view')[0];
|
|
const htmlView = contentArea.getElementsByClassName('html-view')[0];
|
|
const modal = document.getElementsByClassName('modal')[0];
|
|
|
|
// add active tag event
|
|
document.addEventListener('selectionchange', selectionChange);
|
|
|
|
// add paste event
|
|
visuellView.addEventListener('paste', pasteEvent);
|
|
|
|
// add paragraph tag on new line
|
|
contentArea.addEventListener('keypress', addParagraphTag);
|
|
|
|
// add toolbar button actions
|
|
for(let i = 0; i < buttons.length; i++) {
|
|
let button = buttons[i];
|
|
|
|
button.addEventListener('click', function(e) {
|
|
let action = this.dataset.action;
|
|
|
|
switch(action) {
|
|
case 'toggle-view':
|
|
execCodeAction(this, editor);
|
|
break;
|
|
case 'createLink':
|
|
execLinkAction();
|
|
break;
|
|
default:
|
|
execDefaultAction(action);
|
|
}
|
|
|
|
});
|
|
}
|
|
|
|
/**
|
|
* This function toggles between visual and html view
|
|
*/
|
|
function execCodeAction(button, editor) {
|
|
|
|
if(button.classList.contains('active')) { // show visuell view
|
|
visuellView.innerHTML = htmlView.value;
|
|
htmlView.style.display = 'none';
|
|
visuellView.style.display = 'block';
|
|
|
|
button.classList.remove('active');
|
|
} else { // show html view
|
|
htmlView.innerText = visuellView.innerHTML;
|
|
visuellView.style.display = 'none';
|
|
htmlView.style.display = 'block';
|
|
|
|
button.classList.add('active');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This function adds a link to the current selection
|
|
*/
|
|
function execLinkAction() {
|
|
modal.style.display = 'block';
|
|
let selection = saveSelection();
|
|
|
|
let submit = modal.querySelectorAll('button.done')[0];
|
|
let close = modal.querySelectorAll('.close')[0];
|
|
|
|
// done button active => add link
|
|
submit.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
let newTabCheckbox = modal.querySelectorAll('#new-tab')[0];
|
|
let linkInput = modal.querySelectorAll('#linkValue')[0];
|
|
let linkValue = linkInput.value;
|
|
let newTab = newTabCheckbox.checked;
|
|
|
|
restoreSelection(selection);
|
|
|
|
if(window.getSelection().toString()) {
|
|
let a = document.createElement('a');
|
|
a.href = linkValue;
|
|
if(newTab) a.target = '_blank';
|
|
window.getSelection().getRangeAt(0).surroundContents(a);
|
|
}
|
|
|
|
modal.style.display = 'none';
|
|
linkInput.value = '';
|
|
|
|
// deregister modal events
|
|
submit.removeEventListener('click', arguments.callee);
|
|
close.removeEventListener('click', arguments.callee);
|
|
});
|
|
|
|
// close modal on X click
|
|
close.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
let linkInput = modal.querySelectorAll('#linkValue')[0];
|
|
|
|
modal.style.display = 'none';
|
|
linkInput.value = '';
|
|
|
|
// deregister modal events
|
|
submit.removeEventListener('click', arguments.callee);
|
|
close.removeEventListener('click', arguments.callee);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* This function executes all 'normal' actions
|
|
*/
|
|
function execDefaultAction(action) {
|
|
document.execCommand(action, false);
|
|
}
|
|
|
|
/**
|
|
* Saves the current selection
|
|
*/
|
|
function saveSelection() {
|
|
if(window.getSelection) {
|
|
sel = window.getSelection();
|
|
if(sel.getRangeAt && sel.rangeCount) {
|
|
let ranges = [];
|
|
for(var i = 0, len = sel.rangeCount; i < len; ++i) {
|
|
ranges.push(sel.getRangeAt(i));
|
|
}
|
|
return ranges;
|
|
}
|
|
} else if (document.selection && document.selection.createRange) {
|
|
return document.selection.createRange();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Loads a saved selection
|
|
*/
|
|
function restoreSelection(savedSel) {
|
|
if(savedSel) {
|
|
if(window.getSelection) {
|
|
sel = window.getSelection();
|
|
sel.removeAllRanges();
|
|
for(var i = 0, len = savedSel.length; i < len; ++i) {
|
|
sel.addRange(savedSel[i]);
|
|
}
|
|
} else if(document.selection && savedSel.select) {
|
|
savedSel.select();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the current selected format buttons active/inactive
|
|
*/
|
|
function selectionChange(e) {
|
|
|
|
for(let i = 0; i < buttons.length; i++) {
|
|
let button = buttons[i];
|
|
|
|
// don't remove active class on code toggle button
|
|
if(button.dataset.action === 'toggle-view') continue;
|
|
|
|
button.classList.remove('active');
|
|
}
|
|
|
|
if(!childOf(window.getSelection().anchorNode.parentNode, editor)) return false;
|
|
|
|
parentTagActive(window.getSelection().anchorNode.parentNode);
|
|
}
|
|
|
|
/**
|
|
* Checks if the passed child has the passed parent
|
|
*/
|
|
function childOf(child, parent) {
|
|
return parent.contains(child);
|
|
}
|
|
|
|
/**
|
|
* Sets the tag active that is responsible for the current element
|
|
*/
|
|
function parentTagActive(elem) {
|
|
if(!elem ||!elem.classList || elem.classList.contains('visuell-view')) return false;
|
|
|
|
let toolbarButton;
|
|
|
|
// active by tag names
|
|
let tagName = elem.tagName.toLowerCase();
|
|
toolbarButton = document.querySelectorAll(`.toolbar .editor-btn[data-tag-name="${tagName}"]`)[0];
|
|
if(toolbarButton) {
|
|
toolbarButton.classList.add('active');
|
|
}
|
|
|
|
// active by text-align
|
|
let textAlign = elem.style.textAlign;
|
|
toolbarButton = document.querySelectorAll(`.toolbar .editor-btn[data-style="textAlign:${textAlign}"]`)[0];
|
|
if(toolbarButton) {
|
|
toolbarButton.classList.add('active');
|
|
}
|
|
|
|
return parentTagActive(elem.parentNode);
|
|
}
|
|
|
|
/**
|
|
* Handles the paste event and removes all HTML tags
|
|
*/
|
|
function pasteEvent(e) {
|
|
e.preventDefault();
|
|
|
|
let text = (e.originalEvent || e).clipboardData.getData('text/plain');
|
|
document.execCommand('insertHTML', false, text);
|
|
}
|
|
|
|
/**
|
|
* This functions adds a paragraph tag when the enter key is pressed
|
|
*/
|
|
function addParagraphTag(evt) {
|
|
if (evt.keyCode == '13') {
|
|
|
|
// don't add a p tag on list item
|
|
if(window.getSelection().anchorNode.parentNode.tagName === 'LI') return;
|
|
document.execCommand('formatBlock', false, 'p');
|
|
}
|
|
} |