Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions CHANGELOG-GRAVITYPDF.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ Read this section before upgrading from upstream mPDF. Each entry says what chan
* Important declarations apply after the inline style: those of the stylesheets by specificity and then order, then those of `style=""`, then those of the default stylesheet (`defaultCssFile`), as a browser's own important declarations beat a page's.
* A shorthand marked `!important` makes every longhand it sets important, so `border: 1mm solid green !important` beats a `border-top-color` of a more specific rule or of a later declaration in the same block.
* `@page` rules, `body` rules and the class rules SVG text looks up take an important declaration over a later one of the same selector that is not. An important declaration of a `body` rule beats `<body style>`.
* **HTML attributes that style an element are read only where HTML defines them**, as a browser reads them, in standard mode. Set `'cssMode' => \Mpdf\CssMode::LEGACY` to keep the old reading. [#531] [#641]
* `color` applies to `font` and `hr` only, `width` to images, tables, cells, `hr`, `meter` and `progress`, `height` to images, tables, rows, row groups, cells, `meter` and `progress`, `valign` to rows, row groups and cells, `vspace` and `hspace` to images, and `align` to `div`, `p`, headings, table parts, `caption`, `hr` and `img`. So `<a color>`, `<span color>`, `<p color>`, `<td color>`, `<div width>`, `<img valign>` and `<blockquote align>` no longer do anything. mPDF's own tags, such as `<barcode color>`, keep every attribute.
* A stylesheet rule beats the attribute everywhere. Before, `align` on a paragraph, div or table cell, `nowrap` on a cell, `border` on a table, `<caption align>`, `<hr width>` in a table cell and `align` on a text field beat any rule for the same property.
* `<div align>` passes its alignment on to what it holds, and `<li type>` beats the marker the item inherits from its list.
* Attributes mPDF ignored now take effect: `<hr align>`, `<hr size>`, `<img align>` (float left or right, or vertical alignment), `<img border>`, `<thead align>`, and `<table border>` wider than 1.
* A table's `border` gives each cell a 1px border of its own, which a rule for the table's border leaves alone. Before, the cells copied the table's border.

New features
------------
Expand Down Expand Up @@ -800,6 +806,7 @@ These changes do not change output.
[#526]: https://github.com/GravityPDF/mpdf/issues/526
[#527]: https://github.com/GravityPDF/mpdf/issues/527
[#528]: https://github.com/GravityPDF/mpdf/issues/528
[#531]: https://github.com/GravityPDF/mpdf/issues/531
[#532]: https://github.com/GravityPDF/mpdf/issues/532
[#533]: https://github.com/GravityPDF/mpdf/issues/533
[#535]: https://github.com/GravityPDF/mpdf/issues/535
Expand Down Expand Up @@ -852,8 +859,9 @@ These changes do not change output.
[#632]: https://github.com/GravityPDF/mpdf/issues/632
[#633]: https://github.com/GravityPDF/mpdf/pull/633
[#634]: https://github.com/GravityPDF/mpdf/pull/634
[#635]: https://github.com/GravityPDF/mpdf/pull/635
[#636]: https://github.com/GravityPDF/mpdf/issues/636
[#637]: https://github.com/GravityPDF/mpdf/pull/637
[#635]: https://github.com/GravityPDF/mpdf/pull/635
[#639]: https://github.com/GravityPDF/mpdf/pull/639
[#638]: https://github.com/GravityPDF/mpdf/pull/638
[#639]: https://github.com/GravityPDF/mpdf/pull/639
[#641]: https://github.com/GravityPDF/mpdf/pull/641
65 changes: 38 additions & 27 deletions src/Css/CssMerger.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ class CssMerger
*/
private $borderMerger;

/**
* @var \Mpdf\Css\PresentationalHints
*/
private $presentationalHints;

/**
* @var bool When true, state outside this object will be modified
* @internal self::previewBlockCss() uses this property to look ahead without affecting state
Expand All @@ -70,7 +75,8 @@ public function __construct(
SelectorParser $selectorParser,
InlinePropertyConverter $inlinePropertyConverter,
ColorConverter $colorConverter,
BorderMerger $borderMerger
BorderMerger $borderMerger,
PresentationalHints $presentationalHints
) {
$this->mpdf = $mpdf;
$this->normalizeProperties = $normalizeProperties;
Expand All @@ -79,6 +85,7 @@ public function __construct(
$this->inlinePropertyConverter = $inlinePropertyConverter;
$this->colorConverter = $colorConverter;
$this->borderMerger = $borderMerger;
$this->presentationalHints = $presentationalHints;
}

/**
Expand Down Expand Up @@ -199,7 +206,7 @@ private function mergeInCascadeOrder($inherit, $tag, array $attr)
list($defaultRules, $importantDefaultRules) = $this->cssManager->getDefaultRules()->matchingDeclarations($tag, $id, $classes, $path);
$this->mergeEach($defaultRules, $dominance);

$this->mergeInlineAttributes($tag, $attr);
$this->mergePresentationalHints($tag, $attr);
$this->mergeTableSpecificCss($tag, $attr);

if ($tag === 'BODY') {
Expand Down Expand Up @@ -496,30 +503,7 @@ protected function mergeInlineAttributes($tag, $attr)
}

if ($tag === 'FONT') {
if (!empty($attr['FACE'])) {
$this->cssProperties = array_merge($this->cssProperties, $this->normalizeProperties->normalize(['FONT-FAMILY' => $attr['FACE']]));
}

$size = isset($attr['SIZE']) ? $attr['SIZE'] : '';
if ($size === '+1') {
$this->cssProperties['FONT-SIZE'] = '120%';
} elseif ($size === '-1') {
$this->cssProperties['FONT-SIZE'] = '86%';
} elseif ($size === '1') {
$this->cssProperties['FONT-SIZE'] = 'XX-SMALL';
} elseif ($size === '2') {
$this->cssProperties['FONT-SIZE'] = 'X-SMALL';
} elseif ($size === '3') {
$this->cssProperties['FONT-SIZE'] = 'SMALL';
} elseif ($size === '4') {
$this->cssProperties['FONT-SIZE'] = 'MEDIUM';
} elseif ($size === '5') {
$this->cssProperties['FONT-SIZE'] = 'LARGE';
} elseif ($size === '6') {
$this->cssProperties['FONT-SIZE'] = 'X-LARGE';
} elseif ($size === '7') {
$this->cssProperties['FONT-SIZE'] = 'XX-LARGE';
}
$this->cssProperties = array_merge($this->cssProperties, $this->presentationalHints->ofFont($attr));
}

if (!empty($attr['VALIGN'])) {
Expand All @@ -537,6 +521,27 @@ protected function mergeInlineAttributes($tag, $attr)
}
}

/**
* Merges the presentational attributes of an element as the standard cascade reads them: only on the elements
* HTML gives each to. mPDF's own tags take every attribute, as they do under the legacy cascade
*
* @param string $tag HTML tag name
* @param array $attr HTML attributes
* @return void
*/
private function mergePresentationalHints($tag, array $attr)
{
if (in_array($tag, PresentationalHints::OWN_TAGS, true)) {
$this->mergeInlineAttributes($tag, $attr);
return;
}

$hints = $this->presentationalHints->of($tag, $attr);
if ($hints) {
$this->setMergedCss($hints, false);
}
}

/**
* Merge default CSS for the tag.
*
Expand All @@ -557,7 +562,7 @@ protected function mergeDefaultCss($tag)
}

/**
* Merge table specific CSS (CELLSPACING, CELLPADDING).
* Merge table specific CSS (CELLSPACING, CELLPADDING, and the cells' border of a table with a border attribute).
*
* @param string $tag HTML tag name
* @param array $attr HTML attributes
Expand Down Expand Up @@ -588,6 +593,12 @@ protected function mergeTableSpecificCss($tag, $attr)
$this->cssProperties['PADDING-TOP'] = $cellPadding;
$this->cssProperties['PADDING-BOTTOM'] = $cellPadding;
}

// Only the standard cascade marks a table's cells to take the border its border attribute gives them
if (!empty($tableCell['cell_border'])) {
$border = $this->presentationalHints->ofCellBorder();
$this->setMergedCss($border, false);
}
}

/**
Expand Down
Loading
Loading