diff --git a/CSSParser.php b/CSSParser.php
index 54779275..6f1aab76 100644
--- a/CSSParser.php
+++ b/CSSParser.php
@@ -88,7 +88,17 @@ private function parseAtRule() {
$this->consume(';');
$this->setCharset($sCharset->getString());
return new CSSCharset($sCharset);
- } else {
+ } else if($sIdentifier === 'namespace') {
+ if($this->comes('"') || $this->comes("'") || $this->comes(('url'))) {
+ $oNamespace = new CSSNamespace($this->parseURLValue());
+ } else {
+ $sPrefix = $this->parseIdentifier();
+ $oNamespace = new CSSNamespace($this->parseURLValue(), $sPrefix);
+ }
+ $this->consumeWhiteSpace();
+ $this->consume(';');
+ return $oNamespace;
+ } else {
//Unknown other at rule (font-face or such)
$this->consume('{');
$this->consumeWhiteSpace();
@@ -210,7 +220,8 @@ private function parseRuleSet($oRuleSet) {
private function parseRule() {
$oRule = new CSSRule($this->parseIdentifier());
$this->consumeWhiteSpace();
- $this->consume(':');
+ $this->consume(':');
+ $sRule = $oRule->getrule();
$oValue = $this->parseValue(self::listDelimiterForRule($oRule->getRule()));
$oRule->setValue($oValue);
if($this->comes('!')) {
@@ -226,7 +237,7 @@ private function parseRule() {
$this->consume(';');
}
return $oRule;
- }
+ }
private function parseValue($aListDelimiters) {
$aStack = array();
diff --git a/lib/CSSProperties.php b/lib/CSSProperties.php
index 15c9edbd..43a527e8 100644
--- a/lib/CSSProperties.php
+++ b/lib/CSSProperties.php
@@ -52,6 +52,44 @@ public function __toString() {
}
}
+/**
+ * Class representing an @namespace rule.
+ * The following restrictions apply:
+ *
+ * - May not be found in any CSSList other than the CSSDocument.
+ * - May only appear after all @import rules and before other @rules.
+ *
+ */
+class CSSNamespace {
+ private $sPrefix;
+ private $sURI;
+
+ public function __construct($sURI, $sPrefix=null) {
+ $this->sURI = $sURI;
+ $this->sPrefix = $sPrefix;
+ }
+
+ public function getURI() {
+ return $this->sURI;
+ }
+ public function setURI($sURI) {
+ $this->sURI = $sURI;
+ }
+
+ public function getPrefix() {
+ return $this->sPrefix;
+ }
+ public function setPrefix($sPrefix) {
+ $this->sPrefix = $sPrefix;
+ }
+
+ public function __toString() {
+ $sPrefix = $this->sPrefix ? ' '.$this->sPrefix : '';
+ return "@namespace" . $sPrefix . ' ' . $this->sURI . ';';
+ }
+
+}
+
/**
* Class representing a single CSS selector. Selectors have to be split by the comma prior to being passed into this class.
*/
diff --git a/tests/bugs/GH27_Test.php b/tests/bugs/GH27_Test.php
new file mode 100644
index 00000000..b5f8435c
--- /dev/null
+++ b/tests/bugs/GH27_Test.php
@@ -0,0 +1,31 @@
+parse();
+ $this->assertEquals((string)$oDoc, $sExpected);
+ }
+ public function testNamespacesProvider()
+ {
+ return array(
+ array(
+ '@namespace "http://www.w3.org/1999/xhtml";',
+ '@namespace url("http://www.w3.org/1999/xhtml");',
+ ),
+ array(
+ '@namespace svg "http://www.w3.org/2000/svg";',
+ '@namespace svg url("http://www.w3.org/2000/svg");',
+ )
+ );
+ }
+}
diff --git a/testsuite.xml b/testsuite.xml
new file mode 100644
index 00000000..aefc932b
--- /dev/null
+++ b/testsuite.xml
@@ -0,0 +1,11 @@
+
+
+
+ tests/CSSDeclarationBlockTest.php
+ tests/CSSParserTests.php
+
+
+ tests/bugs
+
+
+