From feb457c087c517511c392715a5b62a71f04e647b Mon Sep 17 00:00:00 2001 From: mukherjeesudebi Date: Fri, 22 Dec 2023 14:16:51 +0200 Subject: [PATCH] added new methods for configuration --- src/main/java/org/vaadin/tinymce/Menubar.java | 21 +++ src/main/java/org/vaadin/tinymce/Plugin.java | 55 +++++++ src/main/java/org/vaadin/tinymce/TinyMce.java | 154 +++++++++++++++--- src/main/java/org/vaadin/tinymce/Toolbar.java | 55 +++++++ .../tinymce/TinyMceWithAdditionalConfig.java | 16 ++ 5 files changed, 276 insertions(+), 25 deletions(-) create mode 100644 src/main/java/org/vaadin/tinymce/Menubar.java create mode 100644 src/main/java/org/vaadin/tinymce/Plugin.java create mode 100644 src/main/java/org/vaadin/tinymce/Toolbar.java create mode 100644 src/test/java/org/vaadin/tinymce/TinyMceWithAdditionalConfig.java diff --git a/src/main/java/org/vaadin/tinymce/Menubar.java b/src/main/java/org/vaadin/tinymce/Menubar.java new file mode 100644 index 0000000..a54a80c --- /dev/null +++ b/src/main/java/org/vaadin/tinymce/Menubar.java @@ -0,0 +1,21 @@ +package org.vaadin.tinymce; + +public enum Menubar { + //@formatter:off + FILE("file"), + EDIT("edit"), + VIEW("view"), + INSERT("insert"), + FORMAT("format"), + TOOLS("tools"), + TABLE("table"), + HELP("help"); + //@formatter:on + + public final String menubarLabel; + + private Menubar(String menubarLabel) { + this.menubarLabel = menubarLabel; + } + +} diff --git a/src/main/java/org/vaadin/tinymce/Plugin.java b/src/main/java/org/vaadin/tinymce/Plugin.java new file mode 100644 index 0000000..9d904be --- /dev/null +++ b/src/main/java/org/vaadin/tinymce/Plugin.java @@ -0,0 +1,55 @@ +package org.vaadin.tinymce; + +public enum Plugin { + //@formatter:off + ADVLIST("advlist"), + ANCHOR("anchor"), + AUTOLINK("autolink"), + AUTORESIZE("autoresize"), + AUTOSAVE("autosave"), + CHARMAP("charmap"), + CODE("code"), + CODESAMPLE("codesample"), + COLORPICKER("colorpicker"), + CONTEXTMENU("contextmenu"), + DIRECTIONALITY("directionality"), + EMOTICONS("emoticons"), + FULLPAGE("fullpage"), + FULLSCREEN("fullscreen"), + HELP("help"), + HR("hr"), + IMAGE("image"), + IMAGE_TOOLS("imagetools"), + IMPORT_CSS("importcss"), + INSERT_DATETIME("insertdatetime"), + LEGACYOUTPUT("legacyoutput"), + LINK("link"), + LISTS("lists"), + MEDIA("media"), + NONBREAKING("nonbreaking"), + NONEDITABLE("noneditable"), + PAGEBREAK("pagebreak"), + PASTE("paste"), + PREVIEW("preview"), + PRINT("print"), + QUICKBARS("quickbars"), + SAVE("save"), + SEARCH_REPLACE("searchreplace"), + SPELLCHECKER("spellchecker"), + TABFOCUS("tabfocus"), + TABLE("table"), + TEMPLATE("template"), + TEXT_COLOR("textcolor"), + TEXT_PATTERN("textpattern"), + VISUAL_BLOCKS("visualblocks"), + VISUAL_CHARS("visualchars"), + WORDCOUNT("wordcount"); + //@formatter:on + + public final String pluginLabel; + + private Plugin(String pluginLabel) { + this.pluginLabel = pluginLabel; + } + +} diff --git a/src/main/java/org/vaadin/tinymce/TinyMce.java b/src/main/java/org/vaadin/tinymce/TinyMce.java index 6ed133a..1a40578 100644 --- a/src/main/java/org/vaadin/tinymce/TinyMce.java +++ b/src/main/java/org/vaadin/tinymce/TinyMce.java @@ -39,6 +39,7 @@ import elemental.json.Json; import elemental.json.JsonArray; import elemental.json.JsonObject; +import elemental.json.JsonValue; import java.util.UUID; @@ -53,7 +54,8 @@ */ @Tag("div") @JavaScript("./tinymceConnector.js") -public class TinyMce extends AbstractCompositeField implements HasSize, Focusable { +public class TinyMce extends AbstractCompositeField + implements HasSize, Focusable { private final DomListenerRegistration domListenerRegistration; private String id; @@ -64,6 +66,7 @@ public class TinyMce extends AbstractCompositeField implem private Element ta = new Element("div"); private int debounceTimeout = 5000; + private boolean basicTinyMCECreated; /** * Creates a new TinyMce editor with shadowroot set or disabled. The shadow @@ -72,7 +75,8 @@ public class TinyMce extends AbstractCompositeField implem * hand, the shadow root must not be on when for example used in inline * mode. * - * @param shadowRoot true of shadow root hack should be used + * @param shadowRoot + * true of shadow root hack should be used */ public TinyMce(boolean shadowRoot) { super(""); @@ -84,19 +88,25 @@ public TinyMce(boolean shadowRoot) { } else { getElement().appendChild(ta); } - domListenerRegistration = getElement().addEventListener("tchange", (DomEventListener) event -> { - boolean value = event.getEventData().hasKey("event.htmlString"); - String htmlString = event.getEventData().getString("event.htmlString"); - currentValue = htmlString; - setModelValue(htmlString, true); - }); + domListenerRegistration = getElement().addEventListener("tchange", + (DomEventListener) event -> { + boolean value = event.getEventData() + .hasKey("event.htmlString"); + String htmlString = event.getEventData() + .getString("event.htmlString"); + currentValue = htmlString; + setModelValue(htmlString, true); + }); domListenerRegistration.addEventData("event.htmlString"); domListenerRegistration.debounce(debounceTimeout); } /** - * Sets the debounce timeout for the value change event. The default is 5000. - * @param debounceTimeout the debounce timeout in milliseconds + * Sets the debounce timeout for the value change event. The default is + * 5000. + * + * @param debounceTimeout + * the debounce timeout in milliseconds */ public void setDebounceTimeout(int debounceTimeout) { this.debounceTimeout = debounceTimeout; @@ -132,7 +142,8 @@ protected void onAttach(AttachEvent attachEvent) { protected void onDetach(DetachEvent detachEvent) { super.onDetach(detachEvent); initialContentSent = false; - // save the current value to the dom element in case the component gets reattached + // save the current value to the dom element in case the component gets + // reattached } @SuppressWarnings("deprecation") @@ -140,8 +151,9 @@ private void initConnector() { this.initialContentSent = true; runBeforeClientResponse(ui -> { - ui.getPage().executeJs("window.Vaadin.Flow.tinymceConnector.initLazy($0, $1, $2, $3)", rawConfig, - getElement(), ta, config); + ui.getPage().executeJs( + "window.Vaadin.Flow.tinymceConnector.initLazy($0, $1, $2, $3)", + rawConfig, getElement(), ta, config); }); } @@ -172,7 +184,6 @@ public TinyMce configure(String configurationKey, String... value) { return this; } - public TinyMce configure(String configurationKey, boolean value) { config.put(configurationKey, value); return this; @@ -186,11 +197,12 @@ public TinyMce configure(String configurationKey, double value) { /** * Replaces text in the editors selection (can be just a caret position). * - * @param htmlString the html snippet to be inserted + * @param htmlString + * the html snippet to be inserted */ public void replaceSelectionContent(String htmlString) { - runBeforeClientResponse(ui -> getElement() - .callJsFunction("$connector.replaceSelectionContent", htmlString)); + runBeforeClientResponse(ui -> getElement().callJsFunction( + "$connector.replaceSelectionContent", htmlString)); } /** @@ -200,30 +212,38 @@ public void replaceSelectionContent(String htmlString) { * version, or own custom script if needed. */ protected void injectTinyMceScript() { - getUI().get().getPage().addJavaScript("context://frontend/tinymce_addon/tinymce/tinymce.min.js"); + getUI().get().getPage().addJavaScript( + "context://frontend/tinymce_addon/tinymce/tinymce.min.js"); } @Override public void focus() { - runBeforeClientResponse(ui -> getElement() - .callJsFunction("$connector.focus")); + runBeforeClientResponse( + ui -> getElement().callJsFunction("$connector.focus")); } @Override - public Registration addFocusListener(ComponentEventListener> listener) { - DomListenerRegistration domListenerRegistration = getElement().addEventListener("tfocus", event -> listener.onComponentEvent(new FocusEvent<>(this, false))); + public Registration addFocusListener( + ComponentEventListener> listener) { + DomListenerRegistration domListenerRegistration = getElement() + .addEventListener("tfocus", event -> listener + .onComponentEvent(new FocusEvent<>(this, false))); return domListenerRegistration; } @Override - public Registration addBlurListener(ComponentEventListener> listener) { - DomListenerRegistration domListenerRegistration = getElement().addEventListener("tblur", event -> listener.onComponentEvent(new BlurEvent<>(this, false))); + public Registration addBlurListener( + ComponentEventListener> listener) { + DomListenerRegistration domListenerRegistration = getElement() + .addEventListener("tblur", event -> listener + .onComponentEvent(new BlurEvent<>(this, false))); return domListenerRegistration; } @Override public void blur() { - throw new RuntimeException("Not implemented, TinyMce does not support programmatic blur."); + throw new RuntimeException( + "Not implemented, TinyMce does not support programmatic blur."); } @Override @@ -244,5 +264,89 @@ protected void setPresentationValue(String t) { setEditorContent(t); } + private TinyMce createBasicTinyMce() { + this.setEditorContent(""); + this.configure("branding", false); + this.basicTinyMCECreated = true; + this.configurePlugin(false, Plugin.ADVLIST, Plugin.AUTOLINK, + Plugin.LISTS, Plugin.SEARCH_REPLACE); + this.configureMenubar(false, Menubar.FILE, Menubar.EDIT, Menubar.VIEW, + Menubar.FORMAT); + this.configureToolbar(false, Toolbar.UNDO, Toolbar.REDO, + Toolbar.SEPARATOR, Toolbar.FORMAT_SELECT, Toolbar.SEPARATOR, + Toolbar.BOLD, Toolbar.ITALIC, Toolbar.SEPARATOR, + Toolbar.ALIGN_LEFT, Toolbar.ALIGN_CENTER, Toolbar.ALIGN_RIGHT, + Toolbar.ALIGN_JUSTIFY, Toolbar.SEPARATOR, Toolbar.OUTDENT, + Toolbar.INDENT); + return this; + + } + + public TinyMce configurePlugin(boolean basicTinyMCE, Plugin... plugins) { + if (basicTinyMCE && !basicTinyMCECreated) { + createBasicTinyMce(); + } + + JsonArray jsonArray = config.get("plugins"); + int initialIndex = 0; + + if (jsonArray != null) { + initialIndex = jsonArray.length(); + } else { + jsonArray = Json.createArray(); + } + + for (int i = 0; i < plugins.length; i++) { + jsonArray.set(initialIndex, plugins[i].pluginLabel); + initialIndex++; + } + + config.put("plugins", jsonArray); + return this; + } + + public TinyMce configureMenubar(boolean basicTinyMCE, Menubar... menubars) { + if (basicTinyMCE && !basicTinyMCECreated) { + createBasicTinyMce(); + } + + JsonArray jsonArray = config.get("menubar"); + int initialIndex = 0; + + if (jsonArray != null) { + initialIndex = jsonArray.length(); + } else { + jsonArray = Json.createArray(); + } + + for (int i = 0; i < menubars.length; i++) { + jsonArray.set(initialIndex, menubars[i].menubarLabel); + initialIndex++; + } + + config.put("menubar", jsonArray); + return this; + } + + public TinyMce configureToolbar(boolean basicTinyMCE, Toolbar... toolbars) { + if (basicTinyMCE && !basicTinyMCECreated) { + createBasicTinyMce(); + } + + JsonValue jsonValue = config.get("toolbar"); + String toolbarStr = ""; + + if (jsonValue != null) { + toolbarStr = toolbarStr.concat(jsonValue.asString()); + } + + for (int i = 0; i < toolbars.length; i++) { + toolbarStr = toolbarStr.concat(" ").concat(toolbars[i].toolbarLabel) + .concat(" "); + } + + config.put("toolbar", toolbarStr); + return this; + } } diff --git a/src/main/java/org/vaadin/tinymce/Toolbar.java b/src/main/java/org/vaadin/tinymce/Toolbar.java new file mode 100644 index 0000000..5589fa5 --- /dev/null +++ b/src/main/java/org/vaadin/tinymce/Toolbar.java @@ -0,0 +1,55 @@ +package org.vaadin.tinymce; + +public enum Toolbar { + //@formatter:off + SEPARATOR("|"), + UNDO("undo"), + REDO("redo"), + FORMAT_SELECT("formatselect"), + BLOCKS("blocks"), + BOLD("bold"), + ITALIC("italic"), + UNDERLINE("underline"), + STRIKETHROUGH("strikethrough"), + FORECOLOR("forecolor"), + BACKCOLOR("backcolor"), + ALIGN_LEFT("alignleft"), + ALIGN_CENTER("aligncenter"), + ALIGN_RIGHT("alignright"), + ALIGN_JUSTIFY("alignjustify"), + FONTNAME("fontname"), + FONTSIZE("fontsize"), + BLOCKQUOTE("blockquote"), + NUMLIST("numlist"), + BULLIST("bullist"), + OUTDENT("outdent"), + INDENT("indent"), + REMOVE_FORMAT("removeformat"), + HELP("help"), + TABLE("table"), + TABLE_DELETE("tabledelete"), + TABLE_PROPS("tableprops"), + TABLE_ROWPROPS("tablerowprops"), + TABLE_CELLPROPS("tablecellprops"), + TABLE_INSERT_ROW_BEFORE("tableinsertrowbefore"), + TABLE_INSERT_ROW_AFTER("tableinsertrowafter"), + TABLE_DELETE_ROW("tabledeleterow"), + TABLE_INSERT_COL_BEFORE("tableinsertcolbefore"), + TABLE_INSERT_COL_AFTER("tableinsertcolafter"), + FONTSELECT("FONTSELECT"), + FONTSIZESELECT("FONTSIZESELECT"), + EMOTICONS("emoticons"), + LINK("link"), + IMAGE("image"), + MEDIA("media"), + PRINT("print"), + INSERT_DATETIME("insertdatetime"); + //@formatter:on + + public final String toolbarLabel; + + private Toolbar(String toolbarLabel) { + this.toolbarLabel = toolbarLabel; + } + +} diff --git a/src/test/java/org/vaadin/tinymce/TinyMceWithAdditionalConfig.java b/src/test/java/org/vaadin/tinymce/TinyMceWithAdditionalConfig.java new file mode 100644 index 0000000..db14868 --- /dev/null +++ b/src/test/java/org/vaadin/tinymce/TinyMceWithAdditionalConfig.java @@ -0,0 +1,16 @@ +package org.vaadin.tinymce; + +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.Route; + +@Route +public class TinyMceWithAdditionalConfig extends VerticalLayout { + + public TinyMceWithAdditionalConfig() { + TinyMce tinyMce = new TinyMce(true); + tinyMce.configurePlugin(true, Plugin.TABLE) + .configureMenubar(true, Menubar.TABLE) + .configureToolbar(true, Toolbar.TABLE); + add(tinyMce); + } +}