diff --git a/libs/Format/Confluence/ContentPage.php b/libs/Format/Confluence/ContentPage.php index 54be793a..4c0d24e6 100644 --- a/libs/Format/Confluence/ContentPage.php +++ b/libs/Format/Confluence/ContentPage.php @@ -36,6 +36,11 @@ function ($src, array $attributes, Entry $file) { } ); + if (str_contains($content, 'convert($content); + } + $intro = ''; if ($this->config->getConfluenceConfiguration()->hasHeader()) { $intro = '' . $this->config->getConfluenceConfiguration()->getHeader() . ''; diff --git a/libs/Format/Confluence/DetailsToExpand.php b/libs/Format/Confluence/DetailsToExpand.php new file mode 100644 index 00000000..97e9898f --- /dev/null +++ b/libs/Format/Confluence/DetailsToExpand.php @@ -0,0 +1,78 @@ +loadHTML($content, LIBXML_HTML_NODEFDTD | LIBXML_HTML_NOIMPLIED); + libxml_clear_errors(); + + $detailElements = $dom->getElementsByTagName('details'); + + $count = $detailElements->length; + for ($i = $count - 1; $i >= 0; --$i) { + $this->convertOne($detailElements->item($i)); + } + + return $dom->saveHTML(); + } + + protected function findSummary(\DOMElement $element): ?\DOMElement + { + if ($element->childElementCount == 0) { + return null; + } + + foreach ($element->childNodes as $child) { + if ($child->nodeName == 'summary') { + return $child; + } + } + + return null; + } + + protected function convertOne(\DOMElement $element) + { + /* + +   This is my message +    +     

This text is hidden until you expand it.

+   
+
+ */ + + $summary = $this->findSummary($element); + if (!$summary) { + // If we can't find a title we don't try to convert to expandable + return; + } + + // Create new title node + $title = $element->ownerDocument->createElement('ac:parameter'); + $title->setAttribute('ac:name', ''); + $titleChildNodes = $summary->childNodes; + while ($titleChildNodes->length > 0) { + $title->appendChild($titleChildNodes->item(0)); + } + $element->removeChild($summary); + + // Create body node + $body = $element->ownerDocument->createElement('ac:rich-text-body'); + $childNodes = $element->childNodes; + while ($childNodes->length > 0) { + $body->appendChild($childNodes->item(0)); + } + + // Assemble the macro + $macro = $element->ownerDocument->createElement('ac:structured-macro'); + $macro->setAttribute('ac:name', 'expand'); + $macro->appendChild($title); + $macro->appendChild($body); + + $element->parentNode->replaceChild($macro, $element); + } +} diff --git a/tests/Format/Confluence/DetailsToExpandTest.php b/tests/Format/Confluence/DetailsToExpandTest.php new file mode 100644 index 00000000..21aff67a --- /dev/null +++ b/tests/Format/Confluence/DetailsToExpandTest.php @@ -0,0 +1,102 @@ + + Title ! + + + + + EOD, + <<<'EOD' + Title ! + +
    +
  • Item 1
  • +
  • Item 2
  • +
+
+ EOD + ], + [ + // Don't convert without title + <<<'EOD' +
+ + + +
+ EOD, + <<<'EOD' +
+ +
+ EOD + ], + [ + // Convert nested + <<<'EOD' +
+ Title ! + + + +
+ Inner title + +

Some Text

+ +
+
+ EOD, + <<<'EOD' + Title ! + +
    +
  • Item 1
  • +
  • Item 2
  • +
+ Inner title + +

Some Text

+
+
+ EOD + ], + ]; + } + + /** + * @dataProvider provideExpandData + * + * @param mixed $input + * @param mixed $expected + */ + public function testDetailsToExpand($input, $expected) + { + $expander = new DetailsToExpand(); + + $this->assertEquals($expected, preg_replace("/\n\n/", "\n", trim($expander->convert($input)))); + } +}