This is an automated email from the ASF dual-hosted git repository.

nmalin pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git


The following commit(s) were added to refs/heads/trunk by this push:
     new c7e788c041 Improved: Support Trumbowyg configuration parameter 
(OFBIZ-13224)
c7e788c041 is described below

commit c7e788c0416c206c5865f6822d380e7729188502
Author: Florian Motteau <florian.mott...@nereide.fr>
AuthorDate: Wed Apr 23 10:41:21 2025 +0200

    Improved: Support Trumbowyg configuration parameter (OFBIZ-13224)
    
    On textarea field, uses "visual-editor-buttons" attribute value as a
    configuration description for Trumbowyg, as described in [the
    
documentation](https://alex-d.github.io/Trumbowyg/documentation/#button-pane).
    Also fixes visual glitches on Trumbowyg for some themes.
    
    Thanks: Néréide team
---
 applications/content/widget/forum/ForumForms.xml   |  2 +-
 framework/widget/dtd/widget-form.xsd               | 11 +++--
 .../macro/RenderableFtlFormElementsBuilder.java    |  4 +-
 .../RenderableFtlFormElementsBuilderTest.java      | 50 ++++++++++++++++++++++
 .../webapp/common-theme/js/util/OfbizUtil.js       | 45 ++++++++-----------
 themes/common-theme/widget/Theme.xml               |  3 ++
 .../webapp/helveticus/helveticus-main-theme.less   | 12 +++++-
 .../rainbowstone/rainbowstone-main-theme.less      |  4 +-
 themes/rainbowstone/webapp/rainbowstone/style.css  | 14 +-----
 9 files changed, 95 insertions(+), 50 deletions(-)

diff --git a/applications/content/widget/forum/ForumForms.xml 
b/applications/content/widget/forum/ForumForms.xml
index c83c37e268..fd67248438 100644
--- a/applications/content/widget/forum/ForumForms.xml
+++ b/applications/content/widget/forum/ForumForms.xml
@@ -227,7 +227,7 @@ under the License.
         <field name="ownerContentId"><hidden 
value="${parameters.forumId}"/></field>
         <field name="caContentId"><hidden 
value="${parameters.forumMessageIdTo}"/></field>
         <field name="caContentAssocTypeId"><hidden value="RESPONSE"/></field>
-        <field name="forumMessageText" parameter-name="textData"><textarea 
rows="10" visual-editor-enable="true" visual-editor-buttons="compact"/></field>
+        <field name="forumMessageText" parameter-name="textData"><textarea 
rows="10" visual-editor-enable="true"/></field>
         <field name="addButton" title="${uiLabelMap.CommonAdd}" 
widget-style="smallSubmit"><submit button-type="button"/></field>
     </form>
     <form name="AddForumThreadMessage" type="single" extends="AddForumMessage" 
target="updateForumThreadMessage"
diff --git a/framework/widget/dtd/widget-form.xsd 
b/framework/widget/dtd/widget-form.xsd
index 6cc156640c..2be59b4fc7 100644
--- a/framework/widget/dtd/widget-form.xsd
+++ b/framework/widget/dtd/widget-form.xsd
@@ -1581,13 +1581,18 @@ under the License.
             <xs:attribute name="visual-editor-enable"
                           type="xs:boolean" default="false">
                 <xs:annotation>
-                    <xs:documentation>This will enable the html editor on this 
text area from www.unverse.net (more info there), only one textarea can be used 
on one page</xs:documentation>
+                    <xs:documentation>
+                        This will enable the HTML editor on this text area 
from https://alex-d.github.io/Trumbowyg/
+                    </xs:documentation>
                 </xs:annotation>
             </xs:attribute>
             <xs:attribute type="xs:string" name="visual-editor-buttons">
                 <xs:annotation>
-                    <xs:documentation>In here you can specify which buttons 
you want to see and in which order separated by blanks. Available buttons 
are:formatblock fontname fontsize newline bold italic underline left center 
right number bullet indent outdent undo redo color hilite rule link image
-                        table clean html spellcheck |(separator) Default is 
that all buttons are shown</xs:documentation>
+                    <xs:documentation>
+                        Trumbowyg buttons configuration object, as a 
JSON.parse parsable string (2 dimensions string array).
+                        Ex: 
[['formatting'],['strong','em','del'],['link'],['unorderedList','orderedList'],['horizontalRule']]
+                        See 
https://alex-d.github.io/Trumbowyg/documentation/#button-pane
+                    </xs:documentation>
                 </xs:annotation>
             </xs:attribute>
             <xs:attribute type="xs:string" name="placeholder">
diff --git 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/RenderableFtlFormElementsBuilder.java
 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/RenderableFtlFormElementsBuilder.java
index 8e90e0cc46..2c91b3032b 100644
--- 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/RenderableFtlFormElementsBuilder.java
+++ 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/RenderableFtlFormElementsBuilder.java
@@ -364,9 +364,7 @@ public final class RenderableFtlFormElementsBuilder {
 
         if (textareaField.getVisualEditorEnable()) {
             builder.booleanParameter("visualEditorEnable", true);
-
-            String buttons = textareaField.getVisualEditorButtons(context);
-            builder.stringParameter("buttons", UtilValidate.isEmpty(buttons) ? 
"maxi" : buttons);
+            builder.stringParameter("buttons", 
textareaField.getVisualEditorButtons(context));
         }
 
         if (textareaField.isReadOnly()) {
diff --git 
a/framework/widget/src/test/java/org/apache/ofbiz/widget/renderer/macro/RenderableFtlFormElementsBuilderTest.java
 
b/framework/widget/src/test/java/org/apache/ofbiz/widget/renderer/macro/RenderableFtlFormElementsBuilderTest.java
index 2bfc490f78..13a15f5ee6 100644
--- 
a/framework/widget/src/test/java/org/apache/ofbiz/widget/renderer/macro/RenderableFtlFormElementsBuilderTest.java
+++ 
b/framework/widget/src/test/java/org/apache/ofbiz/widget/renderer/macro/RenderableFtlFormElementsBuilderTest.java
@@ -440,6 +440,56 @@ public class RenderableFtlFormElementsBuilderTest {
                 MacroCallParameterMatcher.hasNameAndBooleanValue("disabled", 
true)));
     }
 
+    @Test
+    public void textareaFieldVisualEditorEnabledNoButtons(@Mocked final 
ModelFormField.TextareaField textareaField) {
+        new Expectations() {
+            {
+                modelFormField.getDisabled(withNotNull());
+                result = true;
+
+                textareaField.getVisualEditorEnable();
+                result = true;
+
+                textareaField.getVisualEditorButtons(withNotNull());
+                result = "";
+            }
+        };
+
+        final HashMap<String, Object> context = new HashMap<>();
+
+        final RenderableFtl renderableFtl = 
renderableFtlFormElementsBuilder.textArea(context, textareaField);
+        assertThat(renderableFtl, 
MacroCallMatcher.hasNameAndParameters("renderTextareaField",
+                
MacroCallParameterMatcher.hasNameAndBooleanValue("visualEditorEnable", true)));
+    }
+
+    @Test
+    public void textareaFieldVisualEditorEnabledButtons(@Mocked final 
ModelFormField.TextareaField textareaField) {
+        String editorConfiguration = 
"[['formatting'],['strong','em','del'],['link'],['unorderedList','orderedList'],"
+                + 
"['horizontalRule'],['removeformat'],['indent','outdent'],['fullscreen']]";
+
+        new Expectations() {
+            {
+                modelFormField.getDisabled(withNotNull());
+                result = true;
+
+                textareaField.getVisualEditorEnable();
+                result = true;
+
+                textareaField.getVisualEditorButtons(withNotNull());
+                result = editorConfiguration;
+            }
+        };
+
+        final HashMap<String, Object> context = new HashMap<>();
+
+        final RenderableFtl renderableFtl = 
renderableFtlFormElementsBuilder.textArea(context, textareaField);
+        assertThat(renderableFtl, 
MacroCallMatcher.hasNameAndParameters("renderTextareaField",
+                
MacroCallParameterMatcher.hasNameAndBooleanValue("visualEditorEnable", true)));
+        assertThat(renderableFtl, MacroCallMatcher.hasNameAndParameters(
+                "renderTextareaField",
+                MacroCallParameterMatcher.hasNameAndStringValue("buttons", 
editorConfiguration)));
+    }
+
     @Test
     public void fieldGroupOpenRendersCollapsibleAreaId(@Mocked final 
ModelForm.FieldGroup fieldGroup) {
         new Expectations() {
diff --git a/themes/common-theme/webapp/common-theme/js/util/OfbizUtil.js 
b/themes/common-theme/webapp/common-theme/js/util/OfbizUtil.js
index fb1cb53f6c..6209be731e 100644
--- a/themes/common-theme/webapp/common-theme/js/util/OfbizUtil.js
+++ b/themes/common-theme/webapp/common-theme/js/util/OfbizUtil.js
@@ -147,34 +147,23 @@ function bindObservers(bind_element) {
         })
     });
     jQuery(bind_element).find(".visual-editor").each(function () {
-        var self = this;
-        var libraryFiles = 
["/common/js/node_modules/trumbowyg/dist/trumbowyg.min.js",
-            
"/common/js/node_modules/trumbowyg/dist/plugins/indent/trumbowyg.indent.min.js"];
-        importLibrary(libraryFiles, function () {
-            var element = jQuery(self);
-            var language = element.data('language');
-            var buttons = [['viewHTML'],
-                ['undo', 'redo'],
-                ['formatting'],
-                ['strong', 'em', 'del'],
-                ['superscript', 'subscript'],
-                ['link'],
-                ['insertImage'],
-                ['justifyLeft', 'justifyCenter', 'justifyRight', 
'justifyFull'],
-                ['unorderedList', 'orderedList'],
-                ['horizontalRule'],
-                ['removeformat'],
-                ['indent', 'outdent'],
-                ['fullscreen']
-            ]
-            var opts = {
-                lang: language,
-                btns: buttons,
-                semantic: false,
-                tagsToRemove: ['script', 'link'],
-                svgPath: '/common/js/node_modules/trumbowyg/dist/ui/icons.svg'
-            }
-            element.trumbowyg(opts);
+        const element = $(this);
+        const lang = element.data('language');
+        const toolbarAttr = element.data('toolbar');
+        const providedBtns = toolbarAttr ? 
JSON.parse(toolbarAttr.replace(/'/g, '"')) : undefined;
+        const defaultBtns = [
+            ['undo', 'redo'], ['formatting'], ['strong', 'em', 'del'], 
['superscript', 'subscript'], ['link'],
+            ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull'], 
['unorderedList', 'orderedList'],
+            ['horizontalRule'], ['removeformat'], ['indent', 'outdent'], 
['fullscreen']
+        ];
+        element.trumbowyg({
+            lang,
+            btns: providedBtns ?? defaultBtns,
+            semantic: false,
+            tagsToRemove: ['script', 'link'],
+            svgPath: '/common/js/node_modules/trumbowyg/dist/ui/icons.svg',
+            resetCss: true,
+            linkTargets: ['_blank']
         });
     });
     jQuery(bind_element).find(".ajaxAutoCompleter").each(function () {
diff --git a/themes/common-theme/widget/Theme.xml 
b/themes/common-theme/widget/Theme.xml
index ab41e20e77..739dc33086 100644
--- a/themes/common-theme/widget/Theme.xml
+++ b/themes/common-theme/widget/Theme.xml
@@ -66,6 +66,8 @@ under the License.
         <property name="VT_HDR_JAVASCRIPT['add']" 
value="/common/js/node_modules/moment/min/moment-with-locales.js"/>
         <property name="VT_HDR_JAVASCRIPT['add']" 
value="/common/js/node_modules/moment-timezone/builds/moment-timezone-with-data.js"/>
         <property name="VT_HDR_JAVASCRIPT['add']" 
value="/common/js/node_modules/daterangepicker/daterangepicker.js"/>
+        <property name="VT_HDR_JAVASCRIPT['add']" 
value="/common/js/node_modules/trumbowyg/dist/trumbowyg.min.js"/>
+        <property name="VT_HDR_JAVASCRIPT['add']" 
value="/common/js/node_modules/trumbowyg/dist/plugins/indent/trumbowyg.indent.min.js"/>
         <property name="VT_HDR_JAVASCRIPT['add']" 
value="/common/js/util/OfbizUtil.js"/>
         <property name="VT_HDR_JAVASCRIPT['add']" 
value="/common/js/util/fieldlookup.js"/>
         <property name="VT_HDR_JAVASCRIPT['add']" 
value="/common/js/plugins/date/date.timezone-min.js"/>
@@ -79,6 +81,7 @@ under the License.
         <property name="VT_STYLESHEET['add']" 
value="/common/js/node_modules/jquery-ui-dist/jquery-ui.min.css"/>
         <property name="VT_STYLESHEET['add']" value="/common/css/info.css"/>
         <property name="VT_STYLESHEET['add']" 
value="/common/js/node_modules/daterangepicker/daterangepicker.css"/>
+        <property name="VT_STYLESHEET['add']" 
value="/common/js/node_modules/trumbowyg/dist/ui/trumbowyg.min.css"/>
     </theme-properties>
 
     <templates><!-- Freemarker template use by this theme to render widget 
model-->
diff --git a/themes/helveticus/webapp/helveticus/helveticus-main-theme.less 
b/themes/helveticus/webapp/helveticus/helveticus-main-theme.less
index c9d309ce35..249ce7d87a 100644
--- a/themes/helveticus/webapp/helveticus/helveticus-main-theme.less
+++ b/themes/helveticus/webapp/helveticus/helveticus-main-theme.less
@@ -62,10 +62,20 @@ body {
     background: @grey-lighter;
 }
 
-ul, li {
+ul li {
     list-style-type: none
 }
 
+/* restore list styles for Trumbowyg text editor */
+.trumbowyg-editor.trumbowyg-reset-css {
+    ul li {
+        list-style-type: disc;
+    }
+    ol li {
+        list-style-type: decimal;
+    }
+}
+
 br.clear, .clear {
     display: none
 }
diff --git 
a/themes/rainbowstone/webapp/rainbowstone/rainbowstone-main-theme.less 
b/themes/rainbowstone/webapp/rainbowstone/rainbowstone-main-theme.less
index 1a6ee86289..c176fae70b 100644
--- a/themes/rainbowstone/webapp/rainbowstone/rainbowstone-main-theme.less
+++ b/themes/rainbowstone/webapp/rainbowstone/rainbowstone-main-theme.less
@@ -1339,7 +1339,9 @@ a.user-pref-btn {
   padding: 0.4em;
 }
 
-.screenlet-body div {
+/* this rule is way too broad, targets all divs in screenlets (which is a lot 
of divs :) */
+/* just excluding Trumbowyg elements to avoid a visual glitch */
+.screenlet-body div:not([class^="trumbowyg"]) {
   margin: 0.8em 0.1em
 }
 
diff --git a/themes/rainbowstone/webapp/rainbowstone/style.css 
b/themes/rainbowstone/webapp/rainbowstone/style.css
index d55919b3a3..8d06162a4c 100644
--- a/themes/rainbowstone/webapp/rainbowstone/style.css
+++ b/themes/rainbowstone/webapp/rainbowstone/style.css
@@ -1927,16 +1927,4 @@ html > /**/ body .jstree-default a {
 /* The custom CSS to show mouse pointer on links using featherlight plugin  */
 a[data-featherlight] {
     cursor: pointer;
-}
-
-/*The custom css for Trumbowyg*/
-.trumbowyg-button-pane {
-    margin: 0 !important;
-}
-.trumbowyg-button-pane .trumbowyg-button-group {
-    display: inline-block; 
-    margin: 0 !important;
-}
-.trumbowyg-button-pane button {
-    color: #000;
-}
+}
\ No newline at end of file

Reply via email to