Skip to content

Commit

Permalink
Fix encoding issues and improve parsing performance
Browse files Browse the repository at this point in the history
  • Loading branch information
Petr Skoda committed Aug 24, 2016
1 parent 50a802f commit 2ddbdef
Show file tree
Hide file tree
Showing 24 changed files with 641 additions and 169 deletions.
402 changes: 271 additions & 131 deletions lib/Sabberworm/CSS/Parser.php

Large diffs are not rendered by default.

29 changes: 20 additions & 9 deletions lib/Sabberworm/CSS/Property/Charset.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

namespace Sabberworm\CSS\Property;
use Sabberworm\CSS\Value\CSSString;

/**
* Class representing an @charset rule.
Expand All @@ -11,12 +12,16 @@
*/
class Charset implements AtRule {

private $sCharset;
private $oCharset;
protected $iLineNo;
protected $aComment;
protected $aComments;

public function __construct($sCharset, $iLineNo = 0) {
$this->sCharset = $sCharset;
/**
* @param CSSString $oCharset
* @param int $iLineNo
*/
public function __construct(CSSString $oCharset, $iLineNo = 0) {
$this->oCharset = $oCharset;
$this->iLineNo = $iLineNo;
$this->aComments = array();
}
Expand All @@ -28,28 +33,34 @@ public function getLineNo() {
return $this->iLineNo;
}

public function setCharset($sCharset) {
$this->sCharset = $sCharset;
/**
* @param CSSString $oCharset
*/
public function setCharset(CSSString $oCharset) {
$this->oCharset = $oCharset;
}

/**
* @return CSSString
*/
public function getCharset() {
return $this->sCharset;
return $this->oCharset;
}

public function __toString() {
return $this->render(new \Sabberworm\CSS\OutputFormat());
}

public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) {
return "@charset {$this->sCharset->render($oOutputFormat)};";
return "@charset {$this->oCharset->render($oOutputFormat)};";
}

public function atRuleName() {
return 'charset';
}

public function atRuleArgs() {
return $this->sCharset;
return $this->oCharset;
}

public function addComments(array $aComments) {
Expand Down
18 changes: 15 additions & 3 deletions lib/Sabberworm/CSS/RuleSet/DeclarationBlock.php
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,11 @@ public function expandFontShorthand() {
}
foreach ($aValues as $mValue) {
if (!$mValue instanceof Value) {
$mValue = mb_strtolower($mValue);
if (function_exists('mb_strtolower')) {
$mValue = mb_strtolower($mValue, 'utf-8');
} else {
$mValue = strtolower($mValue);
}
}
if (in_array($mValue, array('normal', 'inherit'))) {
foreach (array('font-style', 'font-weight', 'font-variant') as $sProperty) {
Expand Down Expand Up @@ -300,7 +304,11 @@ public function expandBackgroundShorthand() {
$iNumBgPos = 0;
foreach ($aValues as $mValue) {
if (!$mValue instanceof Value) {
$mValue = mb_strtolower($mValue);
if (function_exists('mb_strtolower')) {
$mValue = mb_strtolower($mValue, 'utf-8');
} else {
$mValue = strtolower($mValue);
}
}
if ($mValue instanceof URL) {
$aBgProperties['background-image'] = $mValue;
Expand Down Expand Up @@ -369,7 +377,11 @@ public function expandListStyleShorthand() {
}
foreach ($aValues as $mValue) {
if (!$mValue instanceof Value) {
$mValue = mb_strtolower($mValue);
if (function_exists('mb_strtolower')) {
$mValue = mb_strtolower($mValue, 'utf-8');
} else {
$mValue = strtolower($mValue);
}
}
if ($mValue instanceof Url) {
$aListProperties['list-style-image'] = $mValue;
Expand Down
37 changes: 34 additions & 3 deletions lib/Sabberworm/CSS/Value/CSSString.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,40 @@ public function __toString() {
}

public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) {
$sString = addslashes($this->sString);
$sString = str_replace("\n", '\A', $sString);
return $oOutputFormat->getStringQuotingType() . $sString . $oOutputFormat->getStringQuotingType();
$sQuote = $oOutputFormat->getStringQuotingType();
$aString = preg_split('//u', $this->sString, null, PREG_SPLIT_NO_EMPTY);
$iLength = count($aString);
foreach ($aString as $i => $sChar) {
if (strlen($sChar) === 1) {
if ($sChar === $sQuote || $sChar === '\\') {
// Encode quoting related characters as hex values
} else {
$iOrd = ord($sChar);
if ($iOrd > 31 && $iOrd < 127) {
// Keep only human readable ascii characters
continue;
}
}
}

$sHex = '';
$sUtf32 = iconv('utf-8', 'utf-32le', $sChar);
$aBytes = str_split($sUtf32);
foreach (array_reverse($aBytes) as $sByte) {
$sHex .= str_pad(dechex(ord($sByte)), 2, '0', STR_PAD_LEFT);
}
$sHex = ltrim($sHex, '0');
if ($i + 1 < $iLength && strlen($sHex) < 6) {
// Add space after incomplete unicode escape if there can be any confusion
$sNextChar = $aString[$i + 1];
if (preg_match('/^[a-fA-F0-9\s]/u', $sNextChar)) {
$sHex .= ' ';
}
}
$aString[$i] = '\\' . $sHex;
}

return $sQuote . implode($aString) . $sQuote;
}

}
Loading

0 comments on commit 2ddbdef

Please sign in to comment.