Skip to content

Multiline string children in <textarea> are corrupted by pretty-print indentation #44

Description

@glanzel

Summary

When rendering native HTML elements, PyJSX indents all child content for pretty-printed output. For elements where text content is semantically significant (especially <textarea>), this mutates the actual value.

Multiline strings passed as children are indented line-by-line, which breaks use cases like rich-text editors, form fields, or any textarea whose value must round-trip unchanged.

Environment

  • python-jsx / PyJSX: 0.4.0
  • Python: 3.12

Steps to reproduce

# coding: jsx
import pyjsx.auto_setup
from pyjsx import jsx

def TextareaField(value: str):
    return <textarea name="body">{value}</textarea>

html = str(TextareaField("line1\n\nline2"))
print(repr(html))

Actual output

<textarea name="body">
    line1
    
    line2
</textarea>

Expected output

The textarea text content should be exactly line1\n\nline2, without added leading spaces.

Impact

We use PyJSX for an admin UI with a Markdown rich-text editor. Markdown loaded from the DB is rendered into a hidden textarea. PyJSX adds leading spaces to every line (worse in nested components). Markdown parsers then treat the content as a code block, the editor shows raw markdown, and saving persists corrupted content.

Likely also affects <pre>, <script>, <style>, and <title>.

Cause

pyjsx/jsx.py applies indent() to string children:

children_formatted = "\n".join(indent(str(child)) for child in children)

Suggested fix

Do not indent plain string children, at least for RCDATA/RAWTEXT elements like <textarea>. Alternatively, never indent str children and only pretty-print nested elements.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions