@hmcts/ccd-case-ui-toolkit 7.4.3-redact → 7.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -27404,8 +27404,12 @@ class WriteRichTextAreaFieldComponent extends AbstractFieldWriteComponent {
27404
27404
  this.removeUnsupportedMarkup(documentElement);
27405
27405
  this.normaliseDateRangeSpacing(documentElement);
27406
27406
  this.removeUnsupportedAttributes(documentElement);
27407
+ const hasMeaningfulContent = this.hasMeaningfulRichTextContent(documentElement);
27408
+ if (hasMeaningfulContent) {
27409
+ this.preserveDocmosisBlankParagraphs(documentElement);
27410
+ }
27407
27411
  const sanitisedValue = sanitiseRichTextDocument(documentElement);
27408
- return this.hasMeaningfulRichTextContent(documentElement)
27412
+ return hasMeaningfulContent
27409
27413
  ? this.normalisePlainTextValue(sanitisedValue)
27410
27414
  : '';
27411
27415
  }
@@ -27425,11 +27429,22 @@ class WriteRichTextAreaFieldComponent extends AbstractFieldWriteComponent {
27425
27429
  this.removeUnsupportedMarkup(documentElement);
27426
27430
  this.normaliseDateRangeSpacing(documentElement);
27427
27431
  this.removeUnsupportedAttributes(documentElement);
27432
+ const hasMeaningfulContent = this.hasMeaningfulRichTextContent(documentElement);
27433
+ if (hasMeaningfulContent) {
27434
+ this.preserveDocmosisBlankParagraphs(documentElement);
27435
+ }
27428
27436
  const sanitisedValue = sanitiseRichTextDocument(documentElement);
27429
- return this.hasMeaningfulRichTextContent(documentElement)
27437
+ return hasMeaningfulContent
27430
27438
  ? this.normalisePlainTextValue(sanitisedValue)
27431
27439
  : '';
27432
27440
  }
27441
+ /**
27442
+ * Gives intentionally blank paragraphs content so Docmosis preserves them as blank lines.
27443
+ * This runs only when the document has meaningful content, so a completely empty field remains empty.
27444
+ */
27445
+ preserveDocmosisBlankParagraphs(documentElement) {
27446
+ this.replaceBlankParagraphContent(documentElement, '\u00a0');
27447
+ }
27433
27448
  hasMeaningfulRichTextContent(documentElement) {
27434
27449
  const visibleText = (documentElement.body.textContent || '')
27435
27450
  .replace(/[\s\u00a0\u200b-\u200d\ufeff]/g, '');
@@ -27550,7 +27565,8 @@ class WriteRichTextAreaFieldComponent extends AbstractFieldWriteComponent {
27550
27565
  emitEvent: false,
27551
27566
  emitModelToViewChange: false
27552
27567
  });
27553
- if (normalisedValue || this.editorHasMeaningfulRichTextContent()) {
27568
+ if ((normalisedValue || this.editorHasMeaningfulRichTextContent())
27569
+ && !this.differsOnlyByDocmosisBlankParagraphs(value, normalisedValue)) {
27554
27570
  this.editor.setContent(normalisedValue || '');
27555
27571
  }
27556
27572
  }
@@ -27558,6 +27574,34 @@ class WriteRichTextAreaFieldComponent extends AbstractFieldWriteComponent {
27558
27574
  this.isNormalisingValue = false;
27559
27575
  }
27560
27576
  }
27577
+ differsOnlyByDocmosisBlankParagraphs(value, normalisedValue) {
27578
+ if (!value || !normalisedValue) {
27579
+ return false;
27580
+ }
27581
+ const originalDocument = new DOMParser().parseFromString(value, 'text/html');
27582
+ const normalisedDocument = new DOMParser().parseFromString(normalisedValue, 'text/html');
27583
+ this.clearBlankParagraphs(originalDocument);
27584
+ this.clearBlankParagraphs(normalisedDocument);
27585
+ return originalDocument.body.innerHTML === normalisedDocument.body.innerHTML;
27586
+ }
27587
+ /**
27588
+ * Canonicalises visually blank paragraphs to <p></p> before comparing two HTML values.
27589
+ * This lets the editor avoid reloading when only the Docmosis blank-line representation changed.
27590
+ */
27591
+ clearBlankParagraphs(documentElement) {
27592
+ this.replaceBlankParagraphContent(documentElement, '');
27593
+ }
27594
+ replaceBlankParagraphContent(documentElement, replacement) {
27595
+ const paragraphs = Array.prototype.slice.call(documentElement.body.querySelectorAll('p'));
27596
+ paragraphs.forEach((paragraph) => {
27597
+ // Ignore standard whitespace (\s), non-breaking spaces (U+00A0), zero-width characters
27598
+ // (U+200B–U+200D), and the byte-order mark (U+FEFF) when checking for visible text.
27599
+ const visibleText = (paragraph.textContent || '').replace(/[\s\u00a0\u200b-\u200d\ufeff]/g, '');
27600
+ if (!visibleText && !paragraph.querySelector('hr')) {
27601
+ paragraph.textContent = replacement;
27602
+ }
27603
+ });
27604
+ }
27561
27605
  editorHasMeaningfulRichTextContent() {
27562
27606
  const documentNode = this.editor.view.state.doc;
27563
27607
  const visibleText = documentNode.textContent.replace(/[\s\u00a0\u200b-\u200d\ufeff]/g, '');