From 769d38f422b9193da0ab8d4385890a11dd70a210 Mon Sep 17 00:00:00 2001 From: Martin Lopez Date: Fri, 27 Sep 2024 18:56:18 -0300 Subject: [PATCH] feat: initial implementation --- .github/ISSUE_TEMPLATE/bug-report.yml | 2 +- .github/ISSUE_TEMPLATE/feature-request.yml | 2 +- README.md | 49 +++- pom.xml | 28 ++- .../markdown/BaseMarkdownComponent.java | 96 ++++++++ .../addons/markdown/MarkdownEditor.java | 88 +++++++ .../addons/markdown/MarkdownViewer.java | 52 ++++ .../styles/markdown-editor-styles.css} | 33 +-- .../frontend/styles/static_addon_styles | 1 - .../resources/frontend/markdown-editor.tsx | 105 ++++++++ .../resources/frontend/markdown-viewer.tsx | 95 ++++++++ .../META-INF/resources/static_addon_resources | 1 - .../flowingcode/vaadin/addons/DemoLayout.java | 6 +- .../{template => markdown}/DemoView.java | 10 +- .../MarkdownDemoView.java} | 19 +- .../addons/markdown/MarkdownEditorDemo.java | 63 +++++ .../addons/markdown/MarkdownViewerDemo.java | 226 ++++++++++++++++++ .../it/AbstractViewTest.java | 8 +- .../addons/markdown/it/MarkdownEditorIT.java | 40 ++++ .../addons/markdown/it/MarkdownViewerIT.java | 40 ++++ .../test/SerializationTest.java | 14 +- .../vaadin/addons/template/TemplateDemo.java | 17 -- .../vaadin/addons/template/it/ViewIT.java | 64 ----- .../frontend/styles/shared-styles.css | 21 +- 24 files changed, 931 insertions(+), 149 deletions(-) create mode 100644 src/main/java/com/flowingcode/vaadin/addons/markdown/BaseMarkdownComponent.java create mode 100644 src/main/java/com/flowingcode/vaadin/addons/markdown/MarkdownEditor.java create mode 100644 src/main/java/com/flowingcode/vaadin/addons/markdown/MarkdownViewer.java rename src/main/{java/com/flowingcode/vaadin/addons/template/TemplateAddon.java => resources/META-INF/frontend/styles/markdown-editor-styles.css} (57%) delete mode 100644 src/main/resources/META-INF/frontend/styles/static_addon_styles create mode 100644 src/main/resources/META-INF/resources/frontend/markdown-editor.tsx create mode 100644 src/main/resources/META-INF/resources/frontend/markdown-viewer.tsx delete mode 100644 src/main/resources/META-INF/resources/static_addon_resources rename src/test/java/com/flowingcode/vaadin/addons/{template => markdown}/DemoView.java (88%) rename src/test/java/com/flowingcode/vaadin/addons/{template/TemplateDemoView.java => markdown/MarkdownDemoView.java} (74%) create mode 100644 src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownEditorDemo.java create mode 100644 src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownViewerDemo.java rename src/test/java/com/flowingcode/vaadin/addons/{template => markdown}/it/AbstractViewTest.java (97%) create mode 100644 src/test/java/com/flowingcode/vaadin/addons/markdown/it/MarkdownEditorIT.java create mode 100644 src/test/java/com/flowingcode/vaadin/addons/markdown/it/MarkdownViewerIT.java rename src/test/java/com/flowingcode/vaadin/addons/{template => markdown}/test/SerializationTest.java (83%) delete mode 100644 src/test/java/com/flowingcode/vaadin/addons/template/TemplateDemo.java delete mode 100644 src/test/java/com/flowingcode/vaadin/addons/template/it/ViewIT.java diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index f804cc1..16bd491 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -1,5 +1,5 @@ name: Bug Report -description: Please report issues related to TEMPLATE_ADDON here. +description: Please report issues related to Markdown Editor add-on here. body: - type: textarea id: problem-description diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml index 4d37c3b..0408a49 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.yml +++ b/.github/ISSUE_TEMPLATE/feature-request.yml @@ -1,5 +1,5 @@ name: Feature Request -description: Please add feature suggestions related to TEMPLATE_ADDON here. +description: Please add feature suggestions related to Markdown Editor add-on here. body: - type: textarea id: feature-proposal diff --git a/README.md b/README.md index 76d07e4..f92a589 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,26 @@ -[![Published on Vaadin Directory](https://img.shields.io/badge/Vaadin%20Directory-published-00b4f0.svg)](https://vaadin.com/directory/component/template-addon) -[![Stars on vaadin.com/directory](https://img.shields.io/vaadin-directory/star/template-addon.svg)](https://vaadin.com/directory/component/template-addon) -[![Build Status](https://jenkins.flowingcode.com/job/template-addon/badge/icon)](https://jenkins.flowingcode.com/job/template-addon) -[![Maven Central](https://img.shields.io/maven-central/v/com.flowingcode.vaadin.addons/template-addon)](https://mvnrepository.com/artifact/com.flowingcode.vaadin.addons/template-addon) +[![Published on Vaadin Directory](https://img.shields.io/badge/Vaadin%20Directory-published-00b4f0.svg)](https://vaadin.com/directory/component/markdown-editor-add-on) +[![Stars on vaadin.com/directory](https://img.shields.io/vaadin-directory/star/markdown-editor-addon.svg)](https://vaadin.com/directory/component/markdown-editor-add-on) +[![Build Status](https://jenkins.flowingcode.com/job/markdown-editor-addon/badge/icon)](https://jenkins.flowingcode.com/job/MarkdownEditor-addon) +[![Maven Central](https://img.shields.io/maven-central/v/com.flowingcode.vaadin.addons/markdown-editor-addon)](https://mvnrepository.com/artifact/com.flowingcode.vaadin.addons/markdown-editor-addon) +[![Javadoc](https://img.shields.io/badge/javadoc-00b4f0)](https://javadoc.flowingcode.com/artifact/com.flowingcode.vaadin.addons/markdown-editor-addon) -# Template Add-on +# Markdown Editor Add-on -This is a template project for building new Vaadin 24 add-ons +This is a wrapper around [the React Markdown Editor component](https://github.com/uiwjs/react-md-editor). ## Features -* List the features of your add-on in here +* Supports both visual editing of markdown and also just viewing markdown content +* Support for dark and light themes +* Built in support for sanitization ## Online demo -[Online demo here](http://addonsv24.flowingcode.com/template) +[Online demo here](http://addonsv24.flowingcode.com/markdown-editor) ## Download release -[Available in Vaadin Directory](https://vaadin.com/directory/component/template-addon) +[Available in Vaadin Directory](https://vaadin.com/directory/component/markdown-editor-add-on) ### Maven install @@ -26,7 +29,7 @@ Add the following dependencies in your pom.xml file: ```xml com.flowingcode.vaadin.addons - template-addon + markdown-editor-addon X.Y.Z ``` @@ -43,7 +46,7 @@ To see the demo, navigate to http://localhost:8080/ ## Release notes -See [here](https://github.com/FlowingCode/TemplateAddon/releases) +See [here](https://github.com/FlowingCode/MarkdownEditor/releases) ## Issue tracking @@ -68,13 +71,33 @@ Then, follow these steps for creating a contribution: This add-on is distributed under Apache License 2.0. For license terms, see LICENSE.txt. -TEMPLATE_ADDON is written by Flowing Code S.A. +Markdown Editor Add-on is written by Flowing Code S.A. # Developer Guide ## Getting started -Add your code samples in this section +### Markdown Viewer + +To use the viewer, instantiate it and add it to a view like this: + + MarkdownViewer mdv = new MarkdownViewer(); + mdv.setSizeFull(); + mdv.setDataColorMode(DataColorMode.LIGTH); + mdv.setContent("# h1 Heading"); + add(mdv); + +### Markdown Editor + +To use the editor, similar to the viewer, instantiate it and add it to a view like this: + + MarkdownEditor mde = new MarkdownEditor(); + mde.setSizeFull(); + mde.setPlaceholder("Enter Markdown here"); + mde.setMaxLength(500); + mde.setDataColorMode(DataColorMode.LIGTH); + +To obtain the edited value, call `getContent()` ## Special configuration when using Spring diff --git a/pom.xml b/pom.xml index 431cb5a..6fd8d63 100644 --- a/pom.xml +++ b/pom.xml @@ -5,10 +5,10 @@ 4.0.0 com.flowingcode.vaadin.addons - template-addon + markdown-editor-addon 1.0.0-SNAPSHOT - Template Add-on - Template Add-on for Vaadin Flow + Markdown Editor Add-on + Markdown Editor for Vaadin Flow https://www.flowingcode.com/en/open-source/ @@ -39,9 +39,9 @@ - https://github.com/FlowingCode/AddonStarter24 - scm:git:git://github.com/FlowingCode/AddonStarter24.git - scm:git:ssh://git@github.com:/FlowingCode/AddonStarter24.git + https://github.com/FlowingCode/MarkdownEditor + scm:git:git://github.com/FlowingCode/MarkdownEditor.git + scm:git:ssh://git@github.com:/FlowingCode/MarkdownEditor.git master @@ -126,6 +126,7 @@ com.flowingcode.vaadin.addons.demo commons-demo ${flowingcode.commons.demo.version} + test org.slf4j @@ -226,8 +227,14 @@ apache_v2 false - **/dev-bundle/** + **/main/dev-bundle/** + **/main/bundles/** + **/main/frontend/** + **/main/frontend/** + + java + @@ -293,7 +300,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.0.1 + 3.10.0 attach-javadocs @@ -306,7 +313,10 @@ true none - -Xdoclint:none + true + + https://javadoc.io/doc/com.vaadin/vaadin-platform-javadoc/${vaadin.version} + diff --git a/src/main/java/com/flowingcode/vaadin/addons/markdown/BaseMarkdownComponent.java b/src/main/java/com/flowingcode/vaadin/addons/markdown/BaseMarkdownComponent.java new file mode 100644 index 0000000..97c8d9b --- /dev/null +++ b/src/main/java/com/flowingcode/vaadin/addons/markdown/BaseMarkdownComponent.java @@ -0,0 +1,96 @@ +/*- + * #%L + * Markdown Editor Add-on + * %% + * Copyright (C) 2024 Flowing Code + * %% + * 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. + * #L% + */ +package com.flowingcode.vaadin.addons.markdown; + +import com.vaadin.flow.component.HasSize; +import com.vaadin.flow.component.dependency.CssImport; +import com.vaadin.flow.component.dependency.NpmPackage; +import com.vaadin.flow.component.react.ReactAdapterComponent; + +/** + * Base class for Markdown based Components. + */ +@SuppressWarnings("serial") +@CssImport("./styles/markdown-editor-styles.css") +@NpmPackage(value = "mermaid", version = "11.2.1") +@NpmPackage(value = "@uiw/react-md-editor", version = "4.0.4") +@NpmPackage(value = "dompurify", version = "3.1.6") +public class BaseMarkdownComponent extends ReactAdapterComponent implements HasSize { + + /** + * Defines the color schemes for the Markdown component. + * + * The color mode can be set using the {@link #setDataColorMode(DataColorMode)} method. + * + *
    + *
  • {@link #DARK}: Dark color scheme. + *
  • {@link #LIGTH}: Light color scheme. + *
  • {@link #AUTO}: Automatically detects the color scheme based on the user's system settings. + *
+ */ + public enum DataColorMode {DARK,LIGTH,AUTO}; + + /** + * Base constructor that receives the content of the markdown component. + * + * @param content content to be used in the Markdown component + */ + public BaseMarkdownComponent(String content) { + setContent(content); + } + + /** + * Sets the content of the Markdown component. + * + * @return the content of the Markdown component + */ + public String getContent() { + return getState("content", String.class); + } + + /** + * Gets the content of the Markdown component. + * + * @param content retrieved from the state of the component + */ + public void setContent(String content) { + setState("content", content); + } + + /** + * Sets the color mode of the Markdown component. + * + * @param mode the color mode of the component + */ + public void setDataColorMode(DataColorMode mode) { + switch (mode) { + case DARK: + getElement().setAttribute("data-color-mode", "dark"); + break; + case LIGTH: + getElement().setAttribute("data-color-mode", "light"); + break; + case AUTO: + getElement().removeAttribute("data-color-mode"); + break; + } + } + +} diff --git a/src/main/java/com/flowingcode/vaadin/addons/markdown/MarkdownEditor.java b/src/main/java/com/flowingcode/vaadin/addons/markdown/MarkdownEditor.java new file mode 100644 index 0000000..0491822 --- /dev/null +++ b/src/main/java/com/flowingcode/vaadin/addons/markdown/MarkdownEditor.java @@ -0,0 +1,88 @@ +/*- + * #%L + * Markdown Editor Add-on + * %% + * Copyright (C) 2024 Flowing Code + * %% + * 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. + * #L% + */ + +package com.flowingcode.vaadin.addons.markdown; + +import com.vaadin.flow.component.Tag; +import com.vaadin.flow.component.dependency.JsModule; +import com.vaadin.flow.component.dependency.NpmPackage; + +/** + * Markdown component that allows editing the contents. + */ +@SuppressWarnings("serial") +@NpmPackage(value = "rehype-sanitize", version = "6.0.0") +@JsModule("./markdown-editor.tsx") +@Tag("markdown-editor") +public class MarkdownEditor extends BaseMarkdownComponent { + + /** + * Constructor with empty content. + */ + public MarkdownEditor() { + super(null); + } + + /** + * Constructor with default content. + * + * @param content default content for the Markdown editor + */ + public MarkdownEditor(String content) { + super(content); + } + + /** + * Returns the placeholder text for the Markdown editor. + * + * @return the placeholder text + */ + public String getPlaceholder() { + return getState("placeholder", String.class); + } + + /** + * Sets the placeholder text for the Markdown editor. + * + * @param placeholder the placeholder text + */ + public void setPlaceholder(String placeholder) { + setState("placeholder", placeholder); + } + + /** + * Returns the configured maximum character count for the Markdown editor. + * + * @return the configured maximum character count + */ + public int getMaxLength() { + return getState("maxLength", Integer.class); + } + + /** + * Sets the maximum character count for the Markdown editor. + * + * @param maxlength the maximum character count + */ + public void setMaxLength(int maxlength) { + setState("maxLength", maxlength); + } + +} diff --git a/src/main/java/com/flowingcode/vaadin/addons/markdown/MarkdownViewer.java b/src/main/java/com/flowingcode/vaadin/addons/markdown/MarkdownViewer.java new file mode 100644 index 0000000..2904335 --- /dev/null +++ b/src/main/java/com/flowingcode/vaadin/addons/markdown/MarkdownViewer.java @@ -0,0 +1,52 @@ +/*- + * #%L + * Markdown Editor Add-on + * %% + * Copyright (C) 2024 Flowing Code + * %% + * 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. + * #L% + */ + +package com.flowingcode.vaadin.addons.markdown; + +import com.vaadin.flow.component.Tag; +import com.vaadin.flow.component.dependency.JsModule; +import com.vaadin.flow.component.dependency.NpmPackage; +import com.vaadin.flow.component.react.ReactAdapterComponent; + +/** + * Component for displaying Markdown text + */ +@SuppressWarnings("serial") +@JsModule("./markdown-viewer.tsx") +@Tag("markdown-viewer") +public class MarkdownViewer extends BaseMarkdownComponent { + + /** + * Constructor with empty content. + */ + public MarkdownViewer() { + super(""); + } + + /** + * Constructor that receives the default content. + * + * @param content default content for the Markdown Viewer + */ + public MarkdownViewer(String content) { + super(content); + } + +} diff --git a/src/main/java/com/flowingcode/vaadin/addons/template/TemplateAddon.java b/src/main/resources/META-INF/frontend/styles/markdown-editor-styles.css similarity index 57% rename from src/main/java/com/flowingcode/vaadin/addons/template/TemplateAddon.java rename to src/main/resources/META-INF/frontend/styles/markdown-editor-styles.css index c9ec694..59a1abf 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/template/TemplateAddon.java +++ b/src/main/resources/META-INF/frontend/styles/markdown-editor-styles.css @@ -1,15 +1,15 @@ /*- * #%L - * Template Add-on + * Markdown Editor Add-on * %% * Copyright (C) 2024 Flowing Code * %% * 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. @@ -17,16 +17,21 @@ * limitations under the License. * #L% */ +.w-md-editor-text { + height:100%; +} +.w-md-editor-text textarea { + height:100%; +} -package com.flowingcode.vaadin.addons.template; +.w-md-editor { + height: calc(100% - 3px) !important; + width: calc(100% - 2px) !important; + top: 1px; + left: 1px; +} -import com.vaadin.flow.component.Tag; -import com.vaadin.flow.component.dependency.JsModule; -import com.vaadin.flow.component.dependency.NpmPackage; -import com.vaadin.flow.component.html.Div; - -@SuppressWarnings("serial") -@NpmPackage(value = "@polymer/paper-input", version = "3.2.1") -@JsModule("@polymer/paper-input/paper-input.js") -@Tag("paper-input") -public class TemplateAddon extends Div {} +.wmde-markdown { + overflow: auto; + height: 100%; +} diff --git a/src/main/resources/META-INF/frontend/styles/static_addon_styles b/src/main/resources/META-INF/frontend/styles/static_addon_styles deleted file mode 100644 index c2a6ed1..0000000 --- a/src/main/resources/META-INF/frontend/styles/static_addon_styles +++ /dev/null @@ -1 +0,0 @@ -Place add-on shareable styles in this folder \ No newline at end of file diff --git a/src/main/resources/META-INF/resources/frontend/markdown-editor.tsx b/src/main/resources/META-INF/resources/frontend/markdown-editor.tsx new file mode 100644 index 0000000..3a46823 --- /dev/null +++ b/src/main/resources/META-INF/resources/frontend/markdown-editor.tsx @@ -0,0 +1,105 @@ +/*- + * #%L + * Markdown Editor Add-on + * %% + * Copyright (C) 2024 Flowing Code + * %% + * 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. + * #L% + */ +import {type ReactElement} from 'react'; +import { + useState, + useRef, + Fragment, + useEffect, + useCallback +} from "react"; +import ReactDOM from "react-dom"; +import MDEditor from '@uiw/react-md-editor/nohighlight'; +import {ReactAdapterElement, type RenderHooks} from "Frontend/generated/flow/ReactAdapter"; +import React from 'react'; +import "@uiw/react-md-editor/markdown-editor.css"; +import "@uiw/react-markdown-preview/markdown.css"; +import rehypeSanitize from "rehype-sanitize"; +import mermaid from "mermaid"; +import { getCodeString } from "rehype-rewrite"; + +const randomid = () => parseInt(String(Math.random() * 1e15), 10).toString(36); +const Code = ({ inline, children = [], className, ...props }) => { + const demoid = useRef(`dome${randomid()}`); + const [container, setContainer] = useState(null); + const isMermaid = + className && /^language-mermaid/.test(className.toLocaleLowerCase()); + const code = children + ? getCodeString(props.node.children) + : children[0] || ""; + + useEffect(() => { + if (container && isMermaid && demoid.current && code) { + mermaid + .render(demoid.current, code) + .then(({ svg, bindFunctions }) => { + container.innerHTML = svg; + if (bindFunctions) { + bindFunctions(container); + } + }) + .catch((error) => { + console.log("error:", error); + }); + } + }, [container, isMermaid, code, demoid]); + + const refElement = useCallback((node) => { + if (node !== null) { + setContainer(node); + } + }, []); + + if (isMermaid) { + return ( + + + + + ); + } + return {children}; +}; + +class MarkdownEditorElement extends ReactAdapterElement { + + protected override render(hooks: RenderHooks): ReactElement | null { + const [content, setContent] = hooks.useState("content"); + const [placeholder] = hooks.useState("placeholder"); + const [maxLength] = hooks.useState("maxLength"); + + return ; + } +} + +customElements.define("markdown-editor",MarkdownEditorElement); diff --git a/src/main/resources/META-INF/resources/frontend/markdown-viewer.tsx b/src/main/resources/META-INF/resources/frontend/markdown-viewer.tsx new file mode 100644 index 0000000..458dd84 --- /dev/null +++ b/src/main/resources/META-INF/resources/frontend/markdown-viewer.tsx @@ -0,0 +1,95 @@ +/*- + * #%L + * Markdown Editor Add-on + * %% + * Copyright (C) 2024 Flowing Code + * %% + * 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. + * #L% + */ +import {type ReactElement} from 'react'; +import { + useState, + useRef, + Fragment, + useEffect, + useCallback +} from "react"; + + +import MDEditor from "@uiw/react-md-editor"; +import {ReactAdapterElement, type RenderHooks} from "Frontend/generated/flow/ReactAdapter"; +import React from 'react'; +import "@uiw/react-md-editor/markdown-editor.css"; +import "@uiw/react-markdown-preview/markdown.css"; +import rehypeSanitize from "rehype-sanitize"; +import mermaid from "mermaid"; +import { getCodeString } from "rehype-rewrite"; + +const randomid = () => parseInt(String(Math.random() * 1e15), 10).toString(36); +const Code = ({ inline, children = [], className, ...props }) => { + const demoid = useRef(`dome${randomid()}`); + const [container, setContainer] = useState(null); + const isMermaid = + className && /^language-mermaid/.test(className.toLocaleLowerCase()); + const code = children + ? getCodeString(props.node.children) + : children[0] || ""; + + useEffect(() => { + if (container && isMermaid && demoid.current && code) { + mermaid + .render(demoid.current, code) + .then(({ svg, bindFunctions }) => { + container.innerHTML = svg; + if (bindFunctions) { + bindFunctions(container); + } + }) + .catch((error) => { + console.log("error:", error); + }); + } + }, [container, isMermaid, code, demoid]); + + const refElement = useCallback((node) => { + if (node !== null) { + setContainer(node); + } + }, []); + + if (isMermaid) { + return ( + + + + + ); + } + return {children}; +}; + + +class MarkdownViewerElement extends ReactAdapterElement { + + protected override render(hooks: RenderHooks): ReactElement | null { + const [content] = hooks.useState("content"); + + return ; + } +} + +customElements.define("markdown-viewer",MarkdownViewerElement); diff --git a/src/main/resources/META-INF/resources/static_addon_resources b/src/main/resources/META-INF/resources/static_addon_resources deleted file mode 100644 index 70832cc..0000000 --- a/src/main/resources/META-INF/resources/static_addon_resources +++ /dev/null @@ -1 +0,0 @@ -Place static add-on resources in this folder \ No newline at end of file diff --git a/src/test/java/com/flowingcode/vaadin/addons/DemoLayout.java b/src/test/java/com/flowingcode/vaadin/addons/DemoLayout.java index b84172e..03fd608 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/DemoLayout.java +++ b/src/test/java/com/flowingcode/vaadin/addons/DemoLayout.java @@ -1,15 +1,15 @@ /*- * #%L - * Template Add-on + * Markdown Editor Add-on * %% * Copyright (C) 2024 Flowing Code * %% * 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. diff --git a/src/test/java/com/flowingcode/vaadin/addons/template/DemoView.java b/src/test/java/com/flowingcode/vaadin/addons/markdown/DemoView.java similarity index 88% rename from src/test/java/com/flowingcode/vaadin/addons/template/DemoView.java rename to src/test/java/com/flowingcode/vaadin/addons/markdown/DemoView.java index a600c9d..89a8b80 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/template/DemoView.java +++ b/src/test/java/com/flowingcode/vaadin/addons/markdown/DemoView.java @@ -1,15 +1,15 @@ /*- * #%L - * Template Add-on + * Markdown Editor Add-on * %% * Copyright (C) 2024 Flowing Code * %% * 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. @@ -18,7 +18,7 @@ * #L% */ -package com.flowingcode.vaadin.addons.template; +package com.flowingcode.vaadin.addons.markdown; import com.vaadin.flow.component.orderedlayout.VerticalLayout; import com.vaadin.flow.router.BeforeEnterEvent; @@ -31,6 +31,6 @@ public class DemoView extends VerticalLayout implements BeforeEnterObserver { @Override public void beforeEnter(BeforeEnterEvent event) { - event.forwardTo(TemplateDemoView.class); + event.forwardTo(MarkdownDemoView.class); } } diff --git a/src/test/java/com/flowingcode/vaadin/addons/template/TemplateDemoView.java b/src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownDemoView.java similarity index 74% rename from src/test/java/com/flowingcode/vaadin/addons/template/TemplateDemoView.java rename to src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownDemoView.java index 1954535..981741f 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/template/TemplateDemoView.java +++ b/src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownDemoView.java @@ -1,15 +1,15 @@ /*- * #%L - * Template Add-on + * Markdown Editor Add-on * %% * Copyright (C) 2024 Flowing Code * %% * 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. @@ -17,7 +17,7 @@ * limitations under the License. * #L% */ -package com.flowingcode.vaadin.addons.template; +package com.flowingcode.vaadin.addons.markdown; import com.flowingcode.vaadin.addons.DemoLayout; import com.flowingcode.vaadin.addons.GithubLink; @@ -27,12 +27,13 @@ @SuppressWarnings("serial") @ParentLayout(DemoLayout.class) -@Route("template") -@GithubLink("https://github.com/FlowingCode/AddonStarter24") -public class TemplateDemoView extends TabbedDemo { +@Route("markdown-editor") +@GithubLink("https://github.com/FlowingCode/MarkdownEditor") +public class MarkdownDemoView extends TabbedDemo { - public TemplateDemoView() { - addDemo(TemplateDemo.class); + public MarkdownDemoView() { + addDemo(MarkdownViewerDemo.class); + addDemo(MarkdownEditorDemo.class); setSizeFull(); } } diff --git a/src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownEditorDemo.java b/src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownEditorDemo.java new file mode 100644 index 0000000..61ad7cd --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownEditorDemo.java @@ -0,0 +1,63 @@ +/*- + * #%L + * Markdown Editor Add-on + * %% + * Copyright (C) 2024 Flowing Code + * %% + * 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. + * #L% + */ +package com.flowingcode.vaadin.addons.markdown; + +import com.flowingcode.vaadin.addons.demo.DemoSource; +import com.flowingcode.vaadin.addons.markdown.BaseMarkdownComponent.DataColorMode; +import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; + +@DemoSource +@PageTitle("Markdown Editor Demo") +@SuppressWarnings("serial") +@Route(value = "markdown-editor/editor-demo", layout = MarkdownDemoView.class) +public class MarkdownEditorDemo extends VerticalLayout { + + public MarkdownEditorDemo() { + setSizeFull(); + MarkdownEditor mde = new MarkdownEditor(); + mde.setSizeFull(); + mde.setPlaceholder("Enter Markdown here"); + mde.setMaxLength(500); + mde.setDataColorMode(DataColorMode.LIGTH); + ComboBox cb = new ComboBox(); + cb.setItems("Dark","Light","Automatic"); + cb.setLabel("Color mode"); + cb.setValue("Light"); + cb.addValueChangeListener(ev->{ + switch(ev.getValue()) { + case "Dark": + mde.setDataColorMode(DataColorMode.DARK); + break; + case "Light": + mde.setDataColorMode(DataColorMode.LIGTH); + break; + case "Automatic": + mde.setDataColorMode(DataColorMode.AUTO); + break; + default: + break; + } + }); + add(mde,cb); + } +} diff --git a/src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownViewerDemo.java b/src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownViewerDemo.java new file mode 100644 index 0000000..31a8c40 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownViewerDemo.java @@ -0,0 +1,226 @@ +/*- + * #%L + * Markdown Editor Add-on + * %% + * Copyright (C) 2024 Flowing Code + * %% + * 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. + * #L% + */ +package com.flowingcode.vaadin.addons.markdown; + +import com.flowingcode.vaadin.addons.demo.DemoSource; +import com.flowingcode.vaadin.addons.markdown.BaseMarkdownComponent.DataColorMode; +import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; + +@DemoSource +@PageTitle("Markdown Viewer Demo") +@SuppressWarnings("serial") +@Route(value = "markdown-editor/viewer-demo", layout = MarkdownDemoView.class) +public class MarkdownViewerDemo extends VerticalLayout { + + public MarkdownViewerDemo() { + setSizeFull(); + MarkdownViewer mdv = new MarkdownViewer(); + mdv.setSizeFull(); + mdv.setDataColorMode(DataColorMode.LIGTH); + mdv.setContent(""" + +# h1 Heading +## h2 Heading +### h3 Heading +#### h4 Heading +##### h5 Heading +###### h6 Heading + + +## Horizontal Rules + +___ + +--- + +*** + + +## Emphasis + +**This is bold text** + +__This is bold text__ + +*This is italic text* + +_This is italic text_ + +~~Strikethrough~~ + + +## Blockquotes + + +> Blockquotes can also be nested... +>> ...by using additional greater-than signs right next to each other... +> > > ...or with spaces between arrows. + + +## Lists + +Unordered + ++ Create a list by starting a line with `+`, `-`, or `*` ++ Sub-lists are made by indenting 2 spaces: + - Marker character change forces new list start: + * Ac tristique libero volutpat at + + Facilisis in pretium nisl aliquet + - Nulla volutpat aliquam velit ++ Very easy! + +Ordered + +1. Lorem ipsum dolor sit amet +2. Consectetur adipiscing elit +3. Integer molestie lorem at massa + + +1. You can use sequential numbers... +1. ...or keep all the numbers as `1.` + +Start numbering with offset: + +57. foo +1. bar + + +## Code + +Inline `code` + +Indented code + + // Some comments + line 1 of code + line 2 of code + line 3 of code + + +Block code "fences" + +``` +Sample text here... +``` + +Syntax highlighting + +``` js +var foo = function (bar) { + return bar++; +}; + +console.log(foo(5)); +``` + +## Tables + +| Option | Description | +| ------ | ----------- | +| data | path to data files to supply the data that will be passed into templates. | +| engine | engine to be used for processing templates. Handlebars is the default. | +| ext | extension to be used for dest files. | + +Right aligned columns + +| Option | Description | +| ------:| -----------:| +| data | path to data files to supply the data that will be passed into templates. | +| engine | engine to be used for processing templates. Handlebars is the default. | +| ext | extension to be used for dest files. | + + +## Links + +[link text](http://dev.nodeca.com) + +[link with title](http://nodeca.github.io/pica/demo/ "title text!") + +Autoconverted link https://github.com/nodeca/pica (enable linkify to see) + + +## Images + +![Minion](https://octodex.github.com/images/minion.png) +![Stormtroopocat](https://octodex.github.com/images/stormtroopocat.jpg "The Stormtroopocat") + +Like links, Images also have a footnote style syntax + +![Alt text][id] + +With a reference later in the document defining the URL location: + +[id]: https://octodex.github.com/images/dojocat.jpg "The Dojocat" + +## Diagrams with Mermaid + +```mermaid +sequenceDiagram +Alice->>John: Hello John, how are you? +loop Healthcheck + John->>John: Fight against hypochondria +end +Note right of John: Rational thoughts! +John-->>Alice: Great! +John->>Bob: How about you? +Bob-->>John: Jolly good! +``` + + +### [Footnotes](https://github.com/markdown-it/markdown-it-footnote) + +Footnote 1 link[^first]. + +Footnote 2 link[^second]. + +Duplicated footnote reference[^second]. + +[^first]: Footnote **can have markup** + + and multiple paragraphs. + +[^second]: Footnote text. + + """); + ComboBox cb = new ComboBox(); + cb.setItems("Dark","Light","Automatic"); + cb.setLabel("Color mode"); + cb.setValue("Light"); + cb.addValueChangeListener(ev->{ + switch(ev.getValue()) { + case "Dark": + mdv.setDataColorMode(DataColorMode.DARK); + break; + case "Light": + mdv.setDataColorMode(DataColorMode.LIGTH); + break; + case "Automatic": + mdv.setDataColorMode(DataColorMode.AUTO); + break; + default: + break; + } + }); + add(mdv,cb); + } +} diff --git a/src/test/java/com/flowingcode/vaadin/addons/template/it/AbstractViewTest.java b/src/test/java/com/flowingcode/vaadin/addons/markdown/it/AbstractViewTest.java similarity index 97% rename from src/test/java/com/flowingcode/vaadin/addons/template/it/AbstractViewTest.java rename to src/test/java/com/flowingcode/vaadin/addons/markdown/it/AbstractViewTest.java index 1f7749b..24e1075 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/template/it/AbstractViewTest.java +++ b/src/test/java/com/flowingcode/vaadin/addons/markdown/it/AbstractViewTest.java @@ -1,15 +1,15 @@ /*- * #%L - * Template Add-on + * Markdown Editor Add-on * %% * Copyright (C) 2024 Flowing Code * %% * 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. @@ -18,7 +18,7 @@ * #L% */ -package com.flowingcode.vaadin.addons.template.it; +package com.flowingcode.vaadin.addons.markdown.it; import com.vaadin.testbench.ScreenshotOnFailureRule; import com.vaadin.testbench.TestBench; diff --git a/src/test/java/com/flowingcode/vaadin/addons/markdown/it/MarkdownEditorIT.java b/src/test/java/com/flowingcode/vaadin/addons/markdown/it/MarkdownEditorIT.java new file mode 100644 index 0000000..482ccca --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/addons/markdown/it/MarkdownEditorIT.java @@ -0,0 +1,40 @@ +/*- + * #%L + * Markdown Editor Add-on + * %% + * Copyright (C) 2024 Flowing Code + * %% + * 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. + * #L% + */ + +package com.flowingcode.vaadin.addons.markdown.it; + +import static org.junit.Assert.assertTrue; +import com.vaadin.flow.component.html.testbench.DivElement; +import com.vaadin.testbench.TestBenchElement; +import org.junit.Test; + +public class MarkdownEditorIT extends AbstractViewTest { + + public MarkdownEditorIT() { + super("editor-demo"); + } + + @Test + public void componentWorks() { + TestBenchElement element = $("markdown-editor").first(); + DivElement div = element.$(DivElement.class).first(); + assertTrue(div.getClassNames().contains("wmde-markdown-var")); + } +} diff --git a/src/test/java/com/flowingcode/vaadin/addons/markdown/it/MarkdownViewerIT.java b/src/test/java/com/flowingcode/vaadin/addons/markdown/it/MarkdownViewerIT.java new file mode 100644 index 0000000..48c8eb5 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/addons/markdown/it/MarkdownViewerIT.java @@ -0,0 +1,40 @@ +/*- + * #%L + * Markdown Editor Add-on + * %% + * Copyright (C) 2024 Flowing Code + * %% + * 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. + * #L% + */ + +package com.flowingcode.vaadin.addons.markdown.it; + +import static org.junit.Assert.assertTrue; +import com.vaadin.flow.component.html.testbench.DivElement; +import com.vaadin.testbench.TestBenchElement; +import org.junit.Test; + +public class MarkdownViewerIT extends AbstractViewTest { + + public MarkdownViewerIT() { + super("viewer-demo"); + } + + @Test + public void componentWorks() { + TestBenchElement element = $("markdown-viewer").first(); + DivElement div = element.$(DivElement.class).first(); + assertTrue(div.getClassNames().contains("wmde-markdown")); + } +} diff --git a/src/test/java/com/flowingcode/vaadin/addons/template/test/SerializationTest.java b/src/test/java/com/flowingcode/vaadin/addons/markdown/test/SerializationTest.java similarity index 83% rename from src/test/java/com/flowingcode/vaadin/addons/template/test/SerializationTest.java rename to src/test/java/com/flowingcode/vaadin/addons/markdown/test/SerializationTest.java index 1ee78c3..a2b7b95 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/template/test/SerializationTest.java +++ b/src/test/java/com/flowingcode/vaadin/addons/markdown/test/SerializationTest.java @@ -1,15 +1,15 @@ /*- * #%L - * Template Add-on + * Markdown Editor Add-on * %% * Copyright (C) 2024 Flowing Code * %% * 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. @@ -17,9 +17,10 @@ * limitations under the License. * #L% */ -package com.flowingcode.vaadin.addons.template.test; +package com.flowingcode.vaadin.addons.markdown.test; -import com.flowingcode.vaadin.addons.template.TemplateAddon; +import com.flowingcode.vaadin.addons.markdown.MarkdownEditor; +import com.flowingcode.vaadin.addons.markdown.MarkdownViewer; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -44,7 +45,8 @@ private void testSerializationOf(Object obj) throws IOException, ClassNotFoundEx @Test public void testSerialization() throws ClassNotFoundException, IOException { try { - testSerializationOf(new TemplateAddon()); + testSerializationOf(new MarkdownViewer()); + testSerializationOf(new MarkdownEditor()); } catch (Exception e) { Assert.fail("Problem while testing serialization: " + e.getMessage()); } diff --git a/src/test/java/com/flowingcode/vaadin/addons/template/TemplateDemo.java b/src/test/java/com/flowingcode/vaadin/addons/template/TemplateDemo.java deleted file mode 100644 index 5f6e6ee..0000000 --- a/src/test/java/com/flowingcode/vaadin/addons/template/TemplateDemo.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.flowingcode.vaadin.addons.template; - -import com.flowingcode.vaadin.addons.demo.DemoSource; -import com.vaadin.flow.component.html.Div; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; - -@DemoSource -@PageTitle("Template Add-on Demo") -@SuppressWarnings("serial") -@Route(value = "demo", layout = TemplateDemoView.class) -public class TemplateDemo extends Div { - - public TemplateDemo() { - add(new TemplateAddon()); - } -} diff --git a/src/test/java/com/flowingcode/vaadin/addons/template/it/ViewIT.java b/src/test/java/com/flowingcode/vaadin/addons/template/it/ViewIT.java deleted file mode 100644 index 0e5f164..0000000 --- a/src/test/java/com/flowingcode/vaadin/addons/template/it/ViewIT.java +++ /dev/null @@ -1,64 +0,0 @@ -/*- - * #%L - * Template Add-on - * %% - * Copyright (C) 2024 Flowing Code - * %% - * 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. - * #L% - */ - -package com.flowingcode.vaadin.addons.template.it; - -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; -import static org.junit.Assert.assertThat; - -import com.vaadin.testbench.TestBenchElement; -import org.hamcrest.Description; -import org.hamcrest.Matcher; -import org.hamcrest.TypeSafeDiagnosingMatcher; -import org.junit.Test; - -public class ViewIT extends AbstractViewTest { - - private Matcher hasBeenUpgradedToCustomElement = - new TypeSafeDiagnosingMatcher() { - - @Override - public void describeTo(Description description) { - description.appendText("a custom element"); - } - - @Override - protected boolean matchesSafely(TestBenchElement item, Description mismatchDescription) { - String script = "let s=arguments[0].shadowRoot; return !!(s&&s.childElementCount)"; - if (!item.getTagName().contains("-")) { - return true; - } - if ((Boolean) item.getCommandExecutor().executeScript(script, item)) { - return true; - } else { - mismatchDescription.appendText(item.getTagName() + " "); - mismatchDescription.appendDescriptionOf(is(not(this))); - return false; - } - } - }; - - @Test - public void componentWorks() { - TestBenchElement element = $("paper-input").first(); - assertThat(element, hasBeenUpgradedToCustomElement); - } -} diff --git a/src/test/resources/META-INF/frontend/styles/shared-styles.css b/src/test/resources/META-INF/frontend/styles/shared-styles.css index 6680e2d..9e0a278 100644 --- a/src/test/resources/META-INF/frontend/styles/shared-styles.css +++ b/src/test/resources/META-INF/frontend/styles/shared-styles.css @@ -1 +1,20 @@ -/*Demo styles*/ \ No newline at end of file +/*- + * #%L + * Markdown Editor Add-on + * %% + * Copyright (C) 2024 Flowing Code + * %% + * 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. + * #L% + */ +/*Demo styles*/