From: Coleman Watts Date: Sat, 30 Nov 2019 15:52:33 +0000 (-0500) Subject: In shallow mode, only convert markup to array that the GUI editor understands. X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=37b66ed682b6fb5c3401f7f997907d903f58de6e;p=civicrm-core.git In shallow mode, only convert markup to array that the GUI editor understands. Any markup not using a tag/class/attribute understood by the GUI editor will have its contents preserved "as-is" in a "#markup" string. --- diff --git a/ext/afform/core/CRM/Afform/ArrayHtml.php b/ext/afform/core/CRM/Afform/ArrayHtml.php index b0dae5fe7e..59c8cae0a5 100644 --- a/ext/afform/core/CRM/Afform/ArrayHtml.php +++ b/ext/afform/core/CRM/Afform/ArrayHtml.php @@ -125,7 +125,7 @@ class CRM_Afform_ArrayHtml { } } - if (isset($array['#markup']) && !$this->formatWhitespace) { + if (isset($array['#markup']) && (!$this->formatWhitespace || strpos($array['#markup'], '<') === FALSE)) { $buf .= '>' . $array['#markup'] . ''; } elseif (isset($array['#markup'])) { @@ -179,6 +179,7 @@ class CRM_Afform_ArrayHtml { } $doc = new DOMDocument(); + $doc->preserveWhiteSpace = !$this->formatWhitespace; @$doc->loadHTML("$html"); // FIXME: Validate expected number of child nodes @@ -205,8 +206,8 @@ class CRM_Afform_ArrayHtml { $arr[$attribute->name] = $this->decodeAttrValue($type, $txt); } if ($node->childNodes->length > 0) { - // In shallow mode, return "af-markup" containers as-is - if (!$this->deepCoding && !empty($arr['class']) && strpos($arr['class'], 'af-markup') !== FALSE) { + // In shallow mode, return markup as-is if node isn't supported by the gui editor + if (!$this->deepCoding && !$this->isNodeEditable($arr)) { $arr['#markup'] = ''; foreach ($node->childNodes as $child) { $arr['#markup'] .= $child->ownerDocument->saveXML($child); @@ -335,4 +336,19 @@ class CRM_Afform_ArrayHtml { } } + /** + * Determine if a node is recognized by the gui editor. + * + * @param array $item + * @return bool + */ + public function isNodeEditable(array $item) { + if ($item['#tag'] === 'af-field' || $item['#tag'] === 'af-form' || isset($item['af-fieldset'])) { + return TRUE; + } + $editableClasses = ['af-block', 'af-text', 'af-button']; + $classes = explode(' ', $item['class'] ?? ''); + return (bool) array_intersect($editableClasses, $classes); + } + } diff --git a/ext/afform/mock/tests/phpunit/api/v4/AfformTest.php b/ext/afform/mock/tests/phpunit/api/v4/AfformTest.php index 6a7fdd87e1..45bc30c2dc 100644 --- a/ext/afform/mock/tests/phpunit/api/v4/AfformTest.php +++ b/ext/afform/mock/tests/phpunit/api/v4/AfformTest.php @@ -9,6 +9,25 @@ class api_v4_AfformTest extends api_v4_AfformTestCase { use \Civi\Test\Api3TestTrait; use \Civi\Test\ContactTestTrait; + /** + * DOMDocument outputs some tags a little different than they were input. + * It's not really a problem but can trip up tests. + * + * @param array|string $markup + * @return array|string + */ + private function fudgeMarkup($markup) { + if (is_array($markup)) { + foreach ($markup as $idx => $item) { + $markup[$idx] = $this->fudgeMarkup($item); + } + return $markup; + } + else { + return str_replace([' />', '/>'], ['/>', ' />'], $markup); + } + } + public function getBasicDirectives() { return [ ['mockPage', ['title' => '', 'description' => '', 'server_route' => 'civicrm/mock-page']], @@ -117,7 +136,7 @@ class api_v4_AfformTest extends api_v4_AfformTestCase { ->setLayoutFormat($readFormat) ->execute(); - $this->assertEquals($readLayout, $result[0]['layout'], "Based on \"$exampleName\", writing content as \"$updateFormat\" and reading back as \"$readFormat\"."); + $this->assertEquals($readLayout, $this->fudgeMarkup($result[0]['layout']), "Based on \"$exampleName\", writing content as \"$updateFormat\" and reading back as \"$readFormat\"."); Civi\Api4\Afform::revert()->addWhere('name', '=', $formName)->execute(); } @@ -152,7 +171,7 @@ class api_v4_AfformTest extends api_v4_AfformTestCase { ->execute() ->first(); - $this->assertEquals($example['stripped'] ?? $example['shallow'], $result['layout']); + $this->assertEquals($example['stripped'] ?? $example['shallow'], $this->fudgeMarkup($result['layout'])); Civi\Api4\Afform::save() ->addRecord(['name' => $directiveName, 'layout' => $result['layout']]) @@ -166,7 +185,7 @@ class api_v4_AfformTest extends api_v4_AfformTestCase { ->execute() ->first(); - $this->assertEquals($example['pretty'], $result['layout']); + $this->assertEquals($example['pretty'], $this->fudgeMarkup($result['layout'])); } public function testAutoRequires() { diff --git a/ext/afform/mock/tests/phpunit/api/v4/formatExamples/apple.php b/ext/afform/mock/tests/phpunit/api/v4/formatExamples/apple.php index d0674fc335..18a4bb0eab 100644 --- a/ext/afform/mock/tests/phpunit/api/v4/formatExamples/apple.php +++ b/ext/afform/mock/tests/phpunit/api/v4/formatExamples/apple.php @@ -4,7 +4,7 @@ return [ 'html' => 'New text!', 'pretty' => "New text!\n", 'shallow' => [ - ['#tag' => 'strong', '#children' => [['#text' => 'New text!']]], + ['#tag' => 'strong', '#markup' => 'New text!'], ], 'deep' => [ ['#tag' => 'strong', '#children' => [['#text' => 'New text!']]], diff --git a/ext/afform/mock/tests/phpunit/api/v4/formatExamples/banana.php b/ext/afform/mock/tests/phpunit/api/v4/formatExamples/banana.php index 4e2e63db3c..da70ac501c 100644 --- a/ext/afform/mock/tests/phpunit/api/v4/formatExamples/banana.php +++ b/ext/afform/mock/tests/phpunit/api/v4/formatExamples/banana.php @@ -1,17 +1,20 @@ '
New text!
', - 'pretty' => '
- New text! + 'html' => '
New text! No whitespace!
', + 'pretty' => '
+ New text! + No whitespace!
', 'stripped' => [ [ '#tag' => 'div', + 'class' => 'af-block', '#children' => [ - ['#tag' => 'strong', '#children' => [['#text' => 'New text!']]], + ['#tag' => 'strong', '#markup' => ' New text!'], + ['#tag' => 'strong', 'class' => 'af-text', '#children' => [['#text' => 'No whitespace!']]], ['#tag' => 'af-field', 'name' => 'do_not_sms', 'defn' => "{label: 'Do not do any of the emailing'}"], ], ], @@ -19,8 +22,10 @@ return [ 'shallow' => [ [ '#tag' => 'div', + 'class' => 'af-block', '#children' => [ - ['#tag' => 'strong', '#children' => [['#text' => ' New text!']]], + ['#tag' => 'strong', '#markup' => ' New text!'], + ['#tag' => 'strong', 'class' => 'af-text', '#children' => [['#text' => ' No whitespace! ']]], ['#tag' => 'af-field', 'name' => 'do_not_sms', 'defn' => "{label: 'Do not do any of the emailing'}"], ], ], @@ -28,8 +33,10 @@ return [ 'deep' => [ [ '#tag' => 'div', + 'class' => 'af-block', '#children' => [ ['#tag' => 'strong', '#children' => [['#text' => ' New text!']]], + ['#tag' => 'strong', 'class' => 'af-text', '#children' => [['#text' => ' No whitespace! ']]], ['#tag' => 'af-field', 'name' => 'do_not_sms', 'defn' => ['label' => 'Do not do any of the emailing']], ], ], diff --git a/ext/afform/mock/tests/phpunit/api/v4/formatExamples/cherry.php b/ext/afform/mock/tests/phpunit/api/v4/formatExamples/cherry.php index 44376d4cd9..4060cfb6c8 100644 --- a/ext/afform/mock/tests/phpunit/api/v4/formatExamples/cherry.php +++ b/ext/afform/mock/tests/phpunit/api/v4/formatExamples/cherry.php @@ -1,20 +1,21 @@ 'First Second', - 'pretty' => "First\nSecond\n", - 'shallow' => [ - ['#tag' => 'span', '#children' => [['#text' => 'First']]], - ['#text' => ' '], - ['#tag' => 'span', '#children' => [['#text' => 'Second']]], - ], + 'html' => 'First Second', + 'pretty' => "First +Second\n", 'stripped' => [ - ['#tag' => 'span', '#children' => [['#text' => 'First']]], - ['#tag' => 'span', '#children' => [['#text' => 'Second']]], + ['#tag' => 'span', '#markup' => 'First'], + ['#tag' => 'span', '#markup' => 'Second'], + ], + 'shallow' => [ + ['#tag' => 'span', '#markup' => 'First'], + ['#text' => ' '], + ['#tag' => 'span', '#markup' => 'Second'], ], 'deep' => [ ['#tag' => 'span', '#children' => [['#text' => 'First']]], - ['#text' => ' '], + ['#text' => ' '], ['#tag' => 'span', '#children' => [['#text' => 'Second']]], ], ]; diff --git a/ext/afform/mock/tests/phpunit/api/v4/formatExamples/comments.php b/ext/afform/mock/tests/phpunit/api/v4/formatExamples/comments.php index c311e930e6..e060fb6b53 100644 --- a/ext/afform/mock/tests/phpunit/api/v4/formatExamples/comments.php +++ b/ext/afform/mock/tests/phpunit/api/v4/formatExamples/comments.php @@ -5,13 +5,7 @@ return [ 'shallow' => [ [ '#tag' => 'div', - '#children' => [ - ['#text' => 'One'], - ['#comment' => ' uno '], - ['#text' => ' Two '], - ['#comment' => 'dos & so on '], - ['#text' => ' Three'], - ], + '#markup' => 'One Two Three', ], ['#comment' => 'tres-a--b---c'], ], diff --git a/ext/afform/mock/tests/phpunit/api/v4/formatExamples/self-closing.php b/ext/afform/mock/tests/phpunit/api/v4/formatExamples/self-closing.php index 62063a8087..3132e0b4c2 100644 --- a/ext/afform/mock/tests/phpunit/api/v4/formatExamples/self-closing.php +++ b/ext/afform/mock/tests/phpunit/api/v4/formatExamples/self-closing.php @@ -5,20 +5,13 @@ return [ 'pretty' => '
-
-
+

', 'shallow' => [ ['#tag' => 'span', 'class' => 'one'], ['#tag' => 'img', 'class' => 'two'], - [ - '#tag' => 'div', - '#children' => [ - ['#tag' => 'br', 'class' => 'three'], - ['#tag' => 'br'], - ], - ], + ['#tag' => 'div', '#markup' => '

'], ], 'deep' => [ ['#tag' => 'span', 'class' => 'one'], diff --git a/ext/afform/mock/tests/phpunit/api/v4/formatExamples/stylized.php b/ext/afform/mock/tests/phpunit/api/v4/formatExamples/stylized.php index f99f6ba756..65aaede619 100644 --- a/ext/afform/mock/tests/phpunit/api/v4/formatExamples/stylized.php +++ b/ext/afform/mock/tests/phpunit/api/v4/formatExamples/stylized.php @@ -2,21 +2,21 @@ return [ 'html' => '

Stylized text is wonky text!

', - 'pretty' => "

Stylized text is wonky text!

\n", + 'pretty' => "

+ Stylized text is wonky text! +

\n", 'shallow' => [ - ['#tag' => 'p', '#children' => [ - ['#tag' => 'strong', '#children' => [['#text' => 'Stylized']]], - ['#text' => ' text is '], - ['#tag' => 'em', '#children' => [['#text' => 'wonky']]], - ['#text' => ' text!'], - ]], + ['#tag' => 'p', '#markup' => 'Stylized text is wonky text!'], ], 'deep' => [ - ['#tag' => 'p', '#children' => [ - ['#tag' => 'strong', '#children' => [['#text' => 'Stylized']]], - ['#text' => ' text is '], - ['#tag' => 'em', '#children' => [['#text' => 'wonky']]], - ['#text' => ' text!'], - ]], + [ + '#tag' => 'p', + '#children' => [ + ['#tag' => 'strong', '#children' => [['#text' => 'Stylized']]], + ['#text' => ' text is '], + ['#tag' => 'em', '#children' => [['#text' => 'wonky']]], + ['#text' => ' text!'], + ], + ], ], ];