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 <[email protected]>
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