Class BodyComponent

java.lang.Object
dev.jcputney.mjml.component.BaseComponent
dev.jcputney.mjml.component.BodyComponent
Direct Known Subclasses:
AbstractSectionComponent, MjAccordion, MjAccordionElement, MjAccordionText, MjAccordionTitle, MjBody, MjButton, MjCarousel, MjCarouselImage, MjColumn, MjDivider, MjGroup, MjHero, MjImage, MjNavbar, MjNavbarLink, MjRaw, MjSocial, MjSocialElement, MjSpacer, MjTable, MjText

public abstract non-sealed class BodyComponent extends BaseComponent
Abstract base for body components that render to HTML. Provides common utilities for width calculation, padding, and style building.
  • Constructor Details

    • BodyComponent

      protected BodyComponent(MjmlNode node, GlobalContext globalContext, RenderContext renderContext)
      Creates a new body component.
      Parameters:
      node - the parsed MJML node for this component
      globalContext - the document-wide context gathered during head processing
      renderContext - the current rendering context (container width, position, etc.)
  • Method Details

    • buildResponsiveClass

      protected static String buildResponsiveClass(String widthSpec)
      Builds a responsive CSS class name from a column width specification. Returns "mj-column-px-{value}" for pixel widths or "mj-column-per-{value}" for percentages.
      Parameters:
      widthSpec - the width specification (e.g. "200px" or "50")
      Returns:
      the responsive CSS class name
    • render

      public abstract String render()
      Renders this component to HTML.
      Returns:
      the rendered HTML string
    • getContentWidth

      public double getContentWidth()
      Returns the content width after subtracting padding and borders.
      Returns:
      the content width in pixels
    • getBoxModel

      public CssBoxModel getBoxModel()
      Returns the box model for this component based on its padding and border attributes. The result is cached for repeated access within the same render call.
      Returns:
      the CSS box model for this component
    • resolveShorthandSide

      protected double resolveShorthandSide(String shorthandAttr, String sideAttr, int sideIndex)
      Resolves a single side of a CSS shorthand property. Checks the individual override attribute first (e.g., padding-left), then falls back to extracting that side from the shorthand (e.g., padding). Matches MJML's getShorthandAttrValue() behavior.
      Parameters:
      shorthandAttr - the shorthand attribute name (e.g., "padding")
      sideAttr - the individual side attribute (e.g., "padding-left")
      sideIndex - the index within the shorthand (0=top, 1=right, 2=bottom, 3=left)
      Returns:
      the resolved pixel value for that side
    • buildStyle

      protected String buildStyle(Map<String,String> styles)
      Builds a CSS style string from a map of property/value pairs.
      Parameters:
      styles - the map of CSS property names to values
      Returns:
      the concatenated CSS style string
    • buildAttributes

      protected String buildAttributes(Map<String,String> attrs)
      Helper to build HTML attributes string from a map. When sanitizeOutput is enabled, attribute values are HTML-escaped.
      Parameters:
      attrs - the map of attribute names to values
      Returns:
      the concatenated HTML attributes string
    • escapeAttr

      protected String escapeAttr(String value)
      Escapes an attribute value for safe HTML interpolation when sanitizeOutput is enabled. Use this for attribute values that are directly interpolated into HTML via sb.append() rather than going through buildAttributes().
      Parameters:
      value - the attribute value to escape
      Returns:
      the escaped value, or an empty string if value is null
    • escapeHref

      protected static String escapeHref(String href)
      Escapes an href attribute value for safe HTML interpolation. Only escapes the double-quote character to prevent attribute breakout, matching the reference MJML implementation which does not HTML-encode ampersands in URL query parameters.
      Parameters:
      href - the href value to escape (should already be sanitized via sanitizeHref(String))
      Returns:
      the escaped href value, or an empty string if null
    • sanitizeHref

      protected String sanitizeHref(String href)
      Sanitizes a URL using an allowlist of safe URI schemes when sanitizeOutput is enabled. Only permits http:, https:, mailto:, tel:, fragment references (#), and relative paths (/). All other schemes are blocked and replaced with "#".

      Control characters and leading/trailing whitespace are stripped before the check to prevent bypass via \tjavascript: or similar.

      Parameters:
      href - the URL to sanitize
      Returns:
      the original URL if it uses a safe scheme, or "#" otherwise
    • renderChildren

      protected String renderChildren(ComponentRegistry registry)
      Renders all child body components and concatenates their output.
      Parameters:
      registry - the component registry used to create child components
      Returns:
      the concatenated HTML output of all child body components
    • orderedMap

      protected Map<String,String> orderedMap(String... pairs)
      Creates an ordered map for style building.
      Parameters:
      pairs - alternating key/value pairs (e.g. "color", "red", "margin", "0")
      Returns:
      a LinkedHashMap containing the non-empty key/value pairs
    • addBorderStyles

      protected void addBorderStyles(Map<String,String> styles, String... attrNames)
      Adds border styles from the given attribute names to the style map. Skips empty values and "none". Strips "inner-" prefix for CSS property names.
      Parameters:
      styles - the style map to add border styles to
      attrNames - the border attribute names to look up
    • addIfPresent

      protected void addIfPresent(Map<String,String> styles, String attrName)
      Adds an attribute value to the style map if the attribute is non-empty. The CSS property name defaults to the attribute name.
      Parameters:
      styles - the style map to add the value to
      attrName - the attribute name to look up and use as the CSS property name
    • addIfPresent

      protected void addIfPresent(Map<String,String> styles, String cssName, String attrName)
      Adds an attribute value to the style map under the given CSS property name if the attribute is non-empty.
      Parameters:
      styles - the style map to add the value to
      cssName - the CSS property name to use in the style map
      attrName - the attribute name to look up
    • parseWidth

      protected double parseWidth(String value)
      Parses a CSS unit value to pixels, using the container width for percentages.
      Parameters:
      value - the CSS value to parse (e.g. "50%", "200px")
      Returns:
      the computed width in pixels
    • getChildrenByTags

      protected List<MjmlNode> getChildrenByTags(Set<String> tags)
      Returns child nodes whose tag names are in the given set.
      Parameters:
      tags - the set of tag names to filter by
      Returns:
      a list of matching child nodes
    • registerMediaQuery

      protected void registerMediaQuery(String responsiveClass, String widthSpec)
      Registers a responsive media query for the given CSS class name and width specification.
      Parameters:
      responsiveClass - the CSS class name for the media query
      widthSpec - the width specification (e.g. "200px" or "50")
    • sanitizeContent

      protected String sanitizeContent(String content)
      Applies the configured ContentSanitizer to the given content, if one is set. Returns the content unchanged when no sanitizer is configured.
      Parameters:
      content - the content string to sanitize
      Returns:
      the sanitized content, or the original content if no sanitizer is configured