All Downloads are FREE. Search and download functionalities are using the official Maven repository.

META-INF.frontend.uibuilder-rich-text-editor.src.uibuilder-rich-text-editor.js Maven / Gradle / Ivy

The newest version!
/*
 *
 * Copyright © 2018 Webvalto Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
import Quill from 'quill';

export class UibuilderRichTextEditor extends ElementMixin(ThemableMixin(PolymerElement)) {

    static get template() {
        return html`
            
            
[[errorMessage]]
`; } static get is() { return "uibuilder-rich-text-editor" } static get properties() { return { value: { type: String, value: "", notify: true, observer: "_onValueChange" }, readonly: { type: Boolean, value: false, notify: true, observer: "_onReadonlyChange" }, label: { type: String, value: null, notify: true }, invalid: { type: Boolean, value: false, notify: true }, errorMessage: { type: String, value: null, notify: true }, formatter: { type: String, value: "HTML", notify: true }, /** * possible html render modes: "backend", "frontend" */ htmlRenderMode: { type: String, value: "frontend", notify: true }, /** * possible value modes: "html", "plain", "delta", "formatted" */ valueMode: { type: String, value: "html", notify: true } }; } constructor() { super(); this.editorContainer = document.createElement('div'); } connectedCallback() { super.connectedCallback(); this.prepend(this.editorContainer); this.initEditor(this.editorContainer); } initEditor(element) { const configNodes = this._collectConfigurationNodes(); let quillConfig = {} configNodes.forEach(configNode => configNode.preConfig(quillConfig)); if (!quillConfig.theme) { Object.assign(quillConfig, { theme: "snow" }); } this.quillEditor = new Quill(element, quillConfig); configNodes.forEach(configNode => configNode.postConfig(this.quillEditor)); this.quillEditor.on("text-change", (change, oldDelta, source) => { if (source === "user") { this._onQuillChange(change); } }); this._onReadonlyChange(); } _collectConfigurationNodes() { let configNodes = []; this.shadowRoot.querySelectorAll("slot") .forEach(slotNode => { slotNode.assignedNodes() .filter(node => node instanceof UibuilderRichTextEditorConfig) .forEach(configNode => { configNodes.push(configNode); }); }); return configNodes; } _onReadonlyChange() { if (this.quillEditor) { this.quillEditor.readonly = this.readonly; } } _isValueChangeBackendDriven() { if (this.hasAttribute("item-bind")) { const itemBind = this.getAttribute("item-bind"); return itemBind.startsWith("selected:") || itemBind.startsWith("backend:"); } return false; } _onQuillChange(delta) { const html = this.htmlRenderMode === 'frontend' ? this.quillEditor.root.innerHTML : null; const reset = this.valueReset ? this.valueReset : false; this.valueReset = false; this._apiValueChange(() => { if (this._isValueChangeBackendDriven()) { this.dispatchEvent(new CustomEvent("changed")); } else { if (this.valueMode === 'plain') { this.value = this.quillEditor.getText(); } else if (this.valueMode === 'html') { this.value = this.quillEditor.root.innerHTML; } else if (this.valueMode === 'delta') { this.value = JSON.stringify(this.quillEditor.getContents().ops); } } }); this.dispatchEvent(new CustomEvent("delta", { detail: { ops: delta, html: html, reset: reset } })); } _apiValueChange(skipValueChange) { this._apiValueChangeActive = true; skipValueChange(); this._apiValueChangeActive = false; } _onValueChange(value, oldValue) { if (!this._apiValueChangeActive && this.quillEditor) { if (this.valueMode === 'plain') { this.setValueAsPlainText(this.value); } else if (this.valueMode === 'html') { this.setValueAsHtmlText(this.value); } else if (this.valueMode === 'delta') { this.setValueAsOps(JSON.parse(this.value)); } } } _silentClear() { this.valueReset = true; this.quillEditor.setText("", "silent"); } setValueAsHtmlText(htmlText) { this._silentClear(); this.quillEditor.root.innerHTML = htmlText; } setValueAsPlainText(plainText) { this._silentClear(); this.quillEditor.setText(plainText, "user"); } setValueAsOps(ops) { this._silentClear(); this.quillEditor.setContents(ops, "user"); } } export class UibuilderRichTextEditorConfig extends ElementMixin(PolymerElement) { preConfig(config) { } postConfig(quill) { } } customElements.define(UibuilderRichTextEditor.is, UibuilderRichTextEditor);




© 2015 - 2024 Weber Informatics LLC | Privacy Policy