Skip to content

Commit b86c606

Browse files
committed
feat: Update addHtml to handle style inheritance
The aim is to get the output closer to the source html
1 parent ec1b3d3 commit b86c606

File tree

3 files changed

+51
-8
lines changed

3 files changed

+51
-8
lines changed

src/PhpWord/Element/AbstractContainer.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ public function __call($function, $args)
109109
} else {
110110
// All other elements
111111
array_unshift($args, $element); // Prepend element name to the beginning of args array
112+
112113
return call_user_func_array(array($this, 'addElement'), $args);
113114
}
114115
}

src/PhpWord/Shared/Html.php

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ protected static function parseCell($node, $element, &$styles)
364364
$cell = $element->addCell(null, $cellStyles);
365365

366366
if (self::shouldAddTextRun($node)) {
367-
return $cell->addTextRun(self::parseInlineStyle($node, $styles['paragraph']));
367+
return $cell->addTextRun(self::filterOutNonInheritedStyles(self::parseInlineStyle($node, $styles['paragraph'])));
368368
}
369369

370370
return $cell;
@@ -395,15 +395,51 @@ protected static function shouldAddTextRun(\DOMNode $node)
395395
*/
396396
protected static function recursiveParseStylesInHierarchy(\DOMNode $node, array $style)
397397
{
398-
$parentStyle = self::parseInlineStyle($node, array());
399-
$style = array_merge($parentStyle, $style);
398+
$parentStyle = array();
400399
if ($node->parentNode != null && XML_ELEMENT_NODE == $node->parentNode->nodeType) {
401-
$style = self::recursiveParseStylesInHierarchy($node->parentNode, $style);
400+
$parentStyle = self::recursiveParseStylesInHierarchy($node->parentNode, array());
402401
}
402+
if ($node->nodeName === '#text') {
403+
$parentStyle = array_merge($parentStyle, $style);
404+
} else {
405+
$parentStyle = self::filterOutNonInheritedStyles($parentStyle);
406+
}
407+
$style = self::parseInlineStyle($node, $parentStyle);
403408

404409
return $style;
405410
}
406411

412+
/**
413+
* Removes non-inherited styles from array
414+
*
415+
* @param array &$styles
416+
*/
417+
protected static function filterOutNonInheritedStyles(array $styles)
418+
{
419+
$nonInheritedStyles = array(
420+
'borderSize',
421+
'borderTopSize',
422+
'borderRightSize',
423+
'borderBottomSize',
424+
'borderLeftSize',
425+
'borderColor',
426+
'borderTopColor',
427+
'borderRightColor',
428+
'borderBottomColor',
429+
'borderLeftColor',
430+
'borderStyle',
431+
'spaceAfter',
432+
'spaceBefore',
433+
'underline',
434+
'strikethrough',
435+
'hidden',
436+
);
437+
438+
$styles = array_diff_key($styles, array_flip($nonInheritedStyles));
439+
440+
return $styles;
441+
}
442+
407443
/**
408444
* Parse list node
409445
*

tests/PhpWord/Shared/HtmlTest.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -293,11 +293,11 @@ public function testParseTable()
293293
{
294294
$phpWord = new \PhpOffice\PhpWord\PhpWord();
295295
$section = $phpWord->addSection();
296-
$html = '<table align="left" style="width: 50%; border: 6px #0000FF solid;">
296+
$html = '<table align="left" style="width: 50%; border: 12px #0000FF double">
297297
<thead>
298-
<tr style="background-color: #FF0000; text-align: center; color: #FFFFFF; font-weight: bold; ">
299-
<th style="width: 50pt">header a</th>
300-
<th style="width: 50; border-color: #00EE00">header b</th>
298+
<tr style="background-color: #FF0000; text-align: center; color: #FFFFFF; font-weight: bold">
299+
<th style="width: 50pt"><p>header a</p></th>
300+
<th style="width: 50; border-color: #00EE00; border-width: 3px"><span>header b</span></th>
301301
<th style="border-color: #00AA00 #00BB00 #00CC00 #00DD00; border-width: 3px">header c</th>
302302
</tr>
303303
</thead>
@@ -324,6 +324,12 @@ public function testParseTable()
324324
$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'));
325325
$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'));
326326
$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'));
327+
328+
//check borders are not propagated inside cells
329+
$this->assertTrue($doc->elementExists('/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:p'));
330+
$this->assertFalse($doc->elementExists('/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:p/w:pPr/w:pBdr'));
331+
$this->assertTrue($doc->elementExists('/w:document/w:body/w:tbl/w:tr[1]/w:tc[2]/w:p'));
332+
$this->assertFalse($doc->elementExists('/w:document/w:body/w:tbl/w:tr[1]/w:tc[2]/w:p/w:pPr/w:pBdr'));
327333
}
328334

329335
/**

0 commit comments

Comments
 (0)