diff --git a/Classes/Emogrifier.php b/Classes/Emogrifier.php index ea2f6e36..c675f231 100644 --- a/Classes/Emogrifier.php +++ b/Classes/Emogrifier.php @@ -353,7 +353,7 @@ private function parseCssRules($css) foreach ($selectors as $selector) { // don't process pseudo-elements and behavioral (dynamic) pseudo-classes; // only allow structural pseudo-classes - if (strpos($selector, ':') !== false && !preg_match('/:\\S+\\-(child|type)\\(/i', $selector)) { + if (strpos($selector, ':') !== false && !preg_match('/:\\S+\\-(child|type\\()/i', $selector)) { continue; } @@ -1012,8 +1012,8 @@ function (array $matches) { 'child' => '/', 'adjacent sibling' => '/following-sibling::*[1]/self::', 'descendant' => '//', - ':first-child' => '*[1]/self::\\1', - ':last-child' => '*[last()]/self::\\1', + ':first-child' => '\\1/*[1]', + ':last-child' => '\\1/*[last()]', 'attribute only' => '*[@\\1]', 'attribute' => '\\1[@\\2]', 'exact attribute' => '\\1[@\\2="\\3"]', diff --git a/README.md b/README.md index b692e484..c06ad7c3 100644 --- a/README.md +++ b/README.md @@ -149,11 +149,8 @@ Emogrifier currently support the following * attribute presence * attribute value * attribute only - -The following selectors are implemented, but currently are broken: - - * first-child (currently broken) - * last-child (currently broken) + * first-child + * last-child The following selectors are not implemented yet: diff --git a/Tests/Unit/EmogrifierTest.php b/Tests/Unit/EmogrifierTest.php index 2e526666..6070d954 100644 --- a/Tests/Unit/EmogrifierTest.php +++ b/Tests/Unit/EmogrifierTest.php @@ -582,7 +582,7 @@ public function emogrifyCanAssignStyleRulesFromTwoDifferentMatchersToElement() /** * Data provide for selectors. * - * @return array[] + * @return string[][] */ public function selectorDataProvider() { @@ -633,6 +633,17 @@ public function selectorDataProvider() => ['span[title="bonjour"] {' . $styleRule . '} ', '##'], 'attribute value selector SPAN[title] not matches element without any attributes' => ['span[title="bonjour"] {' . $styleRule . '} ', '##'], + 'BODY:first-child matches first child' + => ['body:first-child {' . $styleRule . '} ', '#

#'], + 'BODY:first-child not matches middle child' + => ['body:first-child {' . $styleRule . '} ', '#

#'], + 'BODY:first-child not matches last child' + => ['body:first-child {' . $styleRule . '} ', '#

#'], + 'BODY:last-child not matches first child' => ['body:last-child {' . $styleRule . '} ', '#

#'], + 'BODY:last-child not matches middle child' + => ['body:last-child {' . $styleRule . '} ', '#

#'], + 'BODY:last-child matches last child' + => ['body:last-child {' . $styleRule . '} ', '#

#'], ]; } @@ -640,11 +651,11 @@ public function selectorDataProvider() * @test * * @param string $css the complete CSS - * @param string $containedHtml regular expression for the the HTML that needs to be contained in the merged HTML + * @param string $htmlRegularExpression regular expression for the the HTML that needs to be contained in the HTML * * @dataProvider selectorDataProvider */ - public function emogrifierMatchesSelectors($css, $containedHtml) + public function emogrifierMatchesSelectors($css, $htmlRegularExpression) { $html = $this->html5DocumentType . '' . @@ -654,13 +665,14 @@ public function emogrifierMatchesSelectors($css, $containedHtml) '

some more text

' . ' ' . ''; - $this->subject->setHtml($html); $this->subject->setCss($css); + $result = $this->subject->emogrify(); + self::assertRegExp( - $containedHtml, - $this->subject->emogrify() + $htmlRegularExpression, + $result ); }