Skip to content

Add Tiptap rich text editor form type (TextEditorType)#121

Merged
pierredup merged 4 commits into
mainfrom
tiptap-editor-form-type
Jun 16, 2026
Merged

Add Tiptap rich text editor form type (TextEditorType)#121
pierredup merged 4 commits into
mainfrom
tiptap-editor-form-type

Conversation

@pierredup

Copy link
Copy Markdown
Member

Summary

Adds a secure, opinionated Tiptap-based rich text editor form type (TextEditorType) that any application can use to progressively enhance a standard textarea.

Note: this branch also carries earlier commits (security/2FA config redesign, Rector config, doctrine/orm 3 support). The new work in this PR is the rich text editor described below.

Rich text editor (TextEditorType)

  • Form/Type/TextEditorType.php — extends TextareaType so it degrades gracefully without JavaScript. Auto-registered via the bundle's existing services.php. Options:
    • output_format: html (default, sanitized HTML string) or json (validated Tiptap/ProseMirror document)
    • json_as_array: store JSON as a decoded PHP array or a JSON string
    • toolbar: minimal / default / full preset
    • allowed_tags, sanitizer, placeholder, editor_height
  • Form/TextEditor/ToolbarPreset.php — single source of truth mapping each preset to its toolbar buttons and sanitization allow-lists (HTML tags, ProseMirror nodes/marks, heading levels), so the UI and the server filter can't drift apart.
  • Form/TextEditor/HtmlSanitizerFactory.php — opinionated HtmlSanitizer config (safe link schemes only, forced rel="noopener noreferrer").
  • Form/DataTransformer/SanitizeHtmlTransformer.php — sanitizes submitted HTML on the server (the real security boundary).
  • Form/DataTransformer/JsonDocumentTransformer.php — validates/sanitizes Tiptap JSON, rejecting disallowed nodes/marks/heading levels and stripping unsafe link URLs.

Frontend

  • assets/controllers/text_editor_controller.ts — Stimulus controller mounting Tiptap (StarterKit + Link + Placeholder), wiring server-rendered toolbar buttons to editor commands, syncing content back into the hidden textarea, with Turbo-safe cleanup.
  • assets/scss/_text-editor.scss — Tabler/Bootstrap-matched styling for the toolbar and .ProseMirror content area (imported in platform.scss).
  • Tiptap v2 dependencies and the text-editor controller registered in assets/package.json.

Twig, docs & deps

  • text_editor_widget block added to the platform form theme.
  • docs/form-types/{index,text-editor}.md (linked from docs/index.md), including how to register the form theme and render the output safely.
  • symfony/html-sanitizer added to composer.json.

Security

Sanitization happens in a Symfony data transformer — on the server, independent of the editor — so payloads that bypass the JavaScript editor cannot inject scripts, event handlers, or unsafe URL schemes. Links are restricted to http/https/mailto and forced to carry rel="noopener noreferrer".

Testing

  • TextEditorTypeTest and ToolbarPresetTest20 tests / 51 assertions passing, covering HTML sanitization, output formats, JSON validation/rejection, and option validation.
  • PHPStan (level max) clean on the new code.

The frontend bundler was not run in CI for this change (no Node toolchain available in the dev environment); run cd assets && bun install && bun run build to compile the controller and styles.

Copilot AI review requested due to automatic review settings June 15, 2026 09:56
@coveralls

coveralls commented Jun 15, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 27538745215

Warning

No base build found for commit 4b02f90 on main.
Coverage changes can't be calculated without a base build.
If a base build is processing, this comment will update automatically when it completes.

Coverage: 20.264%

Details

  • Patch coverage: 50 uncovered changes across 2 files (113 of 163 lines covered, 69.33%).

Uncovered Changes

File Changed Covered %
src/Bundle/Platform/Form/DataTransformer/JsonDocumentTransformer.php 74 28 37.84%
src/Bundle/Platform/Form/DataTransformer/SanitizeHtmlTransformer.php 12 8 66.67%
Total (5 files) 163 113 69.33%

Coverage Regressions

Requires a base build to compare against. How to fix this →


Coverage Stats

Coverage Status
Relevant Lines: 3252
Covered Lines: 659
Line Coverage: 20.26%
Coverage Strength: 2.42 hits per line

💛 - Coveralls

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a reusable, progressively-enhanced Tiptap rich text editor Symfony form type (TextEditorType) with server-side sanitization/validation, plus the supporting UI (Stimulus controller, styles, Twig theme) and documentation.

Changes:

  • Introduces TextEditorType with server-side HTML sanitization and optional ProseMirror JSON validation.
  • Adds toolbar presets (ToolbarPreset) as a shared source of truth for UI features and server allow-lists.
  • Adds frontend controller + styling + docs and wires required dependencies.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/Bundle/PlatformBundle/Form/Type/TextEditorTypeTest.php Adds coverage for HTML sanitization, JSON validation, and option validation for TextEditorType.
tests/Bundle/PlatformBundle/Form/TextEditor/ToolbarPresetTest.php Adds coverage for preset feature lists and derived allow-lists.
src/Bundle/Platform/Resources/views/Form/theme.html.twig Adds text_editor_widget Twig block rendering toolbar + editor container + backing textarea.
src/Bundle/Platform/Form/Type/TextEditorType.php New form type wiring toolbar presets + transformers and exposing view vars for the widget/controller.
src/Bundle/Platform/Form/TextEditor/ToolbarPreset.php Defines minimal/default/full presets and derives allowed HTML tags / PM nodes / marks / heading levels.
src/Bundle/Platform/Form/TextEditor/HtmlSanitizerFactory.php Provides opinionated HtmlSanitizer configuration and per-preset element allow-listing.
src/Bundle/Platform/Form/DataTransformer/SanitizeHtmlTransformer.php Sanitizes submitted HTML server-side (security boundary).
src/Bundle/Platform/Form/DataTransformer/JsonDocumentTransformer.php Validates/sanitizes submitted ProseMirror JSON (node/mark allow-lists + link safety).
docs/index.md Adds docs index link for “Form Types”.
docs/form-types/index.md New index page for reusable form types.
docs/form-types/text-editor.md Documents TextEditorType usage, options, build steps, and rendering guidance.
composer.json Adds symfony/html-sanitizer dependency.
assets/scss/platform.scss Imports the new text editor styles.
assets/scss/_text-editor.scss Adds Bootstrap/Tabler-aligned rich editor styling.
assets/package.json Registers text-editor Stimulus controller and adds Tiptap dependencies.
assets/controllers/text_editor_controller.ts Adds Stimulus controller mounting Tiptap, wiring toolbar commands, syncing textarea, and cleanup.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/Bundle/Platform/Form/DataTransformer/JsonDocumentTransformer.php Outdated
Comment thread assets/controllers/text_editor_controller.ts Outdated
pierredup and others added 3 commits June 15, 2026 12:01
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@pierredup pierredup merged commit 8d3cd46 into main Jun 16, 2026
5 of 7 checks passed
@pierredup pierredup deleted the tiptap-editor-form-type branch June 16, 2026 07:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants