From 64a1a8aaeb60ee3ae3c2a63a2a6d17005922bbb4 Mon Sep 17 00:00:00 2001 From: Sylvain Jermini Date: Fri, 8 Mar 2024 17:30:56 +0100 Subject: [PATCH] misc precision fixes: float -> double, in some cases we need the decimals --- data/mj-section-column-precision-2.mjml | 12 ++ data/mj-section-with-background-url.mjml | 9 ++ data/mj-section-with-background.mjml | 9 ++ data/mj-section-with-css-class.mjml | 9 ++ data/mj-section-with-full-width.mjml | 19 +++ data/mj-section-with-mj-class.mjml | 15 +++ data/section-column-precision.mjml | 15 +++ data/sphero-mini.mjml | 84 ++++++++++++ data/ticketshop.mjml | 110 ++++++++++++++++ data/welcome-email.mjml | 22 ++++ data/wordly.mjml | 121 ++++++++++++++++++ .../digitalfondue/mjml4j/BaseComponent.java | 12 +- .../ch/digitalfondue/mjml4j/CssBoxModel.java | 2 +- .../digitalfondue/mjml4j/CssUnitParser.java | 24 +++- .../mjml4j/MjmlComponentButton.java | 4 +- .../mjml4j/MjmlComponentCarousel.java | 4 +- .../mjml4j/MjmlComponentCarouselImage.java | 6 +- .../mjml4j/MjmlComponentColumn.java | 24 ++-- .../mjml4j/MjmlComponentDivider.java | 8 +- .../mjml4j/MjmlComponentGroup.java | 20 +-- .../mjml4j/MjmlComponentHero.java | 18 +-- .../mjml4j/MjmlComponentImage.java | 4 +- .../mjml4j/MjmlComponentSection.java | 14 +- .../mjml4j/MjmlComponentWrapper.java | 2 +- .../java/ch/digitalfondue/mjml4j/Utils.java | 2 +- .../mjml4j/BaseComponentTests.java | 20 +++ .../mjml4j/ComplexTemplateTests.java | 28 ++++ 27 files changed, 551 insertions(+), 66 deletions(-) create mode 100644 data/mj-section-column-precision-2.mjml create mode 100644 data/mj-section-with-background-url.mjml create mode 100644 data/mj-section-with-background.mjml create mode 100644 data/mj-section-with-css-class.mjml create mode 100644 data/mj-section-with-full-width.mjml create mode 100644 data/mj-section-with-mj-class.mjml create mode 100644 data/section-column-precision.mjml create mode 100644 data/sphero-mini.mjml create mode 100644 data/ticketshop.mjml create mode 100644 data/welcome-email.mjml create mode 100644 data/wordly.mjml create mode 100644 src/test/java/ch/digitalfondue/mjml4j/ComplexTemplateTests.java diff --git a/data/mj-section-column-precision-2.mjml b/data/mj-section-column-precision-2.mjml new file mode 100644 index 0000000..7779926 --- /dev/null +++ b/data/mj-section-column-precision-2.mjml @@ -0,0 +1,12 @@ + + + + + hello + + + world + + + + \ No newline at end of file diff --git a/data/mj-section-with-background-url.mjml b/data/mj-section-with-background-url.mjml new file mode 100644 index 0000000..7ab2aae --- /dev/null +++ b/data/mj-section-with-background-url.mjml @@ -0,0 +1,9 @@ + + + + + some text + + + + \ No newline at end of file diff --git a/data/mj-section-with-background.mjml b/data/mj-section-with-background.mjml new file mode 100644 index 0000000..07381c4 --- /dev/null +++ b/data/mj-section-with-background.mjml @@ -0,0 +1,9 @@ + + + + + Foo Bar + + + + \ No newline at end of file diff --git a/data/mj-section-with-css-class.mjml b/data/mj-section-with-css-class.mjml new file mode 100644 index 0000000..586f6ea --- /dev/null +++ b/data/mj-section-with-css-class.mjml @@ -0,0 +1,9 @@ + + + + + some text + + + + \ No newline at end of file diff --git a/data/mj-section-with-full-width.mjml b/data/mj-section-with-full-width.mjml new file mode 100644 index 0000000..93966e6 --- /dev/null +++ b/data/mj-section-with-full-width.mjml @@ -0,0 +1,19 @@ + + + + + some text + + + + + some text + + + + + some text + + + + \ No newline at end of file diff --git a/data/mj-section-with-mj-class.mjml b/data/mj-section-with-mj-class.mjml new file mode 100644 index 0000000..a8c071e --- /dev/null +++ b/data/mj-section-with-mj-class.mjml @@ -0,0 +1,15 @@ + + + + + + + + + + + some text + + + + \ No newline at end of file diff --git a/data/section-column-precision.mjml b/data/section-column-precision.mjml new file mode 100644 index 0000000..ec1601c --- /dev/null +++ b/data/section-column-precision.mjml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data/sphero-mini.mjml b/data/sphero-mini.mjml new file mode 100644 index 0000000..b858c18 --- /dev/null +++ b/data/sphero-mini.mjml @@ -0,0 +1,84 @@ + + + Sphero Mini - Mix and Match + + + + + + + + + + + + + + + + + + + + + + + + + Colorful, interchangeable shells allow you to switch one out to suit your mood. Remove the shell to charge. + + + + + + + + + + + + + + + + GET YOUR ROBOT + Sphero Mini fits a huge experience into a tiny robot the size of a ping pong ball. It’s fun, ok? + + BUY MINI + + + + + + + + + + + + + GET EXTRA SHELLS + Neon pink, orange, blue, green or classic Sphero white. Buy one. Or two. Or all. + + BUY SHELLS + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data/ticketshop.mjml b/data/ticketshop.mjml new file mode 100644 index 0000000..34c34de --- /dev/null +++ b/data/ticketshop.mjml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + [[HEADLINE]] + + + [PERMALINK_LABEL]] + + + + + + + + + Special pre sale information + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin rutrum enim eget magna efficitur, eu semper augue semper. Aliquam erat volutpat. Proin rutrum enim eget magna efficitur. + + + + + PRE SALE BEGINS TODAY AT 9 AM + + + + + BUY TICKETS + PASSWORD : YULAN03 + + + + + + + + LAST ALBUM AVAILABLE 12,99€ + BUY IT ! + + + + + + + + OUR PARTNERS + + + + + + + + + + + + + + + + + + + Terms and conditions: + +

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin rutrum enim eget magna efficitur, eu semper augue semper. Aliquam erat volutpat. Cras id dui lectus. Vestibulum sed finibus lectus, sit amet suscipit nibh. Proin nec commodo purus. + Sed eget nulla elit. Nulla aliquet mollis faucibus.

+
+
+
+ + + +

0800 123 456

+
+ +

Privacy policy

+
+
+ + + + + + + + + + +
+ + + +

[[DELIVERY_INFO]]

+

[[POSTAL_ADDRESS]]

+
+
+
+
+
\ No newline at end of file diff --git a/data/welcome-email.mjml b/data/welcome-email.mjml new file mode 100644 index 0000000..2db1137 --- /dev/null +++ b/data/welcome-email.mjml @@ -0,0 +1,22 @@ + + + + + + + + + + Welcome aboard + + + + + Dear [[FirstName]] Welcome to [[CompanyName]]. + We're really excited you've decided to give us a try. In case you have any questions, feel free to reach out to us at [[ContactEmail]]. You can login to your account with your username [[UserName]] + Login + Thanks,

The [[CompanyName]] Team

+
+
+
+
\ No newline at end of file diff --git a/data/wordly.mjml b/data/wordly.mjml new file mode 100644 index 0000000..25db7b7 --- /dev/null +++ b/data/wordly.mjml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + [[HEADLINE]] + + + [[PERMALINK_LABEL]] + + + + + + + + + + + + home + Summer deals + Our blog + Follow us + + + + + + ARE YOU SEASCAPE? + + + OR CITYSCAPE? + + + + + +

SUNNIEST DESTINATIONS

+
+ + BOOK NOW + + BOOK NOW +
+ + +

CHEAP CITY TOUR

+
+ + BOOK NOW + + BOOK NOW +
+
+ + + + + + +

RATE YOUR STAY !

+
+ +
+
+ + + + +

+ BEST COMPANIES FOR YOUR FLIGHTS +

+
+
+ + + +

+ INSURANCES INCLUDED +

+
+
+ + + +

+ HOTELS BEST SELECTION +

+
+
+
+ + + + + + + + + + + + + + [[DELIVERY_INFO]] +

[[POSTAL_ADDRESS]]

+
+
+
+
+
\ No newline at end of file diff --git a/src/main/java/ch/digitalfondue/mjml4j/BaseComponent.java b/src/main/java/ch/digitalfondue/mjml4j/BaseComponent.java index 90be982..80227ab 100644 --- a/src/main/java/ch/digitalfondue/mjml4j/BaseComponent.java +++ b/src/main/java/ch/digitalfondue/mjml4j/BaseComponent.java @@ -246,7 +246,7 @@ CssBoxModel getBoxModel() { if (hasParentComponent() && getParent() instanceof BodyComponent parent) { - containerWidth.value = parent.getContainerInnerWidth() - paddings - borders; + containerWidth = containerWidth.withValue(parent.getContainerInnerWidth() - paddings - borders); return new CssBoxModel( parent.getContainerInnerWidth(), @@ -265,7 +265,7 @@ CssBoxModel getBoxModel() { private static final Pattern PATTERN_SHORTHAND_BORDER_VALUE = Pattern.compile("(?:(?:^| )([0-9]+))"); - float getShorthandBorderValue(String direction) { + double getShorthandBorderValue(String direction) { var mjAttributeDirection = getAttribute("border-" + direction); var mjAttribute = getAttribute("border"); @@ -283,19 +283,19 @@ float getShorthandBorderValue(String direction) { if (!match.find()) return 0; - return Float.parseFloat(match.group().trim()); + return Double.parseDouble(match.group().trim()); } - float getContainerInnerWidth() { + double getContainerInnerWidth() { return cssBoxModel.boxWidth(); } - float getContainerOuterWidth() { + double getContainerOuterWidth() { return cssBoxModel.totalWidth(); } - float getShorthandAttributeValue(String attribute, String direction) { + double getShorthandAttributeValue(String attribute, String direction) { var mjAttributeDirection = getAttribute(attribute + "-" + direction); var mjAttribute = getAttribute(attribute); diff --git a/src/main/java/ch/digitalfondue/mjml4j/CssBoxModel.java b/src/main/java/ch/digitalfondue/mjml4j/CssBoxModel.java index 5c2b844..a75b173 100644 --- a/src/main/java/ch/digitalfondue/mjml4j/CssBoxModel.java +++ b/src/main/java/ch/digitalfondue/mjml4j/CssBoxModel.java @@ -1,4 +1,4 @@ package ch.digitalfondue.mjml4j; -record CssBoxModel(float totalWidth, float borderWidth, float paddingWidth, float boxWidth) { +record CssBoxModel(double totalWidth, double borderWidth, double paddingWidth, double boxWidth) { } diff --git a/src/main/java/ch/digitalfondue/mjml4j/CssUnitParser.java b/src/main/java/ch/digitalfondue/mjml4j/CssUnitParser.java index 59874d8..c410726 100644 --- a/src/main/java/ch/digitalfondue/mjml4j/CssUnitParser.java +++ b/src/main/java/ch/digitalfondue/mjml4j/CssUnitParser.java @@ -7,11 +7,14 @@ class CssUnitParser { static class CssParsedUnit { final String unit; - float value; + final double value; - CssParsedUnit(String unit, float value) { + final double valueFullPrecision; + + CssParsedUnit(String unit, double value, double valueFullPrecision) { this.unit = unit; this.value = value; + this.valueFullPrecision = valueFullPrecision; } boolean isPercent() { @@ -22,7 +25,15 @@ boolean isPercent() { @Override public String toString() { - return Utils.floatToString(value) + unit; + return Utils.doubleToString(value) + unit; + } + + public String toFullPrecisionString() { + return Utils.doubleToString(valueFullPrecision) + unit; + } + + CssParsedUnit withValue(double value) { + return new CssParsedUnit(unit, value, value); } } @@ -32,7 +43,7 @@ public String toString() { static CssParsedUnit parse(String cssValue) { if (Utils.isNullOrWhiteSpace(cssValue)) { - return new CssParsedUnit(null, 0); + return new CssParsedUnit(null, 0, 0); } var match = UNIT_PATTERN.matcher(cssValue); @@ -46,10 +57,11 @@ static CssParsedUnit parse(String cssValue) { widthUnit = "px"; } + var valueFullPrecision = Double.parseDouble(widthValue); if ("%".equals(widthUnit)) { - return new CssParsedUnit(widthUnit, Float.parseFloat(widthValue)); + return new CssParsedUnit(widthUnit, valueFullPrecision, valueFullPrecision); } else { - return new CssParsedUnit(widthUnit, (int) Float.parseFloat(widthValue)); + return new CssParsedUnit(widthUnit, (int) valueFullPrecision, valueFullPrecision); } } } diff --git a/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentButton.java b/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentButton.java index 2b74a13..a2e1e78 100644 --- a/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentButton.java +++ b/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentButton.java @@ -6,7 +6,7 @@ import java.util.LinkedHashMap; import static ch.digitalfondue.mjml4j.AttributeValueType.of; -import static ch.digitalfondue.mjml4j.Utils.floatToString; +import static ch.digitalfondue.mjml4j.Utils.doubleToString; import static ch.digitalfondue.mjml4j.Utils.mapOf; import static java.util.Map.entry; @@ -115,7 +115,7 @@ private String calculateAWidth(String content) { getShorthandAttributeValue("inner-padding", "right"); var calculatedWidth = parsedWidth.value - innerPaddings - borders; - return floatToString(calculatedWidth) + "px"; + return doubleToString(calculatedWidth) + "px"; } @Override diff --git a/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentCarousel.java b/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentCarousel.java index b412e61..448b764 100644 --- a/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentCarousel.java +++ b/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentCarousel.java @@ -297,8 +297,8 @@ private String getThumbnailsWidth() { if (!Utils.isNullOrEmpty(tbWidth)) { return tbWidth; } - var containerWidth = CssUnitParser.parse(floatToString(getContainerOuterWidth())); - return floatToString(Math.min(containerWidth.value, 110)); + var containerWidth = CssUnitParser.parse(doubleToString(getContainerOuterWidth())); + return doubleToString(Math.min(containerWidth.value, 110)); } @Override diff --git a/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentCarouselImage.java b/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentCarouselImage.java index b1e128a..54d8786 100644 --- a/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentCarouselImage.java +++ b/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentCarouselImage.java @@ -34,7 +34,7 @@ void setupStyles(CssStyleLibraries cssStyleLibraries) { cssStyleLibraries.add("images_img", mapOf( "border-radius", getAttribute("border-radius"), "display", "block", - "width", floatToString(getContainerOuterWidth()) + "px", + "width", doubleToString(getContainerOuterWidth()) + "px", "max-width", "100%", "height", "auto" )); @@ -98,7 +98,7 @@ StringBuilder renderThumbnail(HtmlRenderer renderer) { "style", "thumbnails_img", "src", src, "alt", getAttribute("alt"), - "width", floatToString(CssUnitParser.parse(getAttribute("tb-width")).value) + "width", doubleToString(CssUnitParser.parse(getAttribute("tb-width")).value) )), res); renderer.closeTag("label", res); @@ -134,7 +134,7 @@ StringBuilder renderMjml(HtmlRenderer renderer) { "src", getAttribute("src"), "alt", getAttribute("alt"), "style", "images_img", - "width", floatToString(getContainerOuterWidth()), // this.context.containerWidth + "width", doubleToString(getContainerOuterWidth()), // this.context.containerWidth "border", "0" )), res); diff --git a/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentColumn.java b/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentColumn.java index 254c0e5..176aede 100644 --- a/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentColumn.java +++ b/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentColumn.java @@ -4,10 +4,9 @@ import org.w3c.dom.Element; import java.util.LinkedHashMap; -import java.util.Locale; import static ch.digitalfondue.mjml4j.AttributeValueType.of; -import static ch.digitalfondue.mjml4j.Utils.floatToString; +import static ch.digitalfondue.mjml4j.Utils.doubleToString; import static ch.digitalfondue.mjml4j.Utils.mapOf; import static java.util.Map.entry; @@ -51,16 +50,16 @@ CssBoxModel getBoxModel() { if (hasAttribute("width")) { containerWidth = getAttribute("width"); } else { - containerWidth = floatToString(sectionWidth / parentSectionColumnCount) + "px"; + containerWidth = doubleToString(sectionWidth / parentSectionColumnCount) + "px"; } var childContainerWidth = containerWidth; var parsedWidth = CssUnitParser.parse(containerWidth); if (parsedWidth.isPercent()) { - parsedWidth.value = (sectionWidth * parsedWidth.value / 100); + parsedWidth = parsedWidth.withValue((sectionWidth * parsedWidth.value / 100)); } - containerWidth = floatToString(parsedWidth.value) + "px"; - childContainerWidth = floatToString(parsedWidth.value - allPaddings) + "px"; + containerWidth = doubleToString(parsedWidth.valueFullPrecision) + "px"; + childContainerWidth = doubleToString(parsedWidth.value - allPaddings) + "px"; var columnWidth = CssUnitParser.parse(childContainerWidth); return new CssBoxModel( @@ -84,7 +83,7 @@ private CssUnitParser.CssParsedUnit getParsedWidth() { if (hasAttribute("width")) width = getAttribute("width"); else - width = floatToString(100. / getSectionColumnCount()) + "%"; + width = doubleToString(100. / getSectionColumnCount()) + "%"; return CssUnitParser.parse(width); } @@ -97,15 +96,16 @@ private String getMobileWidth() { return "100%"; } - if (Utils.isNullOrWhiteSpace(width)) - return floatToString(100. / parentSectionColumnCount) + "%"; + if (Utils.isNullOrWhiteSpace(width)) { + return doubleToString(100. / parentSectionColumnCount) + "%"; + } var parsedWidth = CssUnitParser.parse(width); if (parsedWidth.isPercent()) { return width; } else { - return floatToString(parsedWidth.value / CssUnitParser.parse(containerWidth).value) + "%"; + return doubleToString(parsedWidth.value / CssUnitParser.parse(containerWidth).value) + "%"; } } @@ -115,14 +115,14 @@ String getWidthAsPixel() { var parsedContainerWidth = CssUnitParser.parse(containerWidth); if (parsedWidth.isPercent()) { - return parsedContainerWidth.toString(); + return parsedContainerWidth.toFullPrecisionString(); // we don't want to cut off the precision here } return parsedWidth.toString(); } private String getColumnClass() { var parsedWidth = getParsedWidth(); - var formattedClassNb = floatToString(parsedWidth.value).replace('.', '-'); + var formattedClassNb = doubleToString(parsedWidth.value).replace('.', '-'); var className = "mj-column-px-" + formattedClassNb; diff --git a/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentDivider.java b/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentDivider.java index b674886..2f918d8 100644 --- a/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentDivider.java +++ b/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentDivider.java @@ -7,7 +7,7 @@ import java.util.Locale; import static ch.digitalfondue.mjml4j.AttributeValueType.of; -import static ch.digitalfondue.mjml4j.Utils.floatToString; +import static ch.digitalfondue.mjml4j.Utils.doubleToString; import static ch.digitalfondue.mjml4j.Utils.mapOf; import static java.util.Map.entry; @@ -37,7 +37,7 @@ LinkedHashMap allowedAttributes() { } private String getOutlookWidth() { - var containerWidth = CssUnitParser.parse(floatToString(getContainerOuterWidth())); + var containerWidth = CssUnitParser.parse(doubleToString(getContainerOuterWidth())); var paddingSize = getShorthandAttributeValue("padding", "left") + getShorthandAttributeValue("padding", "right"); @@ -48,12 +48,12 @@ private String getOutlookWidth() { case "%": { var effectiveWidth = containerWidth.value - paddingSize; var percentMultiplier = parsedWidth.value / 100; - return floatToString(effectiveWidth * percentMultiplier) + "px"; + return doubleToString(effectiveWidth * percentMultiplier) + "px"; } case "px": return parsedWidth.toString(); default: - return floatToString(containerWidth.value - paddingSize) + "px"; + return doubleToString(containerWidth.value - paddingSize) + "px"; } } diff --git a/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentGroup.java b/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentGroup.java index 886fd86..6001ac4 100644 --- a/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentGroup.java +++ b/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentGroup.java @@ -7,7 +7,7 @@ import java.util.LinkedHashMap; import static ch.digitalfondue.mjml4j.AttributeValueType.of; -import static ch.digitalfondue.mjml4j.Utils.floatToString; +import static ch.digitalfondue.mjml4j.Utils.doubleToString; import static ch.digitalfondue.mjml4j.Utils.mapOf; class MjmlComponentGroup extends BaseComponent.BodyComponent { @@ -69,16 +69,16 @@ CssBoxModel getBoxModel() { if (hasAttribute("width")) { containerWidth = getAttribute("width"); } else { - containerWidth = floatToString(sectionWidth / parentSectionColumnCount) + "px"; + containerWidth = doubleToString(sectionWidth / parentSectionColumnCount) + "px"; } var parsedWidth = CssUnitParser.parse(containerWidth); if (parsedWidth.isPercent()) { - parsedWidth.value = sectionWidth * parsedWidth.value / 100; + parsedWidth = parsedWidth.withValue(sectionWidth * parsedWidth.value / 100); } - containerWidth = floatToString(parsedWidth.value) + "px"; + containerWidth = doubleToString(parsedWidth.value) + "px"; var columnWidth = CssUnitParser.parse(this.containerWidth); @@ -106,7 +106,7 @@ private CssUnitParser.CssParsedUnit getParsedWidth() { if (hasAttribute("width")) width = getAttribute("width"); else - width = floatToString(100. / getSectionColumnCount()) + "%"; + width = doubleToString(100. / getSectionColumnCount()) + "%"; return CssUnitParser.parse(width); } @@ -115,14 +115,14 @@ private String getWidthAsPixel() { var parsedContainerWidth = CssUnitParser.parse(containerWidth); if (parsedWidth.isPercent()) - return floatToString(parsedContainerWidth.value * parsedWidth.value / 100) + "px"; + return doubleToString(parsedContainerWidth.value * parsedWidth.value / 100) + "px"; return parsedWidth.toString(); } private String getColumnClass() { var parsedWidth = getParsedWidth(); - var formattedClassNb = floatToString(parsedWidth.value).replace('.', '-'); + var formattedClassNb = doubleToString(parsedWidth.value).replace('.', '-'); var className = "mj-column-px-" + formattedClassNb; @@ -139,14 +139,14 @@ private String getColumnClass() { private String getElementWidth(String width) { if (Utils.isNullOrWhiteSpace(width)) { var parsedContainerWidth = CssUnitParser.parse(containerWidth); - float columnWidth = parsedContainerWidth.value / getSectionColumnCount(); - return floatToString(columnWidth) + "px"; + var columnWidth = parsedContainerWidth.value / getSectionColumnCount(); + return doubleToString(columnWidth) + "px"; } var parsedWidth = CssUnitParser.parse(width); if (parsedWidth.isPercent()) - return floatToString(100 * parsedWidth.value / getContainerInnerWidth()) + "px"; + return doubleToString(100 * parsedWidth.value / getContainerInnerWidth()) + "px"; return parsedWidth.toString(); } diff --git a/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentHero.java b/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentHero.java index e73daa9..444f05f 100644 --- a/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentHero.java +++ b/src/main/java/ch/digitalfondue/mjml4j/MjmlComponentHero.java @@ -6,7 +6,7 @@ import java.util.LinkedHashMap; import static ch.digitalfondue.mjml4j.AttributeValueType.of; -import static ch.digitalfondue.mjml4j.Utils.floatToString; +import static ch.digitalfondue.mjml4j.Utils.doubleToString; import static ch.digitalfondue.mjml4j.Utils.mapOf; import static java.util.Map.entry; @@ -63,11 +63,11 @@ void setupStyles(CssStyleLibraries cssStyleLibraries) { var backgroundHeight = CssUnitParser.parse(getAttribute("background-height")); var backgroundWidth = CssUnitParser.parse(getAttribute("background-width")); var backgroundRatio = Math.round(backgroundHeight.value / backgroundWidth.value * 100d); - var width = getElement().hasAttribute("background-width") ? getAttribute("background-width") : Utils.floatToString(getContainerInnerWidth()) + "px"; + var width = getElement().hasAttribute("background-width") ? getAttribute("background-width") : Utils.doubleToString(getContainerInnerWidth()) + "px"; cssStyleLibraries.add("div", mapOf( "margin", "0 auto", - "max-width", Utils.floatToString(getContainerInnerWidth()) + "px" + "max-width", Utils.doubleToString(getContainerInnerWidth()) + "px" )); cssStyleLibraries.add("table", mapOf( @@ -97,7 +97,7 @@ void setupStyles(CssStyleLibraries cssStyleLibraries) { )); cssStyleLibraries.add("outlook-table", mapOf( - "width", floatToString(getContainerInnerWidth()) + "px" + "width", doubleToString(getContainerInnerWidth()) + "px" )); cssStyleLibraries.add("outlook-td", mapOf( @@ -107,7 +107,7 @@ void setupStyles(CssStyleLibraries cssStyleLibraries) { )); cssStyleLibraries.add("outlook-inner-table", mapOf( - "width", floatToString(getContainerInnerWidth()) + "px" + "width", doubleToString(getContainerInnerWidth()) + "px" )); cssStyleLibraries.add("outlook-image", mapOf( @@ -183,7 +183,7 @@ private StringBuilder renderContent(HtmlRenderer renderer) { "cellpadding", "0", "cellspacing", "0", "style", "outlook-inner-table", - "width", floatToString(getContainerInnerWidth()) + "width", doubleToString(getContainerInnerWidth()) ))).append(" >"); res.append(""); res.append(""); @@ -252,8 +252,8 @@ private StringBuilder renderMode(HtmlRenderer renderer) { renderer.openTag("td", htmlAttributes(mapOf( "background", background, "style", "hero", - "height", floatToString(height) - ), mapOf("height", floatToString(height) + "px")), res); + "height", doubleToString(height) + ), mapOf("height", doubleToString(height) + "px")), res); res.append(renderContent(renderer)); renderer.closeTag("td", res); } @@ -272,7 +272,7 @@ StringBuilder renderMjml(HtmlRenderer renderer) { "cellspacing", "0", "role", "presentation", "style", "outlook-table", - "width", floatToString(getContainerInnerWidth()) + "width", doubleToString(getContainerInnerWidth()) ))).append(" >"); res.append(""); res.append("\n"); renderer.appendCurrentSpacing(res); renderer.closeEndif(res, true); diff --git a/src/main/java/ch/digitalfondue/mjml4j/Utils.java b/src/main/java/ch/digitalfondue/mjml4j/Utils.java index e8ef476..8f54976 100644 --- a/src/main/java/ch/digitalfondue/mjml4j/Utils.java +++ b/src/main/java/ch/digitalfondue/mjml4j/Utils.java @@ -241,7 +241,7 @@ static StringBuilder msoConditionalTag(CharSequence content, boolean negation) { } - static String floatToString(double d) { + static String doubleToString(double d) { if (d == (long) d) return Long.toString((long) d); else diff --git a/src/test/java/ch/digitalfondue/mjml4j/BaseComponentTests.java b/src/test/java/ch/digitalfondue/mjml4j/BaseComponentTests.java index 947c5ac..aedbe43 100644 --- a/src/test/java/ch/digitalfondue/mjml4j/BaseComponentTests.java +++ b/src/test/java/ch/digitalfondue/mjml4j/BaseComponentTests.java @@ -185,4 +185,24 @@ void testSectionBackgroundImage() { void testEntitiesEscaping() { testTemplate("entities-escaping"); } + + + @Test + void testSectionMisc() { + testTemplate("mj-section-with-background"); + testTemplate("mj-section-with-background-url"); + testTemplate("mj-section-with-css-class"); + testTemplate("mj-section-with-full-width"); + testTemplate("mj-section-with-mj-class"); + } + + @Test + void testSectionColumnPrecision() { + testTemplate("section-column-precision"); + } + + @Test + void testSectionColumnPrecision2() { + testTemplate("mj-section-column-precision-2"); + } } diff --git a/src/test/java/ch/digitalfondue/mjml4j/ComplexTemplateTests.java b/src/test/java/ch/digitalfondue/mjml4j/ComplexTemplateTests.java new file mode 100644 index 0000000..36ff867 --- /dev/null +++ b/src/test/java/ch/digitalfondue/mjml4j/ComplexTemplateTests.java @@ -0,0 +1,28 @@ +package ch.digitalfondue.mjml4j; + +import org.junit.jupiter.api.Test; + +import static ch.digitalfondue.mjml4j.Helpers.testTemplate; + +class ComplexTemplateTests { + + @Test + void testWordly() { + testTemplate("wordly"); + } + + @Test + void testTicketshop() { + testTemplate("ticketshop"); + } + + @Test + void testWelcomeEmail() { + testTemplate("welcome-email"); + } + + @Test + void testSpheroMini() { + testTemplate("sphero-mini"); + } +}