From 1ceb0ad28e31508b56bbc1d22fc3aee47e0a173c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Mummert?= Date: Wed, 26 Aug 2026 14:36:28 +0200 Subject: [PATCH] Normalize Quill's non-breaking spaces so rich-text descriptions wrap Quill 2's getSemanticHTML() serializes every space as U+00A0, turning a whole paragraph into one unbreakable word that stretched the survey cards far past the viewport. Normalize to plain spaces when sanitizing (which also heals existing records on every output) and when the editor writes the serialized HTML back into the textarea. Co-Authored-By: Claude Fable 5 --- public/js/survey-rich-text.js | 4 ++++ src/Service/SurveyHtmlSanitizer.php | 10 +++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/public/js/survey-rich-text.js b/public/js/survey-rich-text.js index 782d09c..336baab 100644 --- a/public/js/survey-rich-text.js +++ b/public/js/survey-rich-text.js @@ -15,6 +15,10 @@ function toSemanticHtml(quill) { var html = typeof quill.getSemanticHTML === 'function' ? quill.getSemanticHTML() : quill.root.innerHTML; + // Quill 2 serialisiert Leerzeichen als   – ohne echte Leerzeichen kann + // der Browser den Text nicht umbrechen und das Layout läuft über. + html = html.replace(/ |\u00a0/g, ' '); + // Leerer Editor: kein "

" speichern. if (/^\s*(

(\s| |)*<\/p>\s*)*$/i.test(html)) { return ''; diff --git a/src/Service/SurveyHtmlSanitizer.php b/src/Service/SurveyHtmlSanitizer.php index ad2f593..2cbdf75 100644 --- a/src/Service/SurveyHtmlSanitizer.php +++ b/src/Service/SurveyHtmlSanitizer.php @@ -28,6 +28,11 @@ final class SurveyHtmlSanitizer return ''; } + // Quill 2 serialisiert Leerzeichen als geschützte Leerzeichen ( /U+00A0). + // Ohne echte Leerzeichen kann der Browser Absätze nicht umbrechen – der Text + // sprengt dann das Kartenlayout. Geschützte Leerzeichen sind hier nie gewollt. + $html = str_replace(["\u{00A0}", ' ', ' ', ' ', ' '], ' ', $html); + // Klartext ohne Tags (Altdaten aus dem bisherigen Textarea): Absätze aus // Leerzeilen bilden, einfache Umbrüche als
erhalten. if (!preg_match('#<[a-z/!]#i', $html)) { @@ -70,6 +75,7 @@ final class SurveyHtmlSanitizer $text = (string) preg_replace('##i', "\n", $text); $text = (string) preg_replace('##i', "\n", $text); $text = html_entity_decode(strip_tags($text), ENT_QUOTES | ENT_HTML5, 'UTF-8'); + $text = str_replace("\u{00A0}", ' ', $text); $text = (string) preg_replace("/[ \t]+\n/", "\n", $text); $text = (string) preg_replace("/\n{3,}/", "\n\n", $text); @@ -78,7 +84,9 @@ final class SurveyHtmlSanitizer public function isEmpty(?string $html): bool { - return '' === trim(strip_tags((string) $html)); + $text = str_replace(["\u{00A0}", ' ', ' '], ' ', strip_tags((string) $html)); + + return '' === trim($text); } private function convertPlainTextToHtml(string $text): string