ArrayHtml - Support comments
authorTim Otten <totten@civicrm.org>
Tue, 29 Oct 2019 22:31:06 +0000 (15:31 -0700)
committerCiviCRM <info@civicrm.org>
Wed, 16 Sep 2020 02:13:19 +0000 (19:13 -0700)
Before
------

HTML comments appear in the array as NULL values

After
-----

HTML comments appear in the array as `['#comment' => '...']`

Technical Notes
---------------

* Considered using `['#tag' => 'comment', '#children' => '...'], but this is ambiguous when you
  have a node/tag named '<comment>'
* Considered using `['#tag' => 'comment', '#children' => '...'], but it's needlessly difficult to
  extract the comment text from under `'#children'`.

ext/afform/core/CRM/Afform/ArrayHtml.php
ext/afform/mock/tests/phpunit/api/v4/AfformTest.php
ext/afform/mock/tests/phpunit/api/v4/formatExamples/comments.php [new file with mode: 0644]

index a3086c514a4469d1fb5c3c8190e532dad6cdb9e1..98204aa65f7f5d830cb2494b3665fcbc618d3a3b 100644 (file)
@@ -59,6 +59,14 @@ class CRM_Afform_ArrayHtml {
       return '';
     }
 
+    if (isset($array['#comment'])) {
+      if (strpos($array['#comment'], '-->')) {
+        Civi::log()->warning('Afform: Cannot store comment with text "-->". Munging.');
+        $array['#comment'] = str_replace('-->', '-- >', $array['#comment']);
+      }
+      return sprintf('<!--%s-->', $array['#comment']);
+    }
+
     $tag = empty($array['#tag']) ? self::DEFAULT_TAG : $array['#tag'];
     unset($array['#tag']);
     $children = empty($array['#children']) ? [] : $array['#children'];
@@ -153,7 +161,8 @@ class CRM_Afform_ArrayHtml {
       return $node->textContent;
     }
     elseif ($node instanceof DOMComment) {
-      // FIXME: How to preserve comments? For the moment, discarding them.
+      $arr = ['#comment' => $node->nodeValue];
+      return $arr;
     }
     else {
       throw new \RuntimeException("Unrecognized DOM node");
index 606ac9c29a44032829201271cba63168ee397b42..f63272b6fe3c800efdf6c0cff076334029e9e3a2 100644 (file)
@@ -65,7 +65,7 @@ class api_v4_AfformTest extends api_v4_AfformTestCase {
   public function getFormatExamples() {
     $es = [];
 
-    foreach (['empty', 'string', 'apple', 'banana', 'cherry'] as $exampleName) {
+    foreach (['empty', 'string', 'comments', 'apple', 'banana', 'cherry'] as $exampleName) {
       $exampleFile = '/formatExamples/' . $exampleName . '.php';
       $example = require __DIR__ . $exampleFile;
       $formats = ['html', 'shallow', 'deep'];
diff --git a/ext/afform/mock/tests/phpunit/api/v4/formatExamples/comments.php b/ext/afform/mock/tests/phpunit/api/v4/formatExamples/comments.php
new file mode 100644 (file)
index 0000000..248cffd
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+
+return [
+  'html' => '<div>One<!-- uno --> Two <!--dos & so on --> Three</div><!--tres-a--b---c-->',
+  'shallow' => [
+    [
+      '#tag' => 'div',
+      '#children' => [
+        'One',
+        ['#comment' => ' uno '],
+        ' Two ',
+        ['#comment' => 'dos & so on '],
+        ' Three',
+      ],
+    ],
+    ['#comment' => 'tres-a--b---c'],
+  ],
+  'deep' => [
+    [
+      '#tag' => 'div',
+      '#children' => [
+        'One',
+        ['#comment' => ' uno '],
+        ' Two ',
+        ['#comment' => 'dos & so on '],
+        ' Three',
+      ],
+    ],
+    ['#comment' => 'tres-a--b---c'],
+  ],
+];