Skip to content

Commit e0458bb

Browse files
authored
Merge pull request MyIntervals#112 from moodlehq/ie-hacks-parsing
Support for IE hack parsing in lenient mode
2 parents dcfbc81 + e1ecb78 commit e0458bb

File tree

4 files changed

+52
-1
lines changed

4 files changed

+52
-1
lines changed

lib/Sabberworm/CSS/Parser.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,10 @@ private function parseStringValue() {
255255

256256
private function parseCharacter($bIsForIdentifier) {
257257
if ($this->peek() === '\\') {
258+
if ($bIsForIdentifier && $this->oParserSettings->bLenientParsing && ($this->comes('\0') || $this->comes('\9'))) {
259+
// Non-strings can contain \0 or \9 which is an IE hack supported in lenient parsing.
260+
return null;
261+
}
258262
$this->consume('\\');
259263
if ($this->comes('\n') || $this->comes('\r')) {
260264
return '';
@@ -350,6 +354,13 @@ private function parseRule() {
350354
$this->consume(':');
351355
$oValue = $this->parseValue(self::listDelimiterForRule($oRule->getRule()));
352356
$oRule->setValue($oValue);
357+
if ($this->oParserSettings->bLenientParsing) {
358+
while ($this->comes('\\')) {
359+
$this->consume('\\');
360+
$oRule->addIeHack($this->consume());
361+
$this->consumeWhiteSpace();
362+
}
363+
}
353364
if ($this->comes('!')) {
354365
$this->consume('!');
355366
$this->consumeWhiteSpace();
@@ -367,7 +378,7 @@ private function parseValue($aListDelimiters) {
367378
$aStack = array();
368379
$this->consumeWhiteSpace();
369380
//Build a list of delimiters and parsed values
370-
while (!($this->comes('}') || $this->comes(';') || $this->comes('!') || $this->comes(')'))) {
381+
while (!($this->comes('}') || $this->comes(';') || $this->comes('!') || $this->comes(')') || $this->comes('\\'))) {
371382
if (count($aStack) > 0) {
372383
$bFoundDelimiter = false;
373384
foreach ($aListDelimiters as $sDelimiter) {

lib/Sabberworm/CSS/Rule/Rule.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ class Rule implements Renderable {
1515
private $sRule;
1616
private $mValue;
1717
private $bIsImportant;
18+
private $aIeHack;
1819
protected $iLineNo;
1920

2021
public function __construct($sRule, $iLineNo = 0) {
2122
$this->sRule = $sRule;
2223
$this->mValue = null;
2324
$this->bIsImportant = false;
25+
$this->aIeHack = array();
2426
$this->iLineNo = $iLineNo;
2527
}
2628

@@ -127,6 +129,18 @@ public function addValue($mValue, $sType = ' ') {
127129
}
128130
}
129131

132+
public function addIeHack($iModifier) {
133+
$this->aIeHack[] = $iModifier;
134+
}
135+
136+
public function setIeHack(array $aModifiers) {
137+
$this->aIeHack = $aModifiers;
138+
}
139+
140+
public function getIeHack() {
141+
return $this->aIeHack;
142+
}
143+
130144
public function setIsImportant($bIsImportant) {
131145
$this->bIsImportant = $bIsImportant;
132146
}
@@ -146,6 +160,9 @@ public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) {
146160
} else {
147161
$sResult .= $this->mValue;
148162
}
163+
if (!empty($this->aIeHack)) {
164+
$sResult .= ' \\' . implode('\\', $this->aIeHack);
165+
}
149166
if ($this->bIsImportant) {
150167
$sResult .= ' !important';
151168
}

tests/Sabberworm/CSS/ParserTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,4 +505,18 @@ function testUnexpectedTokenExceptionLineNo() {
505505
throw $e;
506506
}
507507
}
508+
509+
/**
510+
* @expectedException Sabberworm\CSS\Parsing\UnexpectedTokenException
511+
*/
512+
function testIeHacksStrictParsing() {
513+
// We can't strictly parse IE hacks.
514+
$this->parsedStructureForFile('ie-hacks', Settings::create()->beStrict());
515+
}
516+
517+
function testIeHacksParsing() {
518+
$oDoc = $this->parsedStructureForFile('ie-hacks', Settings::create()->withLenientParsing(true));
519+
$sExpected = 'p {padding-right: .75rem \9;background-image: none \9;color: red \9\0;background-color: red \9\0;background-color: red \9\0 !important;content: "red \0";content: "red઼";}';
520+
$this->assertEquals($sExpected, $oDoc->render());
521+
}
508522
}

tests/files/ie-hacks.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
p {
2+
padding-right: .75rem \9;
3+
background-image: none \9;
4+
color:red\9\0;
5+
background-color:red \9 \0;
6+
background-color:red \9 \0 !important;
7+
content: "red \9\0";
8+
content: "red\0abc";
9+
}

0 commit comments

Comments
 (0)