feat: Update addHtml to handle style inheritance

The aim is to get the output closer to the source html
This commit is contained in:
Julien Aupart 2020-11-08 20:58:06 +01:00
parent ec1b3d35ee
commit b86c60694c
3 changed files with 51 additions and 8 deletions

View File

@ -109,6 +109,7 @@ abstract class AbstractContainer extends AbstractElement
} else {
// All other elements
array_unshift($args, $element); // Prepend element name to the beginning of args array
return call_user_func_array(array($this, 'addElement'), $args);
}
}

View File

@ -364,7 +364,7 @@ class Html
$cell = $element->addCell(null, $cellStyles);
if (self::shouldAddTextRun($node)) {
return $cell->addTextRun(self::parseInlineStyle($node, $styles['paragraph']));
return $cell->addTextRun(self::filterOutNonInheritedStyles(self::parseInlineStyle($node, $styles['paragraph'])));
}
return $cell;
@ -395,15 +395,51 @@ class Html
*/
protected static function recursiveParseStylesInHierarchy(\DOMNode $node, array $style)
{
$parentStyle = self::parseInlineStyle($node, array());
$style = array_merge($parentStyle, $style);
$parentStyle = array();
if ($node->parentNode != null && XML_ELEMENT_NODE == $node->parentNode->nodeType) {
$style = self::recursiveParseStylesInHierarchy($node->parentNode, $style);
$parentStyle = self::recursiveParseStylesInHierarchy($node->parentNode, array());
}
if ($node->nodeName === '#text') {
$parentStyle = array_merge($parentStyle, $style);
} else {
$parentStyle = self::filterOutNonInheritedStyles($parentStyle);
}
$style = self::parseInlineStyle($node, $parentStyle);
return $style;
}
/**
* Removes non-inherited styles from array
*
* @param array &$styles
*/
protected static function filterOutNonInheritedStyles(array $styles)
{
$nonInheritedStyles = array(
'borderSize',
'borderTopSize',
'borderRightSize',
'borderBottomSize',
'borderLeftSize',
'borderColor',
'borderTopColor',
'borderRightColor',
'borderBottomColor',
'borderLeftColor',
'borderStyle',
'spaceAfter',
'spaceBefore',
'underline',
'strikethrough',
'hidden',
);
$styles = array_diff_key($styles, array_flip($nonInheritedStyles));
return $styles;
}
/**
* Parse list node
*

View File

@ -293,11 +293,11 @@ class HtmlTest extends AbstractWebServerEmbeddedTest
{
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
$html = '<table align="left" style="width: 50%; border: 6px #0000FF solid;">
$html = '<table align="left" style="width: 50%; border: 12px #0000FF double">
<thead>
<tr style="background-color: #FF0000; text-align: center; color: #FFFFFF; font-weight: bold; ">
<th style="width: 50pt">header a</th>
<th style="width: 50; border-color: #00EE00">header b</th>
<tr style="background-color: #FF0000; text-align: center; color: #FFFFFF; font-weight: bold">
<th style="width: 50pt"><p>header a</p></th>
<th style="width: 50; border-color: #00EE00; border-width: 3px"><span>header b</span></th>
<th style="border-color: #00AA00 #00BB00 #00CC00 #00DD00; border-width: 3px">header c</th>
</tr>
</thead>
@ -324,6 +324,12 @@ class HtmlTest extends AbstractWebServerEmbeddedTest
$this->assertEquals('00BB00', $doc->getElementAttribute('/w:document/w:body/w:tbl/w:tr[1]/w:tc[3]/w:tcPr/w:tcBorders/w:right', 'w:color'));
$this->assertEquals('00CC00', $doc->getElementAttribute('/w:document/w:body/w:tbl/w:tr[1]/w:tc[3]/w:tcPr/w:tcBorders/w:bottom', 'w:color'));
$this->assertEquals('00DD00', $doc->getElementAttribute('/w:document/w:body/w:tbl/w:tr[1]/w:tc[3]/w:tcPr/w:tcBorders/w:left', 'w:color'));
//check borders are not propagated inside cells
$this->assertTrue($doc->elementExists('/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:p'));
$this->assertFalse($doc->elementExists('/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:p/w:pPr/w:pBdr'));
$this->assertTrue($doc->elementExists('/w:document/w:body/w:tbl/w:tr[1]/w:tc[2]/w:p'));
$this->assertFalse($doc->elementExists('/w:document/w:body/w:tbl/w:tr[1]/w:tc[2]/w:p/w:pPr/w:pBdr'));
}
/**