246 lines
5.9 KiB
JavaScript
246 lines
5.9 KiB
JavaScript
|
|
import { Webcomponent } from "./webcomponent.js";
|
|
|
|
const baseRows = 1.6;
|
|
|
|
const domElements = {
|
|
input: ".input",
|
|
toolbar: ".toolbar",
|
|
wrapper: ".wrapper",
|
|
boilerplate: ".content"
|
|
};
|
|
|
|
const domReplaceTag = {
|
|
i: "em",
|
|
b: "strong",
|
|
pre: "div"
|
|
};
|
|
|
|
const copyCss = [
|
|
"font", "font-size", "color", "background", "outline"
|
|
];
|
|
|
|
class UiTextarea extends Webcomponent {
|
|
|
|
constructor() {
|
|
super();
|
|
|
|
this.fetch_template();
|
|
this.wrapper = this.shadowRoot.querySelector(domElements.wrapper);
|
|
this.content = this.shadowRoot.querySelector(domElements.boilerplate);
|
|
this.toolbar = this.shadowRoot.querySelector(domElements.toolbar);
|
|
|
|
if ( ! this.textareaInit() ) {
|
|
return;
|
|
}
|
|
|
|
this.toolbarInit();
|
|
this.render();
|
|
}
|
|
|
|
render() {
|
|
document.execCommand("DefaultParagraphSeparator", false, "p");
|
|
|
|
this.content.innerHTML = this.textarea.value.trim();
|
|
|
|
this.content.addEventListener("input", function(e, d) {
|
|
this.content.querySelectorAll('[style]').forEach(function(element) {
|
|
element.removeAttribute('style');
|
|
});
|
|
|
|
this.content.querySelectorAll('[class]').forEach(function(element) {
|
|
element.removeAttribute('class');
|
|
});
|
|
|
|
this.textarea.value = this.content.innerHTML;
|
|
|
|
this.content.dispatchEvent(new Event("change"));
|
|
}.bind(this));
|
|
}
|
|
|
|
actionAlign(value) {
|
|
switch(value) {
|
|
case "left" :
|
|
return document.execCommand('justifyLeft',false,null);
|
|
|
|
case "center" :
|
|
return document.execCommand('justifyCenter',false,null);
|
|
|
|
case "right" :
|
|
return document.execCommand('justifyRight',false,null);
|
|
|
|
case "justify" :
|
|
return document.execCommand('justifyFull',false,null);
|
|
}
|
|
}
|
|
|
|
actionBold(value, content) {
|
|
return document.execCommand('bold', false, null);
|
|
}
|
|
|
|
actionItalic(value, content) {
|
|
return document.execCommand('italic', false, null);
|
|
}
|
|
|
|
actionUnderline() {
|
|
return document.execCommand('underline',false, null);
|
|
}
|
|
|
|
actionStrike() {
|
|
return document.execCommand('strikeThrough',false, null);
|
|
}
|
|
|
|
actionUl() {
|
|
return document.execCommand('insertUnorderedList',false, null);
|
|
}
|
|
|
|
actionOl() {
|
|
return document.execCommand('insertOrderedList',false, null);
|
|
}
|
|
|
|
actionUndo() {
|
|
return document.execCommand('undo', false, null);
|
|
}
|
|
|
|
actionRedo() {
|
|
return document.execCommand('redo', false, null);
|
|
}
|
|
|
|
actionForecolor(color) {
|
|
return document.execCommand('forecolor', false, color);
|
|
}
|
|
|
|
actionLink() {
|
|
|
|
}
|
|
|
|
actionImage() {
|
|
|
|
}
|
|
|
|
actionDocument() {
|
|
|
|
}
|
|
|
|
actionTag(tag) {
|
|
return document.execCommand('formatBlock', false, '<'+tag+'>');
|
|
}
|
|
|
|
toolbarInit() {
|
|
let action = this.getAttribute('toolbar');
|
|
|
|
if ( action !== null ) {
|
|
this.toolbar.setAttribute('action', action);
|
|
}
|
|
|
|
this.toolbar.querySelectorAll('[data-action]:not(.font-color)').forEach(function(item){
|
|
item.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
|
|
let action = item.getAttribute('data-action');
|
|
|
|
return this["action" + action[0].toUpperCase() + action.slice(1)].call(this, item.getAttribute('data-value'), this.content);
|
|
}.bind(this));
|
|
}.bind(this));
|
|
|
|
this.toolbar.querySelectorAll('.font-color').forEach(function(item) {
|
|
item.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
|
|
this.toolbar.querySelector('label[for="colorpicker"]').dispatchEvent(new Event('click'));
|
|
}.bind(this));
|
|
}.bind(this));
|
|
|
|
this.toolbar.querySelector('input[type="color"]').addEventListener('change', function(e) {
|
|
return this.actionForecolor.call(this, e.target.value);
|
|
}.bind(this));
|
|
}
|
|
|
|
textareaInit() {
|
|
if ( ! (this.textarea = this.querySelector("textarea") ) ) {
|
|
// throw "You should have a <textarea> element within a container with slot='input'";
|
|
|
|
this.textarea = document.createElement("textarea");
|
|
this.textarea.innerHTML = this.innerHTML;
|
|
this.append(this.textarea);
|
|
}
|
|
|
|
if ( this.textarea.getAttribute('readonly') ) {
|
|
this.wrapper.classList.add("readonly");
|
|
this.content.removeAttribute('contenteditable');
|
|
}
|
|
|
|
let rows = this.textarea.getAttribute('rows') ;
|
|
|
|
if ( rows ) {
|
|
rows = parseInt(rows);
|
|
this.content.style.minHeight = ( rows * baseRows ) + "em";
|
|
}
|
|
|
|
this.textarea.webcomponent = this;
|
|
|
|
if ( this.classList.contains("lite") ) {
|
|
this.wrapper.classList.add("lite");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
html(html) {
|
|
return html !== undefined ? this.content.innerHTML = html : this.content.innerHTML;
|
|
}
|
|
|
|
text(text) {
|
|
return text !== undefined ? this.content.innerText = text : this.content.innerText;
|
|
}
|
|
|
|
get content() {
|
|
return this._content;
|
|
}
|
|
|
|
set content(value) {
|
|
return this._content = value;
|
|
}
|
|
|
|
get toolbar() {
|
|
return this._toolbar;
|
|
}
|
|
|
|
set toolbar(value) {
|
|
return this._toolbar = value;
|
|
}
|
|
|
|
get textarea() {
|
|
return this._textarea;
|
|
}
|
|
|
|
set textarea(value) {
|
|
return this._textarea = value;
|
|
}
|
|
|
|
get element() {
|
|
return this._element;
|
|
}
|
|
|
|
set element(value) {
|
|
return this._element = value;
|
|
}
|
|
|
|
get wrapper() {
|
|
return this._wrapper;
|
|
}
|
|
|
|
set wrapper(value) {
|
|
return this._wrapper = value;
|
|
}
|
|
|
|
get value() {
|
|
return this.content.innerHTML;
|
|
}
|
|
|
|
set value(value) {
|
|
this.content.innerHTML = value;
|
|
}
|
|
}
|
|
|
|
export { UiTextarea } |