WebCore:
authorhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Jun 2008 21:49:52 +0000 (21:49 +0000)
committerhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Jun 2008 21:49:52 +0000 (21:49 +0000)
2008-06-19  David Hyatt  <hyatt@apple.com>

        Add initial support for CSS variables.  Non-dynamic cases should (hopefully) all work.  Things will get
        confused if you use the CSS OM to remove variables/inject variables, etc.  In addition no DOM APIs are
        exposed yet for the new variable interfaces.

        Reviewed by Beth

        Added many tests to fast/css/variables/

        * WebCore.xcodeproj/project.pbxproj:
        * css/CSSFunctionValue.cpp: Added.
        (WebCore::CSSFunctionValue::CSSFunctionValue):
        (WebCore::CSSFunctionValue::~CSSFunctionValue):
        (WebCore::CSSFunctionValue::cssText):
        (WebCore::CSSFunctionValue::parserValue):
        * css/CSSFunctionValue.h: Added.
        (WebCore::CSSFunctionValue::create):
        * css/CSSGrammar.y:
        * css/CSSMutableStyleDeclaration.cpp:
        (WebCore::CSSMutableStyleDeclaration::CSSMutableStyleDeclaration):
        (WebCore::CSSMutableStyleDeclaration::copy):
        * css/CSSMutableStyleDeclaration.h:
        (WebCore::CSSMutableStyleDeclaration::create):
        (WebCore::CSSMutableStyleDeclaration::hasVariableDependentValue):
        * css/CSSParser.cpp:
        (WebCore::equal):
        (WebCore::equalIgnoringCase):
        (WebCore::CSSParser::~CSSParser):
        (WebCore::CSSParserString::lower):
        (WebCore::CSSParser::document):
        (WebCore::CSSParser::validUnit):
        (WebCore::unitFromString):
        (WebCore::CSSParser::checkForOrphanedUnits):
        (WebCore::CSSParser::parseValue):
        (WebCore::CSSParser::parseFillShorthand):
        (WebCore::CSSParser::parseTransitionShorthand):
        (WebCore::CSSParser::parseContent):
        (WebCore::CSSParser::parseFillImage):
        (WebCore::CSSParser::parseFillPosition):
        (WebCore::CSSParser::parseFillSize):
        (WebCore::CSSParser::parseFillProperty):
        (WebCore::CSSParser::parseTransitionDuration):
        (WebCore::CSSParser::parseTransitionRepeatCount):
        (WebCore::CSSParser::parseTimingFunctionValue):
        (WebCore::CSSParser::parseTransitionTimingFunction):
        (WebCore::CSSParser::parseTransitionProperty):
        (WebCore::skipCommaInDashboardRegion):
        (WebCore::CSSParser::parseDashboardRegions):
        (WebCore::CSSParser::parseCounterContent):
        (WebCore::CSSParser::parseShape):
        (WebCore::CSSParser::parseFont):
        (WebCore::CSSParser::parseFontFamily):
        (WebCore::CSSParser::parseFontFaceSrc):
        (WebCore::CSSParser::parseFontFaceUnicodeRange):
        (WebCore::CSSParser::parseColorParameters):
        (WebCore::CSSParser::parseHSLParameters):
        (WebCore::CSSParser::parseColor):
        (WebCore::CSSParser::parseColorFromValue):
        (WebCore::ShadowParseContext::commitLength):
        (WebCore::CSSParser::parseShadow):
        (WebCore::CSSParser::parseReflect):
        (WebCore::BorderImageParseContext::commitNumber):
        (WebCore::BorderImageParseContext::commitWidth):
        (WebCore::BorderImageParseContext::commitBorderImage):
        (WebCore::CSSParser::parseBorderImage):
        (WebCore::CSSParser::parseCounter):
        (WebCore::parseGradientPoint):
        (WebCore::parseGradientColorStop):
        (WebCore::CSSParser::parseGradient):
        (WebCore::CSSParser::parseCanvas):
        (WebCore::TransformOperationInfo::TransformOperationInfo):
        (WebCore::CSSParser::parseTransform):
        (WebCore::CSSParser::lex):
        (WebCore::CSSParser::text):
        (WebCore::CSSParser::createFloatingValueList):
        (WebCore::CSSParser::sinkFloatingValueList):
        (WebCore::CSSParser::createFloatingFunction):
        (WebCore::CSSParser::sinkFloatingFunction):
        (WebCore::CSSParser::sinkFloatingValue):
        (WebCore::CSSParser::createFloatingMediaQueryExp):
        (WebCore::CSSParser::createCharsetRule):
        (WebCore::CSSParser::createImportRule):
        (WebCore::CSSParser::createVariablesRule):
        (WebCore::CSSParser::addVariable):
        (WebCore::CSSParser::clearVariables):
        (WebCore::CSSParser::parseVariable):
        (WebCore::CSSParser::parsePropertyWithResolvedVariables):
        (WebCore::CSSParser::checkForVariables):
        (WebCore::CSSParser::addUnresolvedProperty):
        (WebCore::cssPropertyID):
        (WebCore::cssValueKeywordID):
        * css/CSSParser.h:
        * css/CSSParserValues.cpp: Added.
        (WebCore::CSSParserValueList::~CSSParserValueList):
        (WebCore::CSSParserValueList::addValue):
        (WebCore::CSSParserValueList::deleteValueAt):
        (WebCore::CSSParserValue::createCSSValue):
        * css/CSSParserValues.h: Added.
        (WebCore::CSSParserString::operator String):
        (WebCore::CSSParserString::operator AtomicString):
        (WebCore::CSSParserValue::):
        (WebCore::CSSParserValueList::CSSParserValueList):
        (WebCore::CSSParserValueList::size):
        (WebCore::CSSParserValueList::current):
        (WebCore::CSSParserValueList::next):
        (WebCore::CSSParserValueList::valueAt):
        (WebCore::CSSParserValueList::clear):
        (WebCore::CSSParserValueList::containsVariables):
        (WebCore::CSSParserFunction::~CSSParserFunction):
        * css/CSSPrimitiveValue.cpp:
        (WebCore::CSSPrimitiveValue::getStringValue):
        (WebCore::CSSPrimitiveValue::cssText):
        (WebCore::CSSPrimitiveValue::parserValue):
        * css/CSSPrimitiveValue.h:
        (WebCore::CSSPrimitiveValue::):
        (WebCore::CSSPrimitiveValue::setPrimitiveType):
        * css/CSSRule.h:
        (WebCore::CSSRule::):
        * css/CSSRule.idl:
        * css/CSSStyleDeclaration.cpp:
        (WebCore::CSSStyleDeclaration::copyPropertiesInSet):
        * css/CSSStyleSelector.cpp:
        (WebCore::CSSStyleSelector::addMatchedDeclaration):
        (WebCore::CSSStyleSelector::addVariables):
        (WebCore::CSSStyleSelector::resolveVariableDependentValue):
        (WebCore::CSSRuleSet::addRulesFromSheet):
        (WebCore::CSSStyleSelector::applyDeclarations):
        * css/CSSStyleSelector.h:
        * css/CSSValue.h:
        (WebCore::CSSValue::isVariableDependentValue):
        (WebCore::CSSValue::parserValue):
        * css/CSSValueList.cpp:
        (WebCore::CSSValueList::CSSValueList):
        (WebCore::CSSValueList::createParserValueList):
        * css/CSSValueList.h:
        (WebCore::CSSValueList::createFromParserValueList):
        * css/CSSVariableDependentValue.cpp: Added.
        (WebCore::CSSVariableDependentValue::CSSVariableDependentValue):
        (WebCore::CSSVariableDependentValue::~CSSVariableDependentValue):
        (WebCore::CSSVariableDependentValue::cssText):
        * css/CSSVariableDependentValue.h: Added.
        (WebCore::CSSVariableDependentValue::create):
        (WebCore::CSSVariableDependentValue::isVariableDependentValue):
        (WebCore::CSSVariableDependentValue::valueList):
        * css/CSSVariablesDeclaration.cpp: Added.
        (WebCore::CSSVariablesDeclaration::CSSVariablesDeclaration):
        (WebCore::CSSVariablesDeclaration::~CSSVariablesDeclaration):
        (WebCore::CSSVariablesDeclaration::getVariableValue):
        (WebCore::CSSVariablesDeclaration::removeVariable):
        (WebCore::CSSVariablesDeclaration::setVariable):
        (WebCore::CSSVariablesDeclaration::addParsedVariable):
        (WebCore::CSSVariablesDeclaration::getParsedVariable):
        (WebCore::CSSVariablesDeclaration::length):
        (WebCore::CSSVariablesDeclaration::item):
        (WebCore::CSSVariablesDeclaration::parentRule):
        (WebCore::CSSVariablesDeclaration::cssText):
        * css/CSSVariablesDeclaration.h: Added.
        (WebCore::CSSVariablesDeclaration::create):
        * css/CSSVariablesRule.cpp: Added.
        (WebCore::CSSVariablesRule::CSSVariablesRule):
        (WebCore::CSSVariablesRule::~CSSVariablesRule):
        (WebCore::CSSVariablesRule::cssText):
        * css/CSSVariablesRule.h: Added.
        (WebCore::CSSVariablesRule::media):
        (WebCore::CSSVariablesRule::variables):
        (WebCore::CSSVariablesRule::type):
        (WebCore::CSSVariablesRule::isVariablesRule):
        (WebCore::CSSVariablesRule::setDeclaration):
        * css/MediaQueryExp.cpp:
        (WebCore::MediaQueryExp::MediaQueryExp):
        * css/MediaQueryExp.h:
        * css/SVGCSSParser.cpp:
        (WebCore::CSSParser::parseSVGValue):
        (WebCore::CSSParser::parseSVGStrokeDasharray):
        * css/StyleBase.h:
        (WebCore::StyleBase::isVariablesRule):
        * css/tokenizer.flex:

LayoutTests:

2008-06-19  David Hyatt  <hyatt@apple.com>

        Add layout tests for CSS variables.

        Reviewed by Beth

        * fast/css/variables: Added.
        * fast/css/variables/colors-test.html: Added.
        * fast/css/variables/font-test.html: Added.
        * fast/css/variables/image-test.html: Added.
        * fast/css/variables/import-test.html: Added.
        * fast/css/variables/invalid-variable-test.html: Added.
        * fast/css/variables/margin-test.html: Added.
        * fast/css/variables/misplaced-import-test.html: Added.
        * fast/css/variables/misplaced-variables-test.html: Added.
        * fast/css/variables/override-test.html: Added.
        * fast/css/variables/print-test.html: Added.
        * fast/css/variables/resources: Added.
        * fast/css/variables/resources/bad.css: Added.
        * fast/css/variables/resources/good.css: Added.
        * fast/css/variables/resources/listmark.gif: Added.
        * fast/css/variables/shorthand-test.html: Added.
        * fast/css/variables/single-term-test.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@34666 268f45cc-cd09-0410-ab3c-d52691b4dbfc

48 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/css/variables/colors-test.html [new file with mode: 0644]
LayoutTests/fast/css/variables/font-test.html [new file with mode: 0644]
LayoutTests/fast/css/variables/image-test.html [new file with mode: 0644]
LayoutTests/fast/css/variables/import-test.html [new file with mode: 0644]
LayoutTests/fast/css/variables/invalid-variable-test.html [new file with mode: 0644]
LayoutTests/fast/css/variables/margin-test.html [new file with mode: 0644]
LayoutTests/fast/css/variables/misplaced-import-test.html [new file with mode: 0644]
LayoutTests/fast/css/variables/misplaced-variables-test.html [new file with mode: 0644]
LayoutTests/fast/css/variables/override-test.html [new file with mode: 0644]
LayoutTests/fast/css/variables/print-test.html [new file with mode: 0644]
LayoutTests/fast/css/variables/resources/bad.css [new file with mode: 0644]
LayoutTests/fast/css/variables/resources/good.css [new file with mode: 0644]
LayoutTests/fast/css/variables/resources/listmark.gif [new file with mode: 0644]
LayoutTests/fast/css/variables/shorthand-test.html [new file with mode: 0644]
LayoutTests/fast/css/variables/single-term-test.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/css/CSSFunctionValue.cpp [new file with mode: 0644]
WebCore/css/CSSFunctionValue.h [new file with mode: 0644]
WebCore/css/CSSGrammar.y
WebCore/css/CSSMutableStyleDeclaration.cpp
WebCore/css/CSSMutableStyleDeclaration.h
WebCore/css/CSSParser.cpp
WebCore/css/CSSParser.h
WebCore/css/CSSParserValues.cpp [new file with mode: 0644]
WebCore/css/CSSParserValues.h [new file with mode: 0644]
WebCore/css/CSSPrimitiveValue.cpp
WebCore/css/CSSPrimitiveValue.h
WebCore/css/CSSRule.h
WebCore/css/CSSRule.idl
WebCore/css/CSSStyleDeclaration.cpp
WebCore/css/CSSStyleSelector.cpp
WebCore/css/CSSStyleSelector.h
WebCore/css/CSSValue.h
WebCore/css/CSSValueList.cpp
WebCore/css/CSSValueList.h
WebCore/css/CSSVariableDependentValue.cpp [new file with mode: 0644]
WebCore/css/CSSVariableDependentValue.h [new file with mode: 0644]
WebCore/css/CSSVariablesDeclaration.cpp [new file with mode: 0644]
WebCore/css/CSSVariablesDeclaration.h [new file with mode: 0644]
WebCore/css/CSSVariablesRule.cpp [new file with mode: 0644]
WebCore/css/CSSVariablesRule.h [new file with mode: 0644]
WebCore/css/MediaQueryExp.cpp
WebCore/css/MediaQueryExp.h
WebCore/css/SVGCSSParser.cpp
WebCore/css/StyleBase.h
WebCore/css/tokenizer.flex

index 863fe436542d38f06301bb8bcc635107ead7d358..9ec49bbde13515800d0f3dbd55a854dd19ac4c0d 100644 (file)
@@ -1,3 +1,27 @@
+2008-06-19  David Hyatt  <hyatt@apple.com>
+
+        Add layout tests for CSS variables.
+
+        Reviewed by Beth
+
+        * fast/css/variables: Added.
+        * fast/css/variables/colors-test.html: Added.
+        * fast/css/variables/font-test.html: Added.
+        * fast/css/variables/image-test.html: Added.
+        * fast/css/variables/import-test.html: Added.
+        * fast/css/variables/invalid-variable-test.html: Added.
+        * fast/css/variables/margin-test.html: Added.
+        * fast/css/variables/misplaced-import-test.html: Added.
+        * fast/css/variables/misplaced-variables-test.html: Added.
+        * fast/css/variables/override-test.html: Added.
+        * fast/css/variables/print-test.html: Added.
+        * fast/css/variables/resources: Added.
+        * fast/css/variables/resources/bad.css: Added.
+        * fast/css/variables/resources/good.css: Added.
+        * fast/css/variables/resources/listmark.gif: Added.
+        * fast/css/variables/shorthand-test.html: Added.
+        * fast/css/variables/single-term-test.html: Added.
+
 2008-06-19  Dan Bernstein  <mitz@apple.com>
 
         Reviewed by Darin Adler.
diff --git a/LayoutTests/fast/css/variables/colors-test.html b/LayoutTests/fast/css/variables/colors-test.html
new file mode 100644 (file)
index 0000000..d6839de
--- /dev/null
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<style>
+@-webkit-variables {
+    foreground: green;
+    background: rgb(255, 255, 255);
+}
+
+body {
+    color: -webkit-var(foreground);
+    background-color: red;
+    background-color: -webkit-var(background);
+}
+</style>
+</head>
+<body>
+This text should be green on a white background.  There should be no red visible.
diff --git a/LayoutTests/fast/css/variables/font-test.html b/LayoutTests/fast/css/variables/font-test.html
new file mode 100644 (file)
index 0000000..434fcdc
--- /dev/null
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<style>
+@-webkit-variables {
+    familyName: "Ahem";
+}
+
+div {
+    color: green;
+    font: 24px -webkit-var(familyName);
+}
+</style>
+</head>
+<body>
+<p>You should see a green rectangle below. If you see individual "X" glyphs, the test has failed. (The Ahem font is required for this test.)</p>
+<div>XXXXXXXXXX</div>
+
+
diff --git a/LayoutTests/fast/css/variables/image-test.html b/LayoutTests/fast/css/variables/image-test.html
new file mode 100644 (file)
index 0000000..b1f26e7
--- /dev/null
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<style>
+@-webkit-variables {
+    marker: url(resources/listmark.gif);
+}
+
+li {
+    list-style-type: disc;
+    list-style-image: -webkit-var(marker)
+}
+</style>
+</head>
+<body>
+The list below should use red diamond images for bullets.  If you see circular bullets, the test has failed.
+
+<ul>
+<li>One
+<li>Two
+<li>Three
+</ul>
+</body>
+</html>
diff --git a/LayoutTests/fast/css/variables/import-test.html b/LayoutTests/fast/css/variables/import-test.html
new file mode 100644 (file)
index 0000000..4bd4384
--- /dev/null
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html style="color:red">
+<head>
+<style>
+@import url(resources/good.css);
+
+body {
+    color: -webkit-var(foreground);
+    background-color: -webkit-var(background);
+}
+</style>
+</head>
+<body>
+This text should be green on a white background.  There should be no red visible.
diff --git a/LayoutTests/fast/css/variables/invalid-variable-test.html b/LayoutTests/fast/css/variables/invalid-variable-test.html
new file mode 100644 (file)
index 0000000..8696953
--- /dev/null
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<style>
+@-webkit-variables {
+    foreground; red;
+    background: rgb(255, 255, 255);
+}
+
+body {
+    color: green;
+    color: -webkit-var(foreground);
+    background-color: red;
+    background-color: -webkit-var(background);
+}
+</style>
+</head>
+<body>
+This text should be green on a white background.  There should be no red visible.
diff --git a/LayoutTests/fast/css/variables/margin-test.html b/LayoutTests/fast/css/variables/margin-test.html
new file mode 100644 (file)
index 0000000..e39a4d3
--- /dev/null
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<style>
+@-webkit-variables {
+    verticalMargin: 5em;
+}
+
+div.outer {
+    height:10em;
+    width:10em;
+    position:absolute;
+}
+
+div.bad {
+    position:absolute;
+    top:5em;
+    left:2em;
+    height:5em;
+    width:5em;
+    background-color:red;
+}
+
+div.inner {
+    position:relative;
+    margin: -webkit-var(verticalMargin) 2em;
+    height:5em;
+    width:5em;
+    background-color:green;
+}
+</style>
+</head>
+<body>
+You should see a 5em wide green square below.  There should be no red on the page.
+
+<div class="outer">
+<div class="bad"></div>
+<div class="inner"></div>
+</div>
diff --git a/LayoutTests/fast/css/variables/misplaced-import-test.html b/LayoutTests/fast/css/variables/misplaced-import-test.html
new file mode 100644 (file)
index 0000000..83bd068
--- /dev/null
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<style>
+@-webkit-variables {
+    foreground: green;
+    background: rgb(255, 255, 255);
+}
+
+@import url(resources/bad.css);
+
+body {
+    color: -webkit-var(foreground);
+    background-color: -webkit-var(background);
+}
+</style>
+</head>
+<body>
+This text should be green on a white background.  There should be no red visible.
diff --git a/LayoutTests/fast/css/variables/misplaced-variables-test.html b/LayoutTests/fast/css/variables/misplaced-variables-test.html
new file mode 100644 (file)
index 0000000..630dec7
--- /dev/null
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<style>
+body {
+    color: -webkit-var(foreground);
+    background-color: white;
+    background-color: -webkit-var(background);
+}
+
+@-webkit-variables {
+    foreground: red;
+    background: red;
+}
+
+body {
+    color: green;
+}
+</style>
+</head>
+<body>
+This text should be green on a white background.
diff --git a/LayoutTests/fast/css/variables/override-test.html b/LayoutTests/fast/css/variables/override-test.html
new file mode 100644 (file)
index 0000000..855e198
--- /dev/null
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<style>
+@-webkit-variables {
+    foreground: green;
+    background: red;
+}
+
+@-webkit-variables {
+    background: white;
+}
+
+body {
+    color: -webkit-var(foreground);
+    background-color: -webkit-var(background);
+}
+</style>
+</head>
+<body>
+This text should be green on a white background.  There should be no red visible.
diff --git a/LayoutTests/fast/css/variables/print-test.html b/LayoutTests/fast/css/variables/print-test.html
new file mode 100644 (file)
index 0000000..759a604
--- /dev/null
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<style>
+@-webkit-variables {
+    foreground: green;
+    background: rgb(255, 255, 255);
+}
+
+@-webkit-variables print {
+    foreground: black;
+    background: red;
+}
+
+body {
+    color: -webkit-var(foreground);
+    background-color: -webkit-var(background);
+}
+</style>
+</head>
+<body>
+This text should be green on a white background.  There should be no red visible.
diff --git a/LayoutTests/fast/css/variables/resources/bad.css b/LayoutTests/fast/css/variables/resources/bad.css
new file mode 100644 (file)
index 0000000..8c5fdf6
--- /dev/null
@@ -0,0 +1,4 @@
+body {
+  background-color: red;
+  foreground-color: white;
+}
diff --git a/LayoutTests/fast/css/variables/resources/good.css b/LayoutTests/fast/css/variables/resources/good.css
new file mode 100644 (file)
index 0000000..cbb2b26
--- /dev/null
@@ -0,0 +1,4 @@
+@-webkit-variables {
+    foreground: green;
+    background: rgb(255, 255, 255);
+}
diff --git a/LayoutTests/fast/css/variables/resources/listmark.gif b/LayoutTests/fast/css/variables/resources/listmark.gif
new file mode 100644 (file)
index 0000000..c37cd26
Binary files /dev/null and b/LayoutTests/fast/css/variables/resources/listmark.gif differ
diff --git a/LayoutTests/fast/css/variables/shorthand-test.html b/LayoutTests/fast/css/variables/shorthand-test.html
new file mode 100644 (file)
index 0000000..1d88566
--- /dev/null
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<style>
+@-webkit-variables {
+    borderWidth: 10px;
+    borderStyle: solid;
+    borderColor: green;
+}
+
+div {
+    border: 20px dotted red;
+    border: -webkit-var(borderWidth) -webkit-var(borderStyle) -webkit-var(borderColor);
+}
+</style>
+</head>
+<body>
+<div>This block hould have a 10px solid green border.</div>
\ No newline at end of file
diff --git a/LayoutTests/fast/css/variables/single-term-test.html b/LayoutTests/fast/css/variables/single-term-test.html
new file mode 100644 (file)
index 0000000..a299d29
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<style>
+@-webkit-variables {
+    completeBorder: 10px solid red;
+}
+
+div {
+    border: -webkit-var(completeBorder);
+}
+</style>
+</head>
+<body>
+<div>If this div has a red border, then the test has failed.</div>
\ No newline at end of file
index 4de2ecd5b3302665056f2fb86bac63c1e0cb1876..6361dcdb06c34a170bf25b4a406261f114d39ee6 100644 (file)
@@ -1,3 +1,182 @@
+2008-06-19  David Hyatt  <hyatt@apple.com>
+
+        Add initial support for CSS variables.  Non-dynamic cases should (hopefully) all work.  Things will get
+        confused if you use the CSS OM to remove variables/inject variables, etc.  In addition no DOM APIs are
+        exposed yet for the new variable interfaces.
+
+        Reviewed by Beth
+
+        Added many tests to fast/css/variables/
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * css/CSSFunctionValue.cpp: Added.
+        (WebCore::CSSFunctionValue::CSSFunctionValue):
+        (WebCore::CSSFunctionValue::~CSSFunctionValue):
+        (WebCore::CSSFunctionValue::cssText):
+        (WebCore::CSSFunctionValue::parserValue):
+        * css/CSSFunctionValue.h: Added.
+        (WebCore::CSSFunctionValue::create):
+        * css/CSSGrammar.y:
+        * css/CSSMutableStyleDeclaration.cpp:
+        (WebCore::CSSMutableStyleDeclaration::CSSMutableStyleDeclaration):
+        (WebCore::CSSMutableStyleDeclaration::copy):
+        * css/CSSMutableStyleDeclaration.h:
+        (WebCore::CSSMutableStyleDeclaration::create):
+        (WebCore::CSSMutableStyleDeclaration::hasVariableDependentValue):
+        * css/CSSParser.cpp:
+        (WebCore::equal):
+        (WebCore::equalIgnoringCase):
+        (WebCore::CSSParser::~CSSParser):
+        (WebCore::CSSParserString::lower):
+        (WebCore::CSSParser::document):
+        (WebCore::CSSParser::validUnit):
+        (WebCore::unitFromString):
+        (WebCore::CSSParser::checkForOrphanedUnits):
+        (WebCore::CSSParser::parseValue):
+        (WebCore::CSSParser::parseFillShorthand):
+        (WebCore::CSSParser::parseTransitionShorthand):
+        (WebCore::CSSParser::parseContent):
+        (WebCore::CSSParser::parseFillImage):
+        (WebCore::CSSParser::parseFillPosition):
+        (WebCore::CSSParser::parseFillSize):
+        (WebCore::CSSParser::parseFillProperty):
+        (WebCore::CSSParser::parseTransitionDuration):
+        (WebCore::CSSParser::parseTransitionRepeatCount):
+        (WebCore::CSSParser::parseTimingFunctionValue):
+        (WebCore::CSSParser::parseTransitionTimingFunction):
+        (WebCore::CSSParser::parseTransitionProperty):
+        (WebCore::skipCommaInDashboardRegion):
+        (WebCore::CSSParser::parseDashboardRegions):
+        (WebCore::CSSParser::parseCounterContent):
+        (WebCore::CSSParser::parseShape):
+        (WebCore::CSSParser::parseFont):
+        (WebCore::CSSParser::parseFontFamily):
+        (WebCore::CSSParser::parseFontFaceSrc):
+        (WebCore::CSSParser::parseFontFaceUnicodeRange):
+        (WebCore::CSSParser::parseColorParameters):
+        (WebCore::CSSParser::parseHSLParameters):
+        (WebCore::CSSParser::parseColor):
+        (WebCore::CSSParser::parseColorFromValue):
+        (WebCore::ShadowParseContext::commitLength):
+        (WebCore::CSSParser::parseShadow):
+        (WebCore::CSSParser::parseReflect):
+        (WebCore::BorderImageParseContext::commitNumber):
+        (WebCore::BorderImageParseContext::commitWidth):
+        (WebCore::BorderImageParseContext::commitBorderImage):
+        (WebCore::CSSParser::parseBorderImage):
+        (WebCore::CSSParser::parseCounter):
+        (WebCore::parseGradientPoint):
+        (WebCore::parseGradientColorStop):
+        (WebCore::CSSParser::parseGradient):
+        (WebCore::CSSParser::parseCanvas):
+        (WebCore::TransformOperationInfo::TransformOperationInfo):
+        (WebCore::CSSParser::parseTransform):
+        (WebCore::CSSParser::lex):
+        (WebCore::CSSParser::text):
+        (WebCore::CSSParser::createFloatingValueList):
+        (WebCore::CSSParser::sinkFloatingValueList):
+        (WebCore::CSSParser::createFloatingFunction):
+        (WebCore::CSSParser::sinkFloatingFunction):
+        (WebCore::CSSParser::sinkFloatingValue):
+        (WebCore::CSSParser::createFloatingMediaQueryExp):
+        (WebCore::CSSParser::createCharsetRule):
+        (WebCore::CSSParser::createImportRule):
+        (WebCore::CSSParser::createVariablesRule):
+        (WebCore::CSSParser::addVariable):
+        (WebCore::CSSParser::clearVariables):
+        (WebCore::CSSParser::parseVariable):
+        (WebCore::CSSParser::parsePropertyWithResolvedVariables):
+        (WebCore::CSSParser::checkForVariables):
+        (WebCore::CSSParser::addUnresolvedProperty):
+        (WebCore::cssPropertyID):
+        (WebCore::cssValueKeywordID):
+        * css/CSSParser.h:
+        * css/CSSParserValues.cpp: Added.
+        (WebCore::CSSParserValueList::~CSSParserValueList):
+        (WebCore::CSSParserValueList::addValue):
+        (WebCore::CSSParserValueList::deleteValueAt):
+        (WebCore::CSSParserValue::createCSSValue):
+        * css/CSSParserValues.h: Added.
+        (WebCore::CSSParserString::operator String):
+        (WebCore::CSSParserString::operator AtomicString):
+        (WebCore::CSSParserValue::):
+        (WebCore::CSSParserValueList::CSSParserValueList):
+        (WebCore::CSSParserValueList::size):
+        (WebCore::CSSParserValueList::current):
+        (WebCore::CSSParserValueList::next):
+        (WebCore::CSSParserValueList::valueAt):
+        (WebCore::CSSParserValueList::clear):
+        (WebCore::CSSParserValueList::containsVariables):
+        (WebCore::CSSParserFunction::~CSSParserFunction):
+        * css/CSSPrimitiveValue.cpp:
+        (WebCore::CSSPrimitiveValue::getStringValue):
+        (WebCore::CSSPrimitiveValue::cssText):
+        (WebCore::CSSPrimitiveValue::parserValue):
+        * css/CSSPrimitiveValue.h:
+        (WebCore::CSSPrimitiveValue::):
+        (WebCore::CSSPrimitiveValue::setPrimitiveType):
+        * css/CSSRule.h:
+        (WebCore::CSSRule::):
+        * css/CSSRule.idl:
+        * css/CSSStyleDeclaration.cpp:
+        (WebCore::CSSStyleDeclaration::copyPropertiesInSet):
+        * css/CSSStyleSelector.cpp:
+        (WebCore::CSSStyleSelector::addMatchedDeclaration):
+        (WebCore::CSSStyleSelector::addVariables):
+        (WebCore::CSSStyleSelector::resolveVariableDependentValue):
+        (WebCore::CSSRuleSet::addRulesFromSheet):
+        (WebCore::CSSStyleSelector::applyDeclarations):
+        * css/CSSStyleSelector.h:
+        * css/CSSValue.h:
+        (WebCore::CSSValue::isVariableDependentValue):
+        (WebCore::CSSValue::parserValue):
+        * css/CSSValueList.cpp:
+        (WebCore::CSSValueList::CSSValueList):
+        (WebCore::CSSValueList::createParserValueList):
+        * css/CSSValueList.h:
+        (WebCore::CSSValueList::createFromParserValueList):
+        * css/CSSVariableDependentValue.cpp: Added.
+        (WebCore::CSSVariableDependentValue::CSSVariableDependentValue):
+        (WebCore::CSSVariableDependentValue::~CSSVariableDependentValue):
+        (WebCore::CSSVariableDependentValue::cssText):
+        * css/CSSVariableDependentValue.h: Added.
+        (WebCore::CSSVariableDependentValue::create):
+        (WebCore::CSSVariableDependentValue::isVariableDependentValue):
+        (WebCore::CSSVariableDependentValue::valueList):
+        * css/CSSVariablesDeclaration.cpp: Added.
+        (WebCore::CSSVariablesDeclaration::CSSVariablesDeclaration):
+        (WebCore::CSSVariablesDeclaration::~CSSVariablesDeclaration):
+        (WebCore::CSSVariablesDeclaration::getVariableValue):
+        (WebCore::CSSVariablesDeclaration::removeVariable):
+        (WebCore::CSSVariablesDeclaration::setVariable):
+        (WebCore::CSSVariablesDeclaration::addParsedVariable):
+        (WebCore::CSSVariablesDeclaration::getParsedVariable):
+        (WebCore::CSSVariablesDeclaration::length):
+        (WebCore::CSSVariablesDeclaration::item):
+        (WebCore::CSSVariablesDeclaration::parentRule):
+        (WebCore::CSSVariablesDeclaration::cssText):
+        * css/CSSVariablesDeclaration.h: Added.
+        (WebCore::CSSVariablesDeclaration::create):
+        * css/CSSVariablesRule.cpp: Added.
+        (WebCore::CSSVariablesRule::CSSVariablesRule):
+        (WebCore::CSSVariablesRule::~CSSVariablesRule):
+        (WebCore::CSSVariablesRule::cssText):
+        * css/CSSVariablesRule.h: Added.
+        (WebCore::CSSVariablesRule::media):
+        (WebCore::CSSVariablesRule::variables):
+        (WebCore::CSSVariablesRule::type):
+        (WebCore::CSSVariablesRule::isVariablesRule):
+        (WebCore::CSSVariablesRule::setDeclaration):
+        * css/MediaQueryExp.cpp:
+        (WebCore::MediaQueryExp::MediaQueryExp):
+        * css/MediaQueryExp.h:
+        * css/SVGCSSParser.cpp:
+        (WebCore::CSSParser::parseSVGValue):
+        (WebCore::CSSParser::parseSVGStrokeDasharray):
+        * css/StyleBase.h:
+        (WebCore::StyleBase::isVariablesRule):
+        * css/tokenizer.flex:
+
 2008-06-19  Julien Chaffraix  <jchaffraix@webkit.org>
 
         Reviewed by Darin.
index e054d38efb5ae9c02552405ca403378b5189dfa5..ca1a722dbfb432050f84a8110da2075238f44090 100644 (file)
                B2FA3E190AB75A6F000E5AC4 /* JSSVGZoomEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = B2FA3D310AB75A6F000E5AC4 /* JSSVGZoomEvent.h */; };
                BC014C740CC5579D009C4B20 /* SecurityOrigin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC014C720CC5579D009C4B20 /* SecurityOrigin.cpp */; };
                BC014C750CC5579D009C4B20 /* SecurityOrigin.h in Headers */ = {isa = PBXBuildFile; fileRef = BC014C730CC5579D009C4B20 /* SecurityOrigin.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               BC02A4B70E0997B9004B6D2B /* CSSParserValues.h in Headers */ = {isa = PBXBuildFile; fileRef = BC02A4B60E0997B9004B6D2B /* CSSParserValues.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               BC02A5400E099C5A004B6D2B /* CSSParserValues.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC02A53F0E099C5A004B6D2B /* CSSParserValues.cpp */; };
+               BC02A63C0E09A9CF004B6D2B /* CSSFunctionValue.h in Headers */ = {isa = PBXBuildFile; fileRef = BC02A63B0E09A9CF004B6D2B /* CSSFunctionValue.h */; };
+               BC02A6460E09AAE9004B6D2B /* CSSFunctionValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC02A6450E09AAE9004B6D2B /* CSSFunctionValue.cpp */; };
                BC066F6F09FEB2FA00C589A7 /* WebCoreTextRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = BC066F6C09FEB2FA00C589A7 /* WebCoreTextRenderer.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC06ED060BFD5BAE00856E9D /* JSHTMLTableSectionElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC06ED040BFD5BAE00856E9D /* JSHTMLTableSectionElement.cpp */; };
                BC06ED070BFD5BAE00856E9D /* JSHTMLTableSectionElement.h in Headers */ = {isa = PBXBuildFile; fileRef = BC06ED050BFD5BAE00856E9D /* JSHTMLTableSectionElement.h */; };
                BCCBAD3B0C18BFF800CE890F /* JSHTMLCollectionCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCCBAD3A0C18BFF800CE890F /* JSHTMLCollectionCustom.cpp */; };
                BCCBAD400C18C14200CE890F /* JSHTMLCollection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCCBAD3E0C18C14200CE890F /* JSHTMLCollection.cpp */; };
                BCCBAD410C18C14200CE890F /* JSHTMLCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = BCCBAD3F0C18C14200CE890F /* JSHTMLCollection.h */; };
+               BCCBE68A0E06E60D00EAFA8E /* CSSVariablesDeclaration.h in Headers */ = {isa = PBXBuildFile; fileRef = BCCBE6870E06E60D00EAFA8E /* CSSVariablesDeclaration.h */; };
+               BCCBE68B0E06E60D00EAFA8E /* CSSVariablesRule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCCBE6880E06E60D00EAFA8E /* CSSVariablesRule.cpp */; };
+               BCCBE68C0E06E60D00EAFA8E /* CSSVariablesRule.h in Headers */ = {isa = PBXBuildFile; fileRef = BCCBE6890E06E60D00EAFA8E /* CSSVariablesRule.h */; };
+               BCCBE69B0E06F51000EAFA8E /* CSSVariablesDeclaration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCCBE69A0E06F51000EAFA8E /* CSSVariablesDeclaration.cpp */; };
+               BCCBE7B20E07159A00EAFA8E /* CSSVariableDependentValue.h in Headers */ = {isa = PBXBuildFile; fileRef = BCCBE7B10E07159A00EAFA8E /* CSSVariableDependentValue.h */; };
+               BCCBE7B50E07166900EAFA8E /* CSSVariableDependentValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCCBE7B40E07166900EAFA8E /* CSSVariableDependentValue.cpp */; };
                BCCD74DC0A4C8D35005FDA6D /* HTMLViewSourceDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = BCCD74DB0A4C8D35005FDA6D /* HTMLViewSourceDocument.h */; };
                BCCD74E50A4C8DDF005FDA6D /* HTMLViewSourceDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCCD74E40A4C8DDF005FDA6D /* HTMLViewSourceDocument.cpp */; };
                BCCFBAE80B5152ED0001F1D7 /* Tokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = BCCFBAE70B5152ED0001F1D7 /* Tokenizer.h */; settings = {ATTRIBUTES = (Private, ); }; };
                B2FA3D310AB75A6F000E5AC4 /* JSSVGZoomEvent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSSVGZoomEvent.h; sourceTree = "<group>"; };
                BC014C720CC5579D009C4B20 /* SecurityOrigin.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SecurityOrigin.cpp; sourceTree = "<group>"; };
                BC014C730CC5579D009C4B20 /* SecurityOrigin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecurityOrigin.h; sourceTree = "<group>"; };
+               BC02A4B60E0997B9004B6D2B /* CSSParserValues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSParserValues.h; sourceTree = "<group>"; };
+               BC02A53F0E099C5A004B6D2B /* CSSParserValues.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSParserValues.cpp; sourceTree = "<group>"; };
+               BC02A63B0E09A9CF004B6D2B /* CSSFunctionValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSFunctionValue.h; sourceTree = "<group>"; };
+               BC02A6450E09AAE9004B6D2B /* CSSFunctionValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSFunctionValue.cpp; sourceTree = "<group>"; };
                BC066F6C09FEB2FA00C589A7 /* WebCoreTextRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WebCoreTextRenderer.h; sourceTree = "<group>"; };
                BC06ED040BFD5BAE00856E9D /* JSHTMLTableSectionElement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLTableSectionElement.cpp; sourceTree = "<group>"; };
                BC06ED050BFD5BAE00856E9D /* JSHTMLTableSectionElement.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSHTMLTableSectionElement.h; sourceTree = "<group>"; };
                BCCBAD3A0C18BFF800CE890F /* JSHTMLCollectionCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLCollectionCustom.cpp; sourceTree = "<group>"; };
                BCCBAD3E0C18C14200CE890F /* JSHTMLCollection.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLCollection.cpp; sourceTree = "<group>"; };
                BCCBAD3F0C18C14200CE890F /* JSHTMLCollection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSHTMLCollection.h; sourceTree = "<group>"; };
+               BCCBE6870E06E60D00EAFA8E /* CSSVariablesDeclaration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSVariablesDeclaration.h; sourceTree = "<group>"; };
+               BCCBE6880E06E60D00EAFA8E /* CSSVariablesRule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSVariablesRule.cpp; sourceTree = "<group>"; };
+               BCCBE6890E06E60D00EAFA8E /* CSSVariablesRule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSVariablesRule.h; sourceTree = "<group>"; };
+               BCCBE69A0E06F51000EAFA8E /* CSSVariablesDeclaration.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSVariablesDeclaration.cpp; sourceTree = "<group>"; };
+               BCCBE7B10E07159A00EAFA8E /* CSSVariableDependentValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSVariableDependentValue.h; sourceTree = "<group>"; };
+               BCCBE7B40E07166900EAFA8E /* CSSVariableDependentValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSVariableDependentValue.cpp; sourceTree = "<group>"; };
                BCCD74DB0A4C8D35005FDA6D /* HTMLViewSourceDocument.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HTMLViewSourceDocument.h; sourceTree = "<group>"; };
                BCCD74E40A4C8DDF005FDA6D /* HTMLViewSourceDocument.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLViewSourceDocument.cpp; sourceTree = "<group>"; };
                BCCFBAE70B5152ED0001F1D7 /* Tokenizer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Tokenizer.h; sourceTree = "<group>"; };
                                85C56CA60AA89D5F00D95755 /* CSSPageRule.idl */,
                                BC772B370C4EA91E0083285F /* CSSParser.cpp */,
                                BC772B380C4EA91E0083285F /* CSSParser.h */,
+                               BC02A4B60E0997B9004B6D2B /* CSSParserValues.h */,
+                               BC02A6450E09AAE9004B6D2B /* CSSFunctionValue.cpp */,
+                               BC02A63B0E09A9CF004B6D2B /* CSSFunctionValue.h */,
+                               BC02A53F0E099C5A004B6D2B /* CSSParserValues.cpp */,
                                A80E6CDB0A1989CA007FB8C5 /* CSSPrimitiveValue.cpp */,
                                A80E6CBC0A1989CA007FB8C5 /* CSSPrimitiveValue.h */,
                                9307059009E0C75800B17FE4 /* CSSPrimitiveValue.idl */,
                                A80E6CBA0A1989CA007FB8C5 /* CSSValueList.cpp */,
                                A80E6CBF0A1989CA007FB8C5 /* CSSValueList.h */,
                                A8D0651C0A23C1FE005E7203 /* CSSValueList.idl */,
+                               BCCBE7B10E07159A00EAFA8E /* CSSVariableDependentValue.h */,
+                               BCCBE7B40E07166900EAFA8E /* CSSVariableDependentValue.cpp */,
+                               BCCBE69A0E06F51000EAFA8E /* CSSVariablesDeclaration.cpp */,
+                               BCCBE6870E06E60D00EAFA8E /* CSSVariablesDeclaration.h */,
+                               BCCBE6880E06E60D00EAFA8E /* CSSVariablesRule.cpp */,
+                               BCCBE6890E06E60D00EAFA8E /* CSSVariablesRule.h */,
                                A80E6CE10A1989CA007FB8C5 /* DashboardRegion.h */,
                                FE49EF970DC51462004266E1 /* DashboardSupportCSSPropertyNames.in */,
                                A80E6CC20A1989CA007FB8C5 /* FontFamilyValue.cpp */,
                                65488D6B0DD5A83D009D83B2 /* StringSourceProvider.h in Headers */,
                                652FBBBC0DE27CB60001D386 /* JSDOMWindowCustom.h in Headers */,
                                E1A302BC0DE8370300C52F2C /* StringBuilder.h in Headers */,
+                               BCCBE68A0E06E60D00EAFA8E /* CSSVariablesDeclaration.h in Headers */,
+                               BCCBE68C0E06E60D00EAFA8E /* CSSVariablesRule.h in Headers */,
+                               BCCBE7B20E07159A00EAFA8E /* CSSVariableDependentValue.h in Headers */,
+                               BC02A4B70E0997B9004B6D2B /* CSSParserValues.h in Headers */,
+                               BC02A63C0E09A9CF004B6D2B /* CSSFunctionValue.h in Headers */,
                                AB40484E0E083FA8007D6920 /* MediaDocument.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                                1A2D753E0DE47FAB00F0A648 /* IconFetcher.cpp in Sources */,
                                E1A302C10DE8376900C52F2C /* StringBuilder.cpp in Sources */,
                                1A2C40AB0DEB55AA005AF19E /* JSTextCustom.cpp in Sources */,
+                               BCCBE68B0E06E60D00EAFA8E /* CSSVariablesRule.cpp in Sources */,
+                               BCCBE69B0E06F51000EAFA8E /* CSSVariablesDeclaration.cpp in Sources */,
+                               BCCBE7B50E07166900EAFA8E /* CSSVariableDependentValue.cpp in Sources */,
+                               BC02A5400E099C5A004B6D2B /* CSSParserValues.cpp in Sources */,
+                               BC02A6460E09AAE9004B6D2B /* CSSFunctionValue.cpp in Sources */,
                                AB40484D0E083FA8007D6920 /* MediaDocument.cpp in Sources */,
                                A7D27FC40E0A599F0079AD2B /* SVGFETile.cpp in Sources */,
                        );
diff --git a/WebCore/css/CSSFunctionValue.cpp b/WebCore/css/CSSFunctionValue.cpp
new file mode 100644 (file)
index 0000000..cb938ed
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "CSSFunctionValue.h"
+#include "CSSValueList.h"
+
+namespace WebCore {
+
+CSSFunctionValue::CSSFunctionValue(CSSParserFunction* function)
+{
+    m_name = function->name;
+    if (function->args)
+        m_args = CSSValueList::createFromParserValueList(function->args);
+}
+
+CSSFunctionValue::~CSSFunctionValue()
+{
+}
+
+String CSSFunctionValue::cssText() const
+{
+    String result = m_name; // Includes the '('
+    if (m_args)
+        result += m_args->cssText();
+    result += ")";
+    return result;
+}
+
+CSSParserValue CSSFunctionValue::parserValue() const
+{
+    CSSParserValue val;
+    val.id = 0;
+    val.unit = CSSParserValue::Function;
+    val.function = new CSSParserFunction;
+    val.function->name.characters = const_cast<UChar*>(m_name.characters());
+    val.function->name.length = m_name.length();
+    val.function->args = m_args ? m_args->createParserValueList() : 0;
+    return val;
+}
+
+}
diff --git a/WebCore/css/CSSFunctionValue.h b/WebCore/css/CSSFunctionValue.h
new file mode 100644 (file)
index 0000000..e9545a1
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef CSSFunctionValue_h
+#define CSSFunctionValue_h
+
+#include "CSSValue.h"
+
+namespace WebCore {
+
+class CSSValueList;
+struct CSSParserFunction;
+
+class CSSFunctionValue : public CSSValue {
+public:
+    static PassRefPtr<CSSFunctionValue> create(CSSParserFunction* function)
+    {
+        return adoptRef(new CSSFunctionValue(function));
+    }
+
+    ~CSSFunctionValue();
+    
+    virtual String cssText() const;
+
+    virtual CSSParserValue parserValue() const;
+
+private:
+    CSSFunctionValue(CSSParserFunction*);
+    
+    String m_name;
+    RefPtr<CSSValueList> m_args;
+};
+
+}
+#endif
+
index c2c47bb8b31589331c2307544794e6f1c4ff8e73..11390a7b33ee414d7f55edc9f70d978d4a2c8f5a 100644 (file)
@@ -56,7 +56,7 @@ using namespace HTMLNames;
     char character;
     int integer;
     double number;
-    ParseString string;
+    CSSParserString string;
 
     CSSRule* rule;
     CSSRuleList* ruleList;
@@ -66,8 +66,8 @@ using namespace HTMLNames;
     MediaQuery* mediaQuery;
     MediaQuery::Restrictor mediaQueryRestrictor;
     MediaQueryExp* mediaQueryExp;
-    Value value;
-    ValueList* valueList;
+    CSSParserValue value;
+    CSSParserValueList* valueList;
     Vector<MediaQueryExp*>* mediaQueryExpList;
 }
 
@@ -85,7 +85,7 @@ static int cssyylex(YYSTYPE* yylval, void* parser)
 
 %}
 
-%expect 42
+%expect 44
 
 %left UNIMPORTANT_TOK
 
@@ -120,6 +120,8 @@ static int cssyylex(YYSTYPE* yylval, void* parser)
 %token WEBKIT_DECLS_SYM
 %token WEBKIT_VALUE_SYM
 %token WEBKIT_MEDIAQUERY_SYM
+%token WEBKIT_VARIABLES_SYM
+%token WEBKIT_VARIABLES_DECLS_SYM
 
 %token IMPORTANT_SYM
 %token MEDIA_ONLY
@@ -153,6 +155,8 @@ static int cssyylex(YYSTYPE* yylval, void* parser)
 
 %token <string> UNICODERANGE
 
+%token <string> VARCALL
+
 %type <relation> combinator
 
 %type <rule> charset
@@ -167,6 +171,7 @@ static int cssyylex(YYSTYPE* yylval, void* parser)
 %type <rule> invalid_import
 %type <rule> rule
 %type <rule> valid_rule
+%type <rule> variables_rule
 
 %type <string> maybe_ns_prefix
 
@@ -215,18 +220,25 @@ static int cssyylex(YYSTYPE* yylval, void* parser)
 %type <value> term
 %type <value> unary_term
 %type <value> function
+%type <value> term_or_varcall
 
 %type <string> element_name
 %type <string> attr_name
 
+%type <string> variable_name
+%type <boolean> variables_declaration_list
+%type <boolean> variables_decl_list
+%type <boolean> variables_declaration
+
 %%
 
 stylesheet:
-    maybe_charset maybe_sgml import_list namespace_list rule_list
+    maybe_charset maybe_sgml import_list variables_list namespace_list rule_list
   | webkit_rule maybe_space
   | webkit_decls maybe_space
   | webkit_value maybe_space
   | webkit_mediaquery maybe_space
+  | webkit_variables_decls maybe_space
   ;
 
 valid_rule_or_import:
@@ -246,6 +258,12 @@ webkit_decls:
     }
 ;
 
+webkit_variables_decls:
+    WEBKIT_VARIABLES_DECLS_SYM '{' maybe_space variables_declaration_list '}' {
+        /* can be empty */
+    }
+;
+
 webkit_value:
     WEBKIT_VALUE_SYM '{' maybe_space expr '}' {
         CSSParser* p = static_cast<CSSParser*>(parser);
@@ -306,6 +324,15 @@ import_list:
  }
  ;
 
+variables_list:
+/* empty */
+| variables_list variables_rule maybe_sgml {
+    CSSParser* p = static_cast<CSSParser*>(parser);
+     if ($2 && p->m_styleSheet)
+         p->m_styleSheet->append($2);
+}
+;
+
 namespace_list:
 /* empty */
 | namespace_list namespace maybe_sgml
@@ -346,6 +373,91 @@ import:
     }
   ;
 
+variables_rule:
+    WEBKIT_VARIABLES_SYM maybe_space maybe_media_list '{' maybe_space variables_declaration_list '}' {
+        $$ = static_cast<CSSParser*>(parser)->createVariablesRule($3);
+    }
+    ;
+
+variables_declaration_list:
+    variables_declaration {
+        $$ = $1;
+    }
+    | variables_decl_list variables_declaration {
+        $$ = $1;
+        if ($2)
+            $$ = $2;
+    }
+    | variables_decl_list {
+        $$ = $1;
+    }
+    | error invalid_block_list error {
+        $$ = false;
+    }
+    | error {
+        $$ = false;
+    }
+    | variables_decl_list error {
+        $$ = $1;
+    }
+    ;
+
+variables_decl_list:
+    variables_declaration ';' maybe_space {
+        $$ = $1;
+    }
+    | variables_declaration invalid_block_list ';' maybe_space {
+        $$ = false;
+    }
+    | error ';' maybe_space {
+        $$ = false;
+    }
+    | error invalid_block_list error ';' maybe_space {
+        $$ = false;
+    }
+    | variables_decl_list variables_declaration ';' maybe_space {
+        $$ = $1;
+        if ($2)
+            $$ = $2;
+    }
+    | variables_decl_list error ';' maybe_space {
+        $$ = $1;
+    }
+    | variables_decl_list error invalid_block_list error ';' maybe_space {
+        $$ = $1;
+    }
+    ;
+
+variables_declaration:
+    variable_name ':' maybe_space term {
+        $$ = static_cast<CSSParser*>(parser)->addVariable($1, $4);
+    }
+    |
+    variable_name error {
+        $$ = false;
+    }
+    |
+    variable_name ':' maybe_space error term {
+        $$ = false;
+    }
+    |
+    variable_name ':' maybe_space {
+        /* @variables { varname: } Just reduce away this variable with no value. */
+        $$ = false;
+    }
+    |
+    variable_name ':' maybe_space error {
+        /* if we come across rules with invalid values like this case: @variables { varname: *; }, just discard the property/value pair */
+        $$ = false;
+    }
+    ;
+
+variable_name:
+    IDENT maybe_space {
+        $$ = $1;
+    }
+    ;
+
 namespace:
 NAMESPACE_SYM maybe_space maybe_ns_prefix string_or_uri maybe_space ';' {
     CSSParser* p = static_cast<CSSParser*>(parser);
@@ -667,7 +779,7 @@ simple_selector:
 
 element_name:
     IDENT {
-        ParseString& str = $1;
+        CSSParserString& str = $1;
         CSSParser* p = static_cast<CSSParser*>(parser);
         Document* doc = p->document();
         if (doc && doc->isHTMLDocument())
@@ -745,7 +857,7 @@ class:
 
 attr_name:
     IDENT maybe_space {
-        ParseString& str = $1;
+        CSSParserString& str = $1;
         CSSParser* p = static_cast<CSSParser*>(parser);
         Document* doc = p->document();
         if (doc && doc->isHTMLDocument())
@@ -1024,19 +1136,19 @@ prio:
   ;
 
 expr:
-    term {
+    term_or_varcall {
         CSSParser* p = static_cast<CSSParser*>(parser);
         $$ = p->createFloatingValueList();
         $$->addValue(p->sinkFloatingValue($1));
     }
-    | expr operator term {
+    | expr operator term_or_varcall {
         CSSParser* p = static_cast<CSSParser*>(parser);
         $$ = $1;
         if ($$) {
             if ($2) {
-                Value v;
+                CSSParserValue v;
                 v.id = 0;
-                v.unit = Value::Operator;
+                v.unit = CSSParserValue::Operator;
                 v.iValue = $2;
                 $$->addValue(v);
             }
@@ -1048,6 +1160,17 @@ expr:
     }
   ;
 
+term_or_varcall:
+    term {
+        $$ = $1;
+    }
+    | VARCALL maybe_space {
+        $$.id = 0;
+        $$.string = $1;
+        $$.unit = CSSPrimitiveValue::CSS_PARSER_VARIABLE;
+    }
+    ;
+
 operator:
     '/' maybe_space {
         $$ = '/';
@@ -1075,7 +1198,7 @@ term:
   | URI maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_URI; }
   | UNICODERANGE maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_UNICODE_RANGE }
   | hexcolor { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_RGBCOLOR; }
-  | '#' maybe_space { $$.id = 0; $$.string = ParseString(); $$.unit = CSSPrimitiveValue::CSS_RGBCOLOR; } /* Handle error case: "color: #;" */
+  | '#' maybe_space { $$.id = 0; $$.string = CSSParserString(); $$.unit = CSSPrimitiveValue::CSS_RGBCOLOR; } /* Handle error case: "color: #;" */
   /* FIXME: according to the specs a function can have a unary_operator in front. I know no case where this makes sense */
   | function {
       $$ = $1;
@@ -1101,7 +1224,7 @@ unary_term:
   | HERZ maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_HZ; }
   | KHERZ maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_KHZ; }
   | EMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_EMS; }
-  | QEMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = Value::Q_EMS; }
+  | QEMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSParserValue::Q_EMS; }
   | EXS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_EXS; }
     ;
 
@@ -1109,20 +1232,20 @@ unary_term:
 function:
     FUNCTION maybe_space expr ')' maybe_space {
         CSSParser* p = static_cast<CSSParser*>(parser);
-        Function* f = p->createFloatingFunction();
+        CSSParserFunction* f = p->createFloatingFunction();
         f->name = $1;
         f->args = p->sinkFloatingValueList($3);
         $$.id = 0;
-        $$.unit = Value::Function;
+        $$.unit = CSSParserValue::Function;
         $$.function = f;
     } |
     FUNCTION maybe_space error {
         CSSParser* p = static_cast<CSSParser*>(parser);
-        Function* f = p->createFloatingFunction();
+        CSSParserFunction* f = p->createFloatingFunction();
         f->name = $1;
         f->args = 0;
         $$.id = 0;
-        $$.unit = Value::Function;
+        $$.unit = CSSParserValue::Function;
         $$.function = f;
   }
   ;
index 7fe9b0cc66809f8c944262895315334345db9b62..59791124a832d088fe7a50682b35753dfd9d2be2 100644 (file)
@@ -37,19 +37,22 @@ namespace WebCore {
 
 CSSMutableStyleDeclaration::CSSMutableStyleDeclaration()
     : m_node(0)
+    , m_variableDependentValueCount(0)
 {
 }
 
 CSSMutableStyleDeclaration::CSSMutableStyleDeclaration(CSSRule* parent)
     : CSSStyleDeclaration(parent)
     , m_node(0)
+    , m_variableDependentValueCount(0)
 {
 }
 
-CSSMutableStyleDeclaration::CSSMutableStyleDeclaration(CSSRule* parent, const DeprecatedValueList<CSSProperty>& values)
+CSSMutableStyleDeclaration::CSSMutableStyleDeclaration(CSSRule* parent, const DeprecatedValueList<CSSProperty>& values, unsigned variableDependentValueCount)
     : CSSStyleDeclaration(parent)
     , m_values(values)
     , m_node(0)
+    , m_variableDependentValueCount(variableDependentValueCount)
 {
     // FIXME: This allows duplicate properties.
 }
@@ -57,10 +60,13 @@ CSSMutableStyleDeclaration::CSSMutableStyleDeclaration(CSSRule* parent, const De
 CSSMutableStyleDeclaration::CSSMutableStyleDeclaration(CSSRule* parent, const CSSProperty* const * properties, int numProperties)
     : CSSStyleDeclaration(parent)
     , m_node(0)
+    , m_variableDependentValueCount(0)
 {
     for (int i = 0; i < numProperties; ++i) {
         ASSERT(properties[i]);
         m_values.append(*properties[i]);
+        if (properties[i]->value()->isVariableDependentValue())
+            m_variableDependentValueCount++;
     }
     // FIXME: This allows duplicate properties.
 }
@@ -799,7 +805,7 @@ PassRefPtr<CSSMutableStyleDeclaration> CSSMutableStyleDeclaration::makeMutable()
 
 PassRefPtr<CSSMutableStyleDeclaration> CSSMutableStyleDeclaration::copy() const
 {
-    return adoptRef(new CSSMutableStyleDeclaration(0, m_values));
+    return adoptRef(new CSSMutableStyleDeclaration(0, m_values, m_variableDependentValueCount));
 }
 
 } // namespace WebCore
index 2470200bbbc6ed65ee469302991ef0118ebe6f02..56666ead0723ba0dc1db974b12b103e8d99118ff 100644 (file)
@@ -37,13 +37,17 @@ public:
     {
         return adoptRef(new CSSMutableStyleDeclaration);
     }
+    static PassRefPtr<CSSMutableStyleDeclaration> create(CSSRule* parentRule)
+    {
+        return adoptRef(new CSSMutableStyleDeclaration(parentRule));
+    }
     static PassRefPtr<CSSMutableStyleDeclaration> create(CSSRule* parentRule, const CSSProperty* const* properties, int numProperties)
     {
         return adoptRef(new CSSMutableStyleDeclaration(parentRule, properties, numProperties));
     }
-    static PassRefPtr<CSSMutableStyleDeclaration> create(const DeprecatedValueList<CSSProperty>& properties)
+    static PassRefPtr<CSSMutableStyleDeclaration> create(const DeprecatedValueList<CSSProperty>& properties, unsigned variableDependentValueCount)
     {
-        return adoptRef(new CSSMutableStyleDeclaration(0, properties));
+        return adoptRef(new CSSMutableStyleDeclaration(0, properties, variableDependentValueCount));
     }
 
     CSSMutableStyleDeclaration& operator=(const CSSMutableStyleDeclaration&);
@@ -104,12 +108,14 @@ public:
 
     void merge(CSSMutableStyleDeclaration*, bool argOverridesOnConflict = true);
 
+    bool hasVariableDependentValue() const { return m_variableDependentValueCount > 0; }
+    
 protected:
     CSSMutableStyleDeclaration(CSSRule* parentRule);
 
 private:
     CSSMutableStyleDeclaration();
-    CSSMutableStyleDeclaration(CSSRule* parentRule, const DeprecatedValueList<CSSProperty>&);
+    CSSMutableStyleDeclaration(CSSRule* parentRule, const DeprecatedValueList<CSSProperty>&, unsigned variableDependentValueCount);
     CSSMutableStyleDeclaration(CSSRule* parentRule, const CSSProperty* const *, int numProperties);
 
     virtual PassRefPtr<CSSMutableStyleDeclaration> makeMutable();
@@ -123,6 +129,7 @@ private:
  
     DeprecatedValueList<CSSProperty> m_values;
     Node* m_node;
+    unsigned m_variableDependentValueCount;
 };
 
 } // namespace WebCore
index 3a206f11c29048b1bf2118f2752d061b7852d449..a2adbd57756ef554673d0f2e7f06b7b474f96877 100644 (file)
@@ -53,6 +53,9 @@
 #include "CSSUnicodeRangeValue.h"
 #include "CSSValueKeywords.h"
 #include "CSSValueList.h"
+#include "CSSVariableDependentValue.h"
+#include "CSSVariablesDeclaration.h"
+#include "CSSVariablesRule.h"
 #include "Counter.h"
 #include "Document.h"
 #include "FloatConversion.h"
@@ -85,7 +88,7 @@ using namespace WTF;
 
 namespace WebCore {
 
-static bool equal(const ParseString& a, const char* b)
+static bool equal(const CSSParserString& a, const char* b)
 {
     for (int i = 0; i < a.length; ++i) {
         if (!b[i])
@@ -96,7 +99,7 @@ static bool equal(const ParseString& a, const char* b)
     return !b[a.length];
 }
 
-static bool equalIgnoringCase(const ParseString& a, const char* b)
+static bool equalIgnoringCase(const CSSParserString& a, const char* b)
 {
     for (int i = 0; i < a.length; ++i) {
         if (!b[i])
@@ -119,14 +122,6 @@ static bool hasPrefix(const char* string, unsigned length, const char* prefix)
     return false;
 }
 
-ValueList::~ValueList()
-{
-     size_t numValues = m_values.size();
-     for (size_t i = 0; i < numValues; i++)
-         if (m_values[i].unit == Value::Function)
-             delete m_values[i].function;
-}
-
 CSSParser::CSSParser(bool strictParsing)
     : m_strict(strictParsing)
     , m_important(false)
@@ -157,6 +152,8 @@ CSSParser::~CSSParser()
     clearProperties();
     fastFree(m_parsedProperties);
 
+    clearVariables();
+    
     delete m_valueList;
 
     fastFree(m_data);
@@ -172,7 +169,7 @@ CSSParser::~CSSParser()
     deleteAllValues(m_floatingFunctions);
 }
 
-void ParseString::lower()
+void CSSParserString::lower()
 {
     // FIXME: If we need Unicode lowercasing here, then we probably want the real kind
     // that can potentially change the length of the string rather than the character
@@ -365,14 +362,14 @@ Document* CSSParser::document() const
 {
     StyleBase* root = m_styleSheet;
     Document* doc = 0;
-    while (root->parent())
+    while (root && root->parent())
         root = root->parent();
-    if (root->isCSSStyleSheet())
+    if (root && root->isCSSStyleSheet())
         doc = static_cast<CSSStyleSheet*>(root)->doc();
     return doc;
 }
 
-bool CSSParser::validUnit(Value* value, Units unitflags, bool strict)
+bool CSSParser::validUnit(CSSParserValue* value, Units unitflags, bool strict)
 {
     if (unitflags & FNonNeg && value->fValue < 0)
         return false;
@@ -391,7 +388,7 @@ bool CSSParser::validUnit(Value* value, Units unitflags, bool strict)
     case CSSPrimitiveValue::CSS_PERCENTAGE:
         b = (unitflags & FPercent);
         break;
-    case Value::Q_EMS:
+    case CSSParserValue::Q_EMS:
     case CSSPrimitiveValue::CSS_EMS:
     case CSSPrimitiveValue::CSS_EXS:
     case CSSPrimitiveValue::CSS_PX:
@@ -420,7 +417,7 @@ bool CSSParser::validUnit(Value* value, Units unitflags, bool strict)
     return b;
 }
 
-static int unitFromString(Value* value)
+static int unitFromString(CSSParserValue* value)
 {
     if (value->unit != CSSPrimitiveValue::CSS_IDENT || value->id)
         return 0;
@@ -466,10 +463,11 @@ void CSSParser::checkForOrphanedUnits()
         
     // The purpose of this code is to implement the WinIE quirk that allows unit types to be separated from their numeric values
     // by whitespace, so e.g., width: 20 px instead of width:20px.  This is invalid CSS, so we don't do this in strict mode.
-    Value* numericVal = 0;
+    CSSParserValue* numericVal = 0;
     unsigned size = m_valueList->size();
     for (unsigned i = 0; i < size; i++) {
-        Value* value = m_valueList->valueAt(i);
+        CSSParserValue* value = m_valueList->valueAt(i);
+
         if (numericVal) {
             // Change the unit type of the numeric val to match.
             int unit = unitFromString(value);
@@ -494,7 +492,7 @@ bool CSSParser::parseValue(int propId, bool important)
     if (!m_valueList)
         return false;
 
-    Value *value = m_valueList->current();
+    CSSParserValue *value = m_valueList->current();
 
     if (!value)
         return false;
@@ -516,6 +514,14 @@ bool CSSParser::parseValue(int propId, bool important)
         return true;
     }
 
+    // If we have any variables, then we don't parse the list of values yet.  We add them to the declaration
+    // as unresolved, and allow them to be parsed later.  The parse is considered "successful" for now, even though
+    // it might ultimately fail once the variable has been resolved.
+    if (!inShorthand() && checkForVariables(m_valueList)) {
+        addUnresolvedProperty(propId, important);
+        return true;
+    }
+
     bool valid_primitive = false;
     RefPtr<CSSValue> parsedValue;
 
@@ -594,7 +600,7 @@ bool CSSParser::parseValue(int propId, bool important)
     case CSSPropertyClip:                 // <shape> | auto | inherit
         if (id == CSSValueAuto)
             valid_primitive = true;
-        else if (value->unit == Value::Function)
+        else if (value->unit == CSSParserValue::Function)
             return parseShape(propId, important);
         break;
 
@@ -807,7 +813,7 @@ bool CSSParser::parseValue(int propId, bool important)
                 if (!uri.isNull())
                     list->append(CSSCursorImageValue::create(KURL(m_styleSheet->baseURL(), uri).string(), hotspot));
             }
-            if ((m_strict && !value) || (value && !(value->unit == Value::Operator && value->iValue == ',')))
+            if ((m_strict && !value) || (value && !(value->unit == CSSParserValue::Operator && value->iValue == ',')))
                 return false;
             value = m_valueList->next(); // comma
         }
@@ -874,7 +880,7 @@ bool CSSParser::parseValue(int propId, bool important)
                 parsedValue = CSSImageValue::create(KURL(m_styleSheet->baseURL(), uri).string());
                 m_valueList->next();
             }
-        } else if (value->unit == Value::Function && equalIgnoringCase(value->function->name, "-webkit-gradient(")) {
+        } else if (value->unit == CSSParserValue::Function && equalIgnoringCase(value->function->name, "-webkit-gradient(")) {
             if (parseGradient(parsedValue))
                 m_valueList->next();
             else
@@ -1083,7 +1089,7 @@ bool CSSParser::parseValue(int propId, bool important)
             valid_primitive = true;
         else {
             RefPtr<CSSValueList> values = CSSValueList::createCommaSeparated();
-            Value* val;
+            CSSParserValue* val;
             RefPtr<CSSValue> parsedValue;
             while ((val = m_valueList->current())) {
                 if (val->unit == CSSPrimitiveValue::CSS_URI) {
@@ -1418,7 +1424,7 @@ bool CSSParser::parseValue(int propId, bool important)
 
 #if ENABLE(DASHBOARD_SUPPORT)
     case CSSPropertyWebkitDashboardRegion:                 // <dashboard-region> | <dashboard-region> 
-        if (value->unit == Value::Function || id == CSSValueNone)
+        if (value->unit == CSSParserValue::Function || id == CSSValueNone)
             return parseDashboardRegions(propId, important);
         break;
 #endif
@@ -1567,7 +1573,7 @@ bool CSSParser::parseValue(int propId, bool important)
             parsedValue = CSSPrimitiveValue::create(value->string, (CSSPrimitiveValue::UnitTypes) value->unit);
         else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
             parsedValue = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
-        else if (value->unit >= Value::Q_EMS)
+        else if (value->unit >= CSSParserValue::Q_EMS)
             parsedValue = CSSQuirkPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_EMS);
         m_valueList->next();
     }
@@ -1613,8 +1619,8 @@ bool CSSParser::parseFillShorthand(int propId, const int* properties, int numPro
     int i;
 
     while (m_valueList->current()) {
-        Value* val = m_valueList->current();
-        if (val->unit == Value::Operator && val->iValue == ',') {
+        CSSParserValue* val = m_valueList->current();
+        if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
             // We hit the end.  Fill in all remaining values with the initial value.
             m_valueList->next();
             for (i = 0; i < numProperties; ++i) {
@@ -1711,8 +1717,8 @@ bool CSSParser::parseTransitionShorthand(bool important)
     
     int i;
     while (m_valueList->current()) {
-        Value* val = m_valueList->current();
-        if (val->unit == Value::Operator && val->iValue == ',') {
+        CSSParserValue* val = m_valueList->current();
+        if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
             // We hit the end.  Fill in all remaining values with the initial value.
             m_valueList->next();
             for (i = 0; i < numProperties; ++i) {
@@ -1860,21 +1866,21 @@ bool CSSParser::parseContent(int propId, bool important)
 {
     RefPtr<CSSValueList> values = CSSValueList::createCommaSeparated();
 
-    while (Value* val = m_valueList->current()) {
+    while (CSSParserValue* val = m_valueList->current()) {
         RefPtr<CSSValue> parsedValue;
         if (val->unit == CSSPrimitiveValue::CSS_URI) {
             // url
             String value = parseURL(val->string);
             parsedValue = CSSImageValue::create(KURL(m_styleSheet->baseURL(), value).string());
-        } else if (val->unit == Value::Function) {
+        } else if (val->unit == CSSParserValue::Function) {
             // attr(X) | counter(X [,Y]) | counters(X, Y, [,Z]) | -webkit-gradient(...)
-            ValueList* args = val->function->args;
+            CSSParserValueList* args = val->function->args;
             if (!args)
                 return false;
             if (equalIgnoringCase(val->function->name, "attr(")) {
                 if (args->size() != 1)
                     return false;
-                Value* a = args->current();
+                CSSParserValue* a = args->current();
                 String attrName = a->string;
                 if (document()->isHTMLDocument())
                     attrName = attrName.lower();
@@ -1939,7 +1945,8 @@ bool CSSParser::parseFillImage(RefPtr<CSSValue>& value)
             value = CSSImageValue::create(KURL(m_styleSheet->baseURL(), uri).string());
         return true;
     }
-    if (m_valueList->current()->unit == Value::Function) {
+
+    if (m_valueList->current()->unit == CSSParserValue::Function) {
         if (equalIgnoringCase(m_valueList->current()->function->name, "-webkit-gradient("))
             return parseGradient(value);
         if (equalIgnoringCase(m_valueList->current()->function->name, "-webkit-canvas("))
@@ -1981,7 +1988,7 @@ PassRefPtr<CSSValue> CSSParser::parseFillPositionXY(bool& xFound, bool& yFound)
 
 void CSSParser::parseFillPosition(RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2)
 {
-    Value* value = m_valueList->current();
+    CSSParserValue* value = m_valueList->current();
     
     // Parse the first value.  We're just making sure that it is one of the valid keywords or a percentage/length.
     bool value1IsX = false, value1IsY = false;
@@ -1995,7 +2002,7 @@ void CSSParser::parseFillPosition(RefPtr<CSSValue>& value1, RefPtr<CSSValue>& va
     value = m_valueList->next();
     
     // First check for the comma.  If so, we are finished parsing this value or value pair.
-    if (value && value->unit == Value::Operator && value->iValue == ',')
+    if (value && value->unit == CSSParserValue::Operator && value->iValue == ',')
         value = 0;
     
     bool value2IsX = false, value2IsY = false;
@@ -2024,7 +2031,7 @@ void CSSParser::parseFillPosition(RefPtr<CSSValue>& value1, RefPtr<CSSValue>& va
 
 PassRefPtr<CSSValue> CSSParser::parseFillSize()
 {
-    Value* value = m_valueList->current();
+    CSSParserValue* value = m_valueList->current();
     RefPtr<CSSPrimitiveValue> parsedValue1;
     
     if (value->id == CSSValueAuto)
@@ -2054,7 +2061,7 @@ bool CSSParser::parseFillProperty(int propId, int& propId1, int& propId2,
 {
     RefPtr<CSSValueList> values;
     RefPtr<CSSValueList> values2;
-    Value* val;
+    CSSParserValue* val;
     RefPtr<CSSValue> value;
     RefPtr<CSSValue> value2;
     
@@ -2076,7 +2083,7 @@ bool CSSParser::parseFillProperty(int propId, int& propId1, int& propId2,
         RefPtr<CSSValue> currValue2;
         
         if (allowComma) {
-            if (val->unit != Value::Operator || val->iValue != ',')
+            if (val->unit != CSSParserValue::Operator || val->iValue != ',')
                 return false;
             m_valueList->next();
             allowComma = false;
@@ -2198,7 +2205,7 @@ bool CSSParser::parseFillProperty(int propId, int& propId1, int& propId2,
 
 PassRefPtr<CSSValue> CSSParser::parseTransitionDuration()
 {
-    Value* value = m_valueList->current();
+    CSSParserValue* value = m_valueList->current();
     if (validUnit(value, FTime, m_strict))
         return CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
     return 0;
@@ -2206,7 +2213,7 @@ PassRefPtr<CSSValue> CSSParser::parseTransitionDuration()
 
 PassRefPtr<CSSValue> CSSParser::parseTransitionRepeatCount()
 {
-    Value* value = m_valueList->current();
+    CSSParserValue* value = m_valueList->current();
     if (value->id == CSSValueInfinite)
         return CSSPrimitiveValue::createIdentifier(value->id);
     if (validUnit(value, FInteger|FNonNeg, m_strict))
@@ -2214,9 +2221,9 @@ PassRefPtr<CSSValue> CSSParser::parseTransitionRepeatCount()
     return 0;
 }
 
-bool CSSParser::parseTimingFunctionValue(ValueList*& args, double& result)
+bool CSSParser::parseTimingFunctionValue(CSSParserValueList*& args, double& result)
 {
-    Value* v = args->current();
+    CSSParserValue* v = args->current();
     if (!validUnit(v, FNumber, m_strict))
         return false;
     result = v->fValue;
@@ -2226,7 +2233,7 @@ bool CSSParser::parseTimingFunctionValue(ValueList*& args, double& result)
     if (!v)
         // The last number in the function has no comma after it, so we're done.
         return true;
-    if (v->unit != Value::Operator && v->iValue != ',')
+    if (v->unit != CSSParserValue::Operator && v->iValue != ',')
         return false;
     v = args->next();
     return true;
@@ -2234,16 +2241,16 @@ bool CSSParser::parseTimingFunctionValue(ValueList*& args, double& result)
 
 PassRefPtr<CSSValue> CSSParser::parseTransitionTimingFunction()
 {
-    Value* value = m_valueList->current();
+    CSSParserValue* value = m_valueList->current();
     if (value->id == CSSValueEase || value->id == CSSValueLinear || value->id == CSSValueEaseIn || value->id == CSSValueEaseOut || value->id == CSSValueEaseInOut)
         return CSSPrimitiveValue::createIdentifier(value->id);
     
     // We must be a function.
-    if (value->unit != Value::Function)
+    if (value->unit != CSSParserValue::Function)
         return 0;
     
     // The only timing function we accept for now is a cubic bezier function.  4 points must be specified.
-    ValueList* args = value->function->args;
+    CSSParserValueList* args = value->function->args;
     if (!equalIgnoringCase(value->function->name, "cubic-bezier(") || !args || args->size() != 7)
         return 0;
 
@@ -2264,7 +2271,7 @@ PassRefPtr<CSSValue> CSSParser::parseTransitionTimingFunction()
 
 PassRefPtr<CSSValue> CSSParser::parseTransitionProperty()
 {
-    Value* value = m_valueList->current();
+    CSSParserValue* value = m_valueList->current();
     if (value->unit != CSSPrimitiveValue::CSS_IDENT)
         return 0;
     int result = cssPropertyID(value->string);
@@ -2280,7 +2287,7 @@ PassRefPtr<CSSValue> CSSParser::parseTransitionProperty()
 bool CSSParser::parseTransitionProperty(int propId, RefPtr<CSSValue>& result)
 {
     RefPtr<CSSValueList> values;
-    Value* val;
+    CSSParserValue* val;
     RefPtr<CSSValue> value;
     bool allowComma = false;
     
@@ -2289,7 +2296,7 @@ bool CSSParser::parseTransitionProperty(int propId, RefPtr<CSSValue>& result)
     while ((val = m_valueList->current())) {
         RefPtr<CSSValue> currValue;
         if (allowComma) {
-            if (val->unit != Value::Operator || val->iValue != ',')
+            if (val->unit != CSSParserValue::Operator || val->iValue != ',')
                 return false;
             m_valueList->next();
             allowComma = false;
@@ -2356,12 +2363,12 @@ bool CSSParser::parseTransitionProperty(int propId, RefPtr<CSSValue>& result)
 #define DASHBOARD_REGION_NUM_PARAMETERS  6
 #define DASHBOARD_REGION_SHORT_NUM_PARAMETERS  2
 
-static Value *skipCommaInDashboardRegion (ValueList *args)
+static CSSParserValue* skipCommaInDashboardRegion (CSSParserValueList *args)
 {
     if (args->size() == (DASHBOARD_REGION_NUM_PARAMETERS*2-1) ||
          args->size() == (DASHBOARD_REGION_SHORT_NUM_PARAMETERS*2-1)) {
-        Value *current = args->current();
-        if (current->unit == Value::Operator && current->iValue == ',')
+        CSSParserValue* current = args->current();
+        if (current->unit == CSSParserValue::Operator && current->iValue == ',')
             return args->next();
     }
     return args->current();
@@ -2371,7 +2378,7 @@ bool CSSParser::parseDashboardRegions(int propId, bool important)
 {
     bool valid = true;
     
-    Value *value = m_valueList->current();
+    CSSParserValue* value = m_valueList->current();
 
     if (value->id == CSSValueNone) {
         if (m_valueList->next())
@@ -2392,7 +2399,7 @@ bool CSSParser::parseDashboardRegions(int propId, bool important)
             region = nextRegion.get();
         }
         
-        if (value->unit != Value::Function) {
+        if (value->unit != CSSParserValue::Function) {
             valid = false;
             break;
         }
@@ -2403,7 +2410,7 @@ bool CSSParser::parseDashboardRegions(int propId, bool important)
         // also allow
         // dashboard-region(label, type) or dashboard-region(label type)
         // dashboard-region(label, type) or dashboard-region(label type)
-        ValueList* args = value->function->args;
+        CSSParserValueList* args = value->function->args;
         if (!equalIgnoringCase(value->function->name, "dashboard-region(") || !args) {
             valid = false;
             break;
@@ -2417,7 +2424,7 @@ bool CSSParser::parseDashboardRegions(int propId, bool important)
         }
             
         // First arg is a label.
-        Value* arg = args->current();
+        CSSParserValue* arg = args->current();
         if (arg->unit != CSSPrimitiveValue::CSS_IDENT) {
             valid = false;
             break;
@@ -2492,7 +2499,7 @@ bool CSSParser::parseDashboardRegions(int propId, bool important)
 
 #endif /* ENABLE(DASHBOARD_SUPPORT) */
 
-PassRefPtr<CSSValue> CSSParser::parseCounterContent(ValueList* args, bool counters)
+PassRefPtr<CSSValue> CSSParser::parseCounterContent(CSSParserValueList* args, bool counters)
 {
     unsigned numArgs = args->size();
     if (counters && numArgs != 3 && numArgs != 5)
@@ -2500,7 +2507,7 @@ PassRefPtr<CSSValue> CSSParser::parseCounterContent(ValueList* args, bool counte
     if (!counters && numArgs != 1 && numArgs != 3)
         return 0;
     
-    Value* i = args->current();
+    CSSParserValue* i = args->current();
     RefPtr<CSSPrimitiveValue> identifier = CSSPrimitiveValue::create(i->string, CSSPrimitiveValue::CSS_STRING);
 
     RefPtr<CSSPrimitiveValue> separator;
@@ -2508,7 +2515,7 @@ PassRefPtr<CSSValue> CSSParser::parseCounterContent(ValueList* args, bool counte
         separator = CSSPrimitiveValue::create(String(), CSSPrimitiveValue::CSS_STRING);
     else {
         i = args->next();
-        if (i->unit != Value::Operator || i->iValue != ',')
+        if (i->unit != CSSParserValue::Operator || i->iValue != ',')
             return 0;
         
         i = args->next();
@@ -2523,7 +2530,7 @@ PassRefPtr<CSSValue> CSSParser::parseCounterContent(ValueList* args, bool counte
     if (!i) // Make the list style default decimal
         listStyle = CSSPrimitiveValue::create(CSSValueDecimal - CSSValueDisc, CSSPrimitiveValue::CSS_NUMBER);
     else {
-        if (i->unit != Value::Operator || i->iValue != ',')
+        if (i->unit != CSSParserValue::Operator || i->iValue != ',')
             return 0;
         
         i = args->next();
@@ -2546,8 +2553,9 @@ PassRefPtr<CSSValue> CSSParser::parseCounterContent(ValueList* args, bool counte
 
 bool CSSParser::parseShape(int propId, bool important)
 {
-    Value* value = m_valueList->current();
-    ValueList* args = value->function->args;
+    CSSParserValue* value = m_valueList->current();
+    CSSParserValueList* args = value->function->args;
+    
     if (!equalIgnoringCase(value->function->name, "rect(") || !args)
         return false;
 
@@ -2557,7 +2565,7 @@ bool CSSParser::parseShape(int propId, bool important)
     RefPtr<Rect> rect = Rect::create();
     bool valid = true;
     int i = 0;
-    Value *a = args->current();
+    CSSParserValue* a = args->current();
     while (a) {
         valid = a->id == CSSValueAuto || validUnit(a, FLength, m_strict);
         if (!valid)
@@ -2575,7 +2583,7 @@ bool CSSParser::parseShape(int propId, bool important)
             rect->setLeft(length);
         a = args->next();
         if (a && args->size() == 7) {
-            if (a->unit == Value::Operator && a->iValue == ',') {
+            if (a->unit == CSSParserValue::Operator && a->iValue == ',') {
                 a = args->next();
             } else {
                 valid = false;
@@ -2596,7 +2604,7 @@ bool CSSParser::parseShape(int propId, bool important)
 bool CSSParser::parseFont(bool important)
 {
     bool valid = true;
-    Value *value = m_valueList->current();
+    CSSParserValue *value = m_valueList->current();
     RefPtr<FontValue> font = FontValue::create();
     // optional font-style, font-variant and font-weight
     while (value) {
@@ -2673,7 +2681,7 @@ bool CSSParser::parseFont(bool important)
     if (!font->size || !value)
         return false;
 
-    if (value->unit == Value::Operator && value->iValue == '/') {
+    if (value->unit == CSSParserValue::Operator && value->iValue == '/') {
         // line-height
         value = m_valueList->next();
         if (!value)
@@ -2705,12 +2713,13 @@ bool CSSParser::parseFont(bool important)
 PassRefPtr<CSSValueList> CSSParser::parseFontFamily()
 {
     RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
-    Value* value = m_valueList->current();
+    CSSParserValue* value = m_valueList->current();
+
     FontFamilyValue* currFamily = 0;
     while (value) {
-        Value* nextValue = m_valueList->next();
+        CSSParserValue* nextValue = m_valueList->next();
         bool nextValBreaksFont = !nextValue ||
-                                 (nextValue->unit == Value::Operator && nextValue->iValue == ',');
+                                 (nextValue->unit == CSSParserValue::Operator && nextValue->iValue == ',');
         bool nextValIsFontName = nextValue &&
             ((nextValue->id >= CSSValueSerif && nextValue->id <= CSSValueWebkitBody) ||
             (nextValue->unit == CSSPrimitiveValue::CSS_STRING || nextValue->unit == CSSPrimitiveValue::CSS_IDENT));
@@ -2763,7 +2772,7 @@ PassRefPtr<CSSValueList> CSSParser::parseFontFamily()
 bool CSSParser::parseFontFaceSrc()
 {
     RefPtr<CSSValueList> values(CSSValueList::createCommaSeparated());
-    Value* val;
+    CSSParserValue* val;
     bool expectComma = false;
     bool allowFormat = false;
     bool failed = false;
@@ -2776,14 +2785,14 @@ bool CSSParser::parseFontFaceSrc()
             uriValue = parsedValue;
             allowFormat = true;
             expectComma = true;
-        } else if (val->unit == Value::Function) {
+        } else if (val->unit == CSSParserValue::Function) {
             // There are two allowed functions: local() and format().             
-            ValueList* args = val->function->args;
+            CSSParserValueList* args = val->function->args;
             if (args && args->size() == 1) {
                 if (equalIgnoringCase(val->function->name, "local(") && !expectComma) {
                     expectComma = true;
                     allowFormat = false;
-                    Value* a = args->current();
+                    CSSParserValue* a = args->current();
                     uriValue.clear();
                     parsedValue = CSSFontFaceSrcValue::createLocal(a->string);
                 } else if (equalIgnoringCase(val->function->name, "format(") && allowFormat && uriValue) {
@@ -2795,7 +2804,7 @@ bool CSSParser::parseFontFaceSrc()
                     continue;
                 }
             }
-        } else if (val->unit == Value::Operator && val->iValue == ',' && expectComma) {
+        } else if (val->unit == CSSParserValue::Operator && val->iValue == ',' && expectComma) {
             expectComma = false;
             allowFormat = false;
             uriValue.clear();
@@ -2824,7 +2833,7 @@ bool CSSParser::parseFontFaceSrc()
 bool CSSParser::parseFontFaceUnicodeRange()
 {
     RefPtr<CSSValueList> values = CSSValueList::createCommaSeparated();
-    Value* currentValue;
+    CSSParserValue* currentValue;
     bool failed = false;
     while ((currentValue = m_valueList->current())) {
         if (m_valueList->current()->unit != CSSPrimitiveValue::CSS_UNICODE_RANGE) {
@@ -2924,10 +2933,10 @@ bool CSSParser::parseColor(const String &name, RGBA32& rgb, bool strict)
     return false;
 }
 
-bool CSSParser::parseColorParameters(Value* value, int* colorArray, bool parseAlpha)
+bool CSSParser::parseColorParameters(CSSParserValue* value, int* colorArray, bool parseAlpha)
 {
-    ValueList* args = value->function->args;
-    Value* v = args->current();
+    CSSParserValueList* args = value->function->args;
+    CSSParserValue* v = args->current();
     Units unitType = FUnknown;
     // Get the first value and its type
     if (validUnit(v, FInteger, true))
@@ -2939,7 +2948,7 @@ bool CSSParser::parseColorParameters(Value* value, int* colorArray, bool parseAl
     colorArray[0] = static_cast<int>(v->fValue * (v->unit == CSSPrimitiveValue::CSS_PERCENTAGE ? 256.0 / 100.0 : 1.0));
     for (int i = 1; i < 3; i++) {
         v = args->next();
-        if (v->unit != Value::Operator && v->iValue != ',')
+        if (v->unit != CSSParserValue::Operator && v->iValue != ',')
             return false;
         v = args->next();
         if (!validUnit(v, unitType, true))
@@ -2948,7 +2957,7 @@ bool CSSParser::parseColorParameters(Value* value, int* colorArray, bool parseAl
     }
     if (parseAlpha) {
         v = args->next();
-        if (v->unit != Value::Operator && v->iValue != ',')
+        if (v->unit != CSSParserValue::Operator && v->iValue != ',')
             return false;
         v = args->next();
         if (!validUnit(v, FNumber, true))
@@ -2958,15 +2967,15 @@ bool CSSParser::parseColorParameters(Value* value, int* colorArray, bool parseAl
     return true;
 }
 
-// CSS3 sepcification defines the format of a HSL color as
+// The CSS3 specification defines the format of a HSL color as
 // hsl(<number>, <percent>, <percent>)
 // and with alpha, the format is
 // hsla(<number>, <percent>, <percent>, <number>)
 // The first value, HUE, is in an angle with a value between 0 and 360
-bool CSSParser::parseHSLParameters(Value* value, double* colorArray, bool parseAlpha)
+bool CSSParser::parseHSLParameters(CSSParserValue* value, double* colorArray, bool parseAlpha)
 {
-    ValueList* args = value->function->args;
-    Value* v = args->current();
+    CSSParserValueList* args = value->function->args;
+    CSSParserValue* v = args->current();
     // Get the first value
     if (!validUnit(v, FNumber, true))
         return false;
@@ -2974,7 +2983,7 @@ bool CSSParser::parseHSLParameters(Value* value, double* colorArray, bool parseA
     colorArray[0] = (((static_cast<int>(v->fValue) % 360) + 360) % 360) / 360.0;
     for (int i = 1; i < 3; i++) {
         v = args->next();
-        if (v->unit != Value::Operator && v->iValue != ',')
+        if (v->unit != CSSParserValue::Operator && v->iValue != ',')
             return false;
         v = args->next();
         if (!validUnit(v, FPercent, true))
@@ -2983,7 +2992,7 @@ bool CSSParser::parseHSLParameters(Value* value, double* colorArray, bool parseA
     }
     if (parseAlpha) {
         v = args->next();
-        if (v->unit != Value::Operator && v->iValue != ',')
+        if (v->unit != CSSParserValue::Operator && v->iValue != ',')
             return false;
         v = args->next();
         if (!validUnit(v, FNumber, true))
@@ -2993,7 +3002,7 @@ bool CSSParser::parseHSLParameters(Value* value, double* colorArray, bool parseA
     return true;
 }
 
-PassRefPtr<CSSPrimitiveValue> CSSParser::parseColor(Value* value)
+PassRefPtr<CSSPrimitiveValue> CSSParser::parseColor(CSSParserValue* value)
 {
     RGBA32 c = Color::transparent;
     if (!parseColorFromValue(value ? value : m_valueList->current(), c))
@@ -3001,7 +3010,7 @@ PassRefPtr<CSSPrimitiveValue> CSSParser::parseColor(Value* value)
     return CSSPrimitiveValue::createColor(c);
 }
 
-bool CSSParser::parseColorFromValue(Value* value, RGBA32& c, bool svg)
+bool CSSParser::parseColorFromValue(CSSParserValue* value, RGBA32& c, bool svg)
 {
     if (!m_strict && value->unit == CSSPrimitiveValue::CSS_NUMBER &&
         value->fValue >= 0. && value->fValue < 1000000.) {
@@ -3013,7 +3022,7 @@ bool CSSParser::parseColorFromValue(Value* value, RGBA32& c, bool svg)
                 (!m_strict && value->unit == CSSPrimitiveValue::CSS_DIMENSION)) {
         if (!CSSParser::parseColor(value->string, c, m_strict && value->unit == CSSPrimitiveValue::CSS_IDENT))
             return false;
-    } else if (value->unit == Value::Function &&
+    } else if (value->unit == CSSParserValue::Function &&
                 value->function->args != 0 &&
                 value->function->args->size() == 5 /* rgb + two commas */ &&
                 equalIgnoringCase(value->function->name, "rgb(")) {
@@ -3022,7 +3031,7 @@ bool CSSParser::parseColorFromValue(Value* value, RGBA32& c, bool svg)
             return false;
         c = makeRGB(colorValues[0], colorValues[1], colorValues[2]);
     } else if (!svg) {
-        if (value->unit == Value::Function &&
+        if (value->unit == CSSParserValue::Function &&
                 value->function->args != 0 &&
                 value->function->args->size() == 7 /* rgba + three commas */ &&
                 equalIgnoringCase(value->function->name, "rgba(")) {
@@ -3030,7 +3039,7 @@ bool CSSParser::parseColorFromValue(Value* value, RGBA32& c, bool svg)
             if (!parseColorParameters(value, colorValues, true))
                 return false;
             c = makeRGBA(colorValues[0], colorValues[1], colorValues[2], colorValues[3]);
-        } else if (value->unit == Value::Function &&
+        } else if (value->unit == CSSParserValue::Function &&
                     value->function->args != 0 &&
                     value->function->args->size() == 5 /* hsl + two commas */ &&
                     equalIgnoringCase(value->function->name, "hsl(")) {
@@ -3038,7 +3047,7 @@ bool CSSParser::parseColorFromValue(Value* value, RGBA32& c, bool svg)
             if (!parseHSLParameters(value, colorValues, false))
                 return false;
             c = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValues[2], 1.0);
-        } else if (value->unit == Value::Function &&
+        } else if (value->unit == CSSParserValue::Function &&
                     value->function->args != 0 &&
                     value->function->args->size() == 7 /* hsla + three commas */ &&
                     equalIgnoringCase(value->function->name, "hsla(")) {
@@ -3083,7 +3092,7 @@ struct ShadowParseContext {
         allowY = allowBlur = false;  
     }
 
-    void commitLength(Value* v) {
+    void commitLength(CSSParserValue* v) {
         RefPtr<CSSPrimitiveValue> val = CSSPrimitiveValue::create(v->fValue, (CSSPrimitiveValue::UnitTypes)v->unit);
 
         if (allowX) {
@@ -3125,10 +3134,10 @@ struct ShadowParseContext {
 bool CSSParser::parseShadow(int propId, bool important)
 {
     ShadowParseContext context;
-    Value* val;
+    CSSParserValue* val;
     while ((val = m_valueList->current())) {
         // Check for a comma break first.
-        if (val->unit == Value::Operator) {
+        if (val->unit == CSSParserValue::Operator) {
             if (val->iValue != ',' || !context.allowBreak)
                 // Other operators aren't legal or we aren't done with the current shadow
                 // value.  Treat as invalid.
@@ -3188,7 +3197,7 @@ bool CSSParser::parseReflect(int propId, bool important)
     // box-reflect: <direction> <offset> <mask>
     
     // Direction comes first.
-    Value* val = m_valueList->current();
+    CSSParserValue* val = m_valueList->current();
     CSSReflectionDirection direction;
     switch (val->id) {
         case CSSValueAbove:
@@ -3255,7 +3264,7 @@ struct BorderImageParseContext
     bool allowRule() const { return m_allowRule; }
 
     void commitImage(PassRefPtr<CSSValue> image) { m_image = image; m_allowNumber = true; }
-    void commitNumber(Value* v) {
+    void commitNumber(CSSParserValue* v) {
         PassRefPtr<CSSPrimitiveValue> val = CSSPrimitiveValue::create(v->fValue, (CSSPrimitiveValue::UnitTypes)v->unit);
         if (!m_top)
             m_top = val;
@@ -3272,7 +3281,7 @@ struct BorderImageParseContext
         m_allowNumber = !m_left;
     }
     void commitSlash() { m_allowBreak = m_allowSlash = m_allowNumber = false; m_allowWidth = true; }
-    void commitWidth(Value* val) {
+    void commitWidth(CSSParserValue* val) {
         if (!m_borderTop)
             m_borderTop = val;
         else if (!m_borderRight)
@@ -3326,7 +3335,7 @@ struct BorderImageParseContext
         // Now we have to deal with the border widths.  The best way to deal with these is to actually put these values into a value
         // list and then make our parsing machinery do the parsing.
         if (m_borderTop) {
-            ValueList newList;
+            CSSParserValueList newList;
             newList.addValue(*m_borderTop);
             if (m_borderRight)
                 newList.addValue(*m_borderRight);
@@ -3356,10 +3365,10 @@ struct BorderImageParseContext
     RefPtr<CSSPrimitiveValue> m_bottom;
     RefPtr<CSSPrimitiveValue> m_left;
     
-    Value* m_borderTop;
-    Value* m_borderRight;
-    Value* m_borderBottom;
-    Value* m_borderLeft;
+    CSSParserValue* m_borderTop;
+    CSSParserValue* m_borderRight;
+    CSSParserValue* m_borderBottom;
+    CSSParserValue* m_borderLeft;
     
     int m_horizontalRule;
     int m_verticalRule;
@@ -3369,13 +3378,13 @@ bool CSSParser::parseBorderImage(int propId, bool important, RefPtr<CSSValue>& r
 {
     // Look for an image initially.  If the first value is not a URI, then we're done.
     BorderImageParseContext context;
-    Value* val = m_valueList->current();
+    CSSParserValue* val = m_valueList->current();
     if (val->unit == CSSPrimitiveValue::CSS_URI) {        
         String uri = parseURL(val->string);
         if (uri.isNull())
             return false;
         context.commitImage(CSSImageValue::create(KURL(m_styleSheet->baseURL(), uri).string()));
-    } else if (val->unit == Value::Function) {
+    } else if (val->unit == CSSParserValue::Function) {
         RefPtr<CSSValue> value;
         if ((equalIgnoringCase(val->function->name, "-webkit-gradient(") && parseGradient(value)) ||
             (equalIgnoringCase(val->function->name, "-webkit-canvas(") && parseCanvas(value)))
@@ -3388,7 +3397,7 @@ bool CSSParser::parseBorderImage(int propId, bool important, RefPtr<CSSValue>& r
     while ((val = m_valueList->next())) {
         if (context.allowNumber() && validUnit(val, FInteger|FNonNeg|FPercent, true)) {
             context.commitNumber(val);
-        } else if (propId == CSSPropertyWebkitBorderImage && context.allowSlash() && val->unit == Value::Operator && val->iValue == '/') {
+        } else if (propId == CSSPropertyWebkitBorderImage && context.allowSlash() && val->unit == CSSParserValue::Operator && val->iValue == '/') {
             context.commitSlash();
         } else if (context.allowWidth() &&
             (val->id == CSSValueThin || val->id == CSSValueMedium || val->id == CSSValueThick || validUnit(val, FLength, m_strict))) {
@@ -3425,7 +3434,7 @@ bool CSSParser::parseCounter(int propId, int defaultValue, bool important)
     RefPtr<CSSPrimitiveValue> counterName;
     
     while (true) {
-        Value* val = m_valueList->current();
+        CSSParserValue* val = m_valueList->current();
         switch (state) {
             case ID:
                 if (val && val->unit == CSSPrimitiveValue::CSS_IDENT) {
@@ -3459,7 +3468,7 @@ bool CSSParser::parseCounter(int propId, int defaultValue, bool important)
     return false;
 }
 
-static PassRefPtr<CSSPrimitiveValue> parseGradientPoint(Value* a, bool horizontal)
+static PassRefPtr<CSSPrimitiveValue> parseGradientPoint(CSSParserValue* a, bool horizontal)
 {
     RefPtr<CSSPrimitiveValue> result;
     if (a->unit == CSSPrimitiveValue::CSS_IDENT) {
@@ -3476,9 +3485,9 @@ static PassRefPtr<CSSPrimitiveValue> parseGradientPoint(Value* a, bool horizonta
     return result;
 }
 
-bool parseGradientColorStop(CSSParser* p, Value* a, CSSGradientColorStop& stop)
+bool parseGradientColorStop(CSSParser* p, CSSParserValue* a, CSSGradientColorStop& stop)
 {
-    if (a->unit != Value::Function)
+    if (a->unit != CSSParserValue::Function)
         return false;
     
     if (!equalIgnoringCase(a->function->name, "from(") &&
@@ -3486,7 +3495,7 @@ bool parseGradientColorStop(CSSParser* p, Value* a, CSSGradientColorStop& stop)
         !equalIgnoringCase(a->function->name, "color-stop("))
         return false;
     
-    ValueList* args = a->function->args;
+    CSSParserValueList* args = a->function->args;
     if (!args)
         return false;
     
@@ -3515,7 +3524,7 @@ bool parseGradientColorStop(CSSParser* p, Value* a, CSSGradientColorStop& stop)
         if (args->size() != 3)
             return false;
         
-        Value* stopArg = args->current();
+        CSSParserValue* stopArg = args->current();
         if (stopArg->unit == CSSPrimitiveValue::CSS_PERCENTAGE)
             stop.m_stop = (float)stopArg->fValue / 100.f;
         else if (stopArg->unit == CSSPrimitiveValue::CSS_NUMBER)
@@ -3524,7 +3533,7 @@ bool parseGradientColorStop(CSSParser* p, Value* a, CSSGradientColorStop& stop)
             return false;
 
         stopArg = args->next();
-        if (stopArg->unit != Value::Operator || stopArg->iValue != ',')
+        if (stopArg->unit != CSSParserValue::Operator || stopArg->iValue != ',')
             return false;
             
         stopArg = args->next();
@@ -3545,12 +3554,12 @@ bool CSSParser::parseGradient(RefPtr<CSSValue>& gradient)
     RefPtr<CSSGradientValue> result = CSSGradientValue::create();
     
     // Walk the arguments.
-    ValueList* args = m_valueList->current()->function->args;
+    CSSParserValueList* args = m_valueList->current()->function->args;
     if (!args || args->size() == 0)
         return false;
     
     // The first argument is the gradient type.  It is an identifier.
-    Value* a = args->current();
+    CSSParserValue* a = args->current();
     if (!a || a->unit != CSSPrimitiveValue::CSS_IDENT)
         return false;
     if (equalIgnoringCase(a->string, "linear"))
@@ -3562,7 +3571,7 @@ bool CSSParser::parseGradient(RefPtr<CSSValue>& gradient)
     
     // Comma.
     a = args->next();
-    if (!a || a->unit != Value::Operator || a->iValue != ',')
+    if (!a || a->unit != CSSParserValue::Operator || a->iValue != ',')
         return false;
     
     // Next comes the starting point for the gradient as an x y pair.  There is no
@@ -3587,7 +3596,7 @@ bool CSSParser::parseGradient(RefPtr<CSSValue>& gradient)
     
     // Comma after the first point.
     a = args->next();
-    if (!a || a->unit != Value::Operator || a->iValue != ',')
+    if (!a || a->unit != CSSParserValue::Operator || a->iValue != ',')
         return false;
             
     // For radial gradients only, we now expect a numeric radius.
@@ -3599,7 +3608,7 @@ bool CSSParser::parseGradient(RefPtr<CSSValue>& gradient)
         
         // Comma after the first radius.
         a = args->next();
-        if (!a || a->unit != Value::Operator || a->iValue != ',')
+        if (!a || a->unit != CSSParserValue::Operator || a->iValue != ',')
             return false;
     }
     
@@ -3626,7 +3635,7 @@ bool CSSParser::parseGradient(RefPtr<CSSValue>& gradient)
     if (result->type() == CSSRadialGradient) {
         // Comma after the second point.
         a = args->next();
-        if (!a || a->unit != Value::Operator || a->iValue != ',')
+        if (!a || a->unit != CSSParserValue::Operator || a->iValue != ',')
             return false;
         
         a = args->next();
@@ -3639,7 +3648,7 @@ bool CSSParser::parseGradient(RefPtr<CSSValue>& gradient)
     a = args->next();
     while (a) {
         // Look for the comma before the next stop.
-        if (a->unit != Value::Operator || a->iValue != ',')
+        if (a->unit != CSSParserValue::Operator || a->iValue != ',')
             return false;
         
         // Now examine the stop itself.
@@ -3666,12 +3675,12 @@ bool CSSParser::parseCanvas(RefPtr<CSSValue>& canvas)
     RefPtr<CSSCanvasValue> result = CSSCanvasValue::create();
     
     // Walk the arguments.
-    ValueList* args = m_valueList->current()->function->args;
+    CSSParserValueList* args = m_valueList->current()->function->args;
     if (!args || args->size() != 1)
         return false;
     
     // The first argument is the canvas name.  It is an identifier.
-    Value* a = args->current();
+    CSSParserValue* a = args->current();
     if (!a || a->unit != CSSPrimitiveValue::CSS_IDENT)
         return false;
     result->setName(a->string);
@@ -3681,7 +3690,7 @@ bool CSSParser::parseCanvas(RefPtr<CSSValue>& canvas)
 
 class TransformOperationInfo {
 public:
-    TransformOperationInfo(const ParseString& name)
+    TransformOperationInfo(const CSSParserString& name)
     : m_type(CSSTransformValue::UnknownTransformOperation)
     , m_argCount(1)
     , m_allowSingleArgument(false)
@@ -3748,12 +3757,12 @@ PassRefPtr<CSSValueList> CSSParser::parseTransform()
     // The transform is a list of functional primitives that specify transform operations.
     // We collect a list of CSSTransformValues, where each value specifies a single operation.
     RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
-    for (Value* value = m_valueList->current(); value; value = m_valueList->next()) {
-        if (value->unit != Value::Function || !value->function)
+    for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
+        if (value->unit != CSSParserValue::Function || !value->function)
             return 0;
         
         // Every primitive requires at least one argument.
-        ValueList* args = value->function->args;
+        CSSParserValueList* args = value->function->args;
         if (!args)
             return 0;
         
@@ -3770,7 +3779,7 @@ PassRefPtr<CSSValueList> CSSParser::parseTransform()
         list->append(transformValue);
 
         // Snag our values.
-        Value* a = args->current();
+        CSSParserValue* a = args->current();
         unsigned argNumber = 0;
         while (a) {
             CSSParser::Units unit = info.unit();
@@ -3784,7 +3793,7 @@ PassRefPtr<CSSValueList> CSSParser::parseTransform()
             a = args->next();
             if (!a)
                 break;
-            if (a->unit != Value::Operator || a->iValue != ',')
+            if (a->unit != CSSParserValue::Operator || a->iValue != ',')
                 return 0;
             a = args->next();
             
@@ -3870,6 +3879,7 @@ int CSSParser::lex(void* yylvalWithoutType)
     case UNICODERANGE:
     case FUNCTION:
     case NOTFUNCTION:
+    case VARCALL:
         yylval->string.characters = t;
         yylval->string.length = length;
         break;
@@ -3966,6 +3976,23 @@ UChar* CSSParser::text(int *length)
         if (l && (start[l-1] == '\"' || start[l-1] == '\''))
              l--;
 
+        break;
+    case VARCALL:
+        // "-webkit-var("{w}{ident}{w}")"
+        // strip "-webkit-var(" and ")"
+        start += 12;
+        l -= 13;
+        // strip {w}
+        while (l &&
+                (*start == ' ' || *start == '\t' || *start == '\r' ||
+                 *start == '\n' || *start == '\f')) {
+            start++; l--;
+        }
+        while (l &&
+                (start[l-1] == ' ' || start[l-1] == '\t' || start[l-1] == '\r' ||
+                 start[l-1] == '\n' || start[l-1] == '\f')) {
+            l--;
+        }
     default:
         break;
     }
@@ -4066,14 +4093,14 @@ CSSSelector* CSSParser::sinkFloatingSelector(CSSSelector* selector)
     return selector;
 }
 
-ValueList* CSSParser::createFloatingValueList()
+CSSParserValueList* CSSParser::createFloatingValueList()
 {
-    ValueList* list = new ValueList;
+    CSSParserValueList* list = new CSSParserValueList;
     m_floatingValueLists.add(list);
     return list;
 }
 
-ValueList* CSSParser::sinkFloatingValueList(ValueList* list)
+CSSParserValueList* CSSParser::sinkFloatingValueList(CSSParserValueList* list)
 {
     if (list) {
         ASSERT(m_floatingValueLists.contains(list));
@@ -4082,14 +4109,14 @@ ValueList* CSSParser::sinkFloatingValueList(ValueList* list)
     return list;
 }
 
-Function* CSSParser::createFloatingFunction()
+CSSParserFunction* CSSParser::createFloatingFunction()
 {
-    Function* function = new Function;
+    CSSParserFunction* function = new CSSParserFunction;
     m_floatingFunctions.add(function);
     return function;
 }
 
-Function* CSSParser::sinkFloatingFunction(Function* function)
+CSSParserFunction* CSSParser::sinkFloatingFunction(CSSParserFunction* function)
 {
     if (function) {
         ASSERT(m_floatingFunctions.contains(function));
@@ -4098,16 +4125,16 @@ Function* CSSParser::sinkFloatingFunction(Function* function)
     return function;
 }
 
-Value& CSSParser::sinkFloatingValue(Value& value)
+CSSParserValue& CSSParser::sinkFloatingValue(CSSParserValue& value)
 {
-    if (value.unit == Value::Function) {
+    if (value.unit == CSSParserValue::Function) {
         ASSERT(m_floatingFunctions.contains(value.function));
         m_floatingFunctions.remove(value.function);
     }
     return value;
 }
 
-MediaQueryExp* CSSParser::createFloatingMediaQueryExp(const AtomicString& mediaFeature, ValueList* values)
+MediaQueryExp* CSSParser::createFloatingMediaQueryExp(const AtomicString& mediaFeature, CSSParserValueList* values)
 {
     delete m_floatingMediaQueryExp;
     m_floatingMediaQueryExp = new MediaQueryExp(mediaFeature, values);
@@ -4165,7 +4192,7 @@ MediaList* CSSParser::createMediaList()
     return result;
 }
 
-CSSRule* CSSParser::createCharsetRule(const ParseString& charset)
+CSSRule* CSSParser::createCharsetRule(const CSSParserString& charset)
 {
     if (!m_styleSheet)
         return 0;
@@ -4175,7 +4202,7 @@ CSSRule* CSSParser::createCharsetRule(const ParseString& charset)
     return result;
 }
 
-CSSRule* CSSParser::createImportRule(const ParseString& url, MediaList* media)
+CSSRule* CSSParser::createImportRule(const CSSParserString& url, MediaList* media)
 {
     if (!media || !m_styleSheet)
         return 0;
@@ -4228,6 +4255,90 @@ CSSRule* CSSParser::createFontFaceRule()
     return result;
 }
 
+CSSRule* CSSParser::createVariablesRule(MediaList* mediaList)
+{
+    CSSVariablesRule* rule = new CSSVariablesRule(m_styleSheet, mediaList);
+    m_parsedStyleObjects.append(rule);
+    rule->setDeclaration(CSSVariablesDeclaration::create(rule, m_variableNames, m_variableValues).get());
+    clearVariables();
+    return rule;
+}
+
+bool CSSParser::addVariable(const CSSParserString& name, CSSParserValue& value)
+{
+    m_variableNames.append(String(name));
+    m_variableValues.append(value.createCSSValue());
+    return true;
+}
+
+void CSSParser::clearVariables()
+{
+    m_variableNames.clear();
+    m_variableValues.clear();
+}
+
+bool CSSParser::parseVariable(CSSVariablesDeclaration* declaration, const String& variableName, const String& variableValue)
+{
+    m_styleSheet = static_cast<CSSStyleSheet*>(declaration->stylesheet());
+
+    String nameValuePair = variableName + ": ";
+    nameValuePair += variableValue;
+
+    setupParser("@-webkit-variables-decls{", nameValuePair, "} ");
+    cssyyparse(this);
+    m_rule = 0;
+
+    bool ok = false;
+    if (m_variableNames.size()) {
+        ok = true;
+        declaration->addParsedVariable(variableName, m_variableValues[0]);
+        clearVariables();
+    } else
+        clearVariables();
+
+    return ok;
+}
+
+void CSSParser::parsePropertyWithResolvedVariables(int propId, bool isImportant, CSSMutableStyleDeclaration* declaration, CSSParserValueList* list)
+{
+    m_valueList = list;
+    m_styleSheet = static_cast<CSSStyleSheet*>(declaration->stylesheet());
+
+    if (parseValue(propId, isImportant))
+        declaration->addParsedProperties(m_parsedProperties, m_numParsedProperties);
+        
+    clearProperties();
+    m_valueList = 0;
+}
+
+bool CSSParser::checkForVariables(CSSParserValueList* valueList)
+{
+    if (!valueList || !valueList->containsVariables())
+        return false;
+
+    bool hasVariables = false;
+    for (unsigned i = 0; i < valueList->size(); ++i) {
+        if (valueList->valueAt(i)->unit == CSSPrimitiveValue::CSS_PARSER_VARIABLE) {
+            hasVariables = true;
+            break;
+        } else if (valueList->valueAt(i)->unit == CSSParserValue::Function) {
+            if (checkForVariables(valueList->valueAt(i)->function->args)) {
+                hasVariables = true;
+                break;
+            }
+        }
+    }
+
+    return hasVariables;
+}
+
+void CSSParser::addUnresolvedProperty(int propId, bool important)
+{
+    RefPtr<CSSVariableDependentValue> val = CSSVariableDependentValue::create(CSSValueList::createFromParserValueList(m_valueList));
+    m_valueList = 0;
+    addProperty(propId, val.get(), important);
+}
+
 static int cssPropertyID(const UChar* propertyName, unsigned length)
 {
     if (!length)
@@ -4273,12 +4384,12 @@ int cssPropertyID(const String& string)
     return cssPropertyID(string.characters(), string.length());
 }
 
-int cssPropertyID(const ParseString& string)
+int cssPropertyID(const CSSParserString& string)
 {
     return cssPropertyID(string.characters, string.length);
 }
 
-int cssValueKeywordID(const ParseString& string)
+int cssValueKeywordID(const CSSParserString& string)
 {
     unsigned length = string.length;
     if (!length)
index 017cdd76da4d579dd5fc1b203be7a8ef95acae51..206cbe67f78f53846d776ccb7e60cc0f506894bf 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "AtomicString.h"
 #include "Color.h"
+#include "CSSParserValues.h"
 #include "MediaQuery.h"
 #include <wtf/HashSet.h>
 #include <wtf/Vector.h>
@@ -39,64 +40,12 @@ namespace WebCore {
     class CSSStyleSheet;
     class CSSValue;
     class CSSValueList;
+    class CSSVariablesDeclaration;
     class Document;
     class MediaList;
     class MediaQueryExp;
     class StyleBase;
     class StyleList;
-    struct Function;
-
-    struct ParseString {
-        UChar* characters;
-        int length;
-
-        void lower();
-
-        operator String() const { return String(characters, length); }
-        operator AtomicString() const { return AtomicString(characters, length); }
-    };
-
-    struct Value {
-        int id;
-        bool isInt;
-        union {
-            double fValue;
-            int iValue;
-            ParseString string;
-            Function* function;
-        };
-        enum {
-            Operator = 0x100000,
-            Function = 0x100001,
-            Q_EMS    = 0x100002
-        };
-        int unit;
-    };
-
-    class ValueList {
-    public:
-        ValueList() : m_current(0) { }
-        ~ValueList();
-
-        void addValue(const Value& v) { m_values.append(v); }
-        unsigned size() const { return m_values.size(); }
-        Value* current() { return m_current < m_values.size() ? &m_values[m_current] : 0; }
-        Value* next() { ++m_current; return current(); }
-
-        Value* valueAt(unsigned i) { return i < m_values.size() ? &m_values[i] : 0; }
-        void deleteValueAt(unsigned i) { m_values.remove(i); }
-
-    private:
-        Vector<Value, 16> m_values;
-        unsigned m_current;
-    };
-
-    struct Function {
-        ParseString name;
-        ValueList* args;
-
-        ~Function() { delete args; }
-    };
 
     class CSSParser {
     public:
@@ -138,7 +87,7 @@ namespace WebCore {
         PassRefPtr<CSSValue> parseTransitionDuration();
         PassRefPtr<CSSValue> parseTransitionRepeatCount();
         PassRefPtr<CSSValue> parseTransitionTimingFunction();
-        bool parseTimingFunctionValue(ValueList*& args, double& result);
+        bool parseTimingFunctionValue(CSSParserValueList*& args, double& result);
         PassRefPtr<CSSValue> parseTransitionProperty();
         bool parseTransitionProperty(int propId, RefPtr<CSSValue>&);
         bool parseTransitionShorthand(bool important);
@@ -151,12 +100,12 @@ namespace WebCore {
         PassRefPtr<CSSValueList> parseFontFamily();
 
         bool parseCounter(int propId, int defaultValue, bool important);
-        PassRefPtr<CSSValue> parseCounterContent(ValueList* args, bool counters);
+        PassRefPtr<CSSValue> parseCounterContent(CSSParserValueList* args, bool counters);
 
-        bool parseColorParameters(Value*, int* colorValues, bool parseAlpha);
-        bool parseHSLParameters(Value*, double* colorValues, bool parseAlpha);
-        PassRefPtr<CSSPrimitiveValue> parseColor(Value* = 0);
-        bool parseColorFromValue(Value*, RGBA32&, bool = false);
+        bool parseColorParameters(CSSParserValue*, int* colorValues, bool parseAlpha);
+        bool parseHSLParameters(CSSParserValue*, double* colorValues, bool parseAlpha);
+        PassRefPtr<CSSPrimitiveValue> parseColor(CSSParserValue* = 0);
+        bool parseColorFromValue(CSSParserValue*, RGBA32&, bool = false);
 
         static bool parseColor(const String&, RGBA32& rgb, bool strict);
 
@@ -182,29 +131,33 @@ namespace WebCore {
 
         PassRefPtr<CSSValueList> parseTransform();
         bool parseTransformOrigin(int propId, int& propId1, int& propId2, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
-        
+
+        bool parseVariable(CSSVariablesDeclaration*, const String& variableName, const String& variableValue);
+        void parsePropertyWithResolvedVariables(int propId, bool important, CSSMutableStyleDeclaration*, CSSParserValueList*);
+
         int yyparse();
 
         CSSSelector* createFloatingSelector();
         CSSSelector* sinkFloatingSelector(CSSSelector*);
 
-        ValueList* createFloatingValueList();
-        ValueList* sinkFloatingValueList(ValueList*);
+        CSSParserValueList* createFloatingValueList();
+        CSSParserValueList* sinkFloatingValueList(CSSParserValueList*);
 
-        Function* createFloatingFunction();
-        Function* sinkFloatingFunction(Function*);
+        CSSParserFunction* createFloatingFunction();
+        CSSParserFunction* sinkFloatingFunction(CSSParserFunction*);
 
-        Value& sinkFloatingValue(Value&);
+        CSSParserValue& sinkFloatingValue(CSSParserValue&);
 
         MediaList* createMediaList();
-        CSSRule* createCharsetRule(const ParseString&);
-        CSSRule* createImportRule(const ParseString&, MediaList*);
+        CSSRule* createCharsetRule(const CSSParserString&);
+        CSSRule* createImportRule(const CSSParserString&, MediaList*);
         CSSRule* createMediaRule(MediaList*, CSSRuleList*);
         CSSRuleList* createRuleList();
         CSSRule* createStyleRule(CSSSelector*);
         CSSRule* createFontFaceRule();
+        CSSRule* createVariablesRule(MediaList*);
 
-        MediaQueryExp* createFloatingMediaQueryExp(const AtomicString&, ValueList*);
+        MediaQueryExp* createFloatingMediaQueryExp(const AtomicString&, CSSParserValueList*);
         MediaQueryExp* sinkFloatingMediaQueryExp(MediaQueryExp*);
         Vector<MediaQueryExp*>* createFloatingMediaQueryExpList();
         Vector<MediaQueryExp*>* sinkFloatingMediaQueryExpList(Vector<MediaQueryExp*>*);
@@ -212,6 +165,10 @@ namespace WebCore {
         MediaQuery* createFloatingMediaQuery(Vector<MediaQueryExp*>*);
         MediaQuery* sinkFloatingMediaQuery(MediaQuery*);
 
+        bool addVariable(const CSSParserString&, CSSParserValue&);
+        bool checkForVariables(CSSParserValueList*);
+        void addUnresolvedProperty(int propId, bool important);
+        
     public:
         bool m_strict;
         bool m_important;
@@ -219,7 +176,7 @@ namespace WebCore {
         CSSStyleSheet* m_styleSheet;
         RefPtr<CSSRule> m_rule;
         MediaQuery* m_mediaQuery;
-        ValueList* m_valueList;
+        CSSParserValueList* m_valueList;
         CSSProperty** m_parsedProperties;
         int m_numParsedProperties;
         int m_maxParsedProperties;
@@ -228,6 +185,9 @@ namespace WebCore {
         int m_currentShorthand;
         bool m_implicitShorthand;
 
+        Vector<String> m_variableNames;
+        Vector<RefPtr<CSSValue> > m_variableValues;
+
         AtomicString m_defaultNamespace;
 
         // tokenizer methods and data
@@ -246,6 +206,8 @@ namespace WebCore {
 
         void checkForOrphanedUnits();
         
+        void clearVariables();
+
         UChar* m_data;
         UChar* yytext;
         UChar* yy_c_buf_p;
@@ -259,8 +221,8 @@ namespace WebCore {
         Vector<RefPtr<StyleBase> > m_parsedStyleObjects;
         Vector<RefPtr<CSSRuleList> > m_parsedRuleLists;
         HashSet<CSSSelector*> m_floatingSelectors;
-        HashSet<ValueList*> m_floatingValueLists;
-        HashSet<Function*> m_floatingFunctions;
+        HashSet<CSSParserValueList*> m_floatingValueLists;
+        HashSet<CSSParserFunction*> m_floatingFunctions;
 
         MediaQuery* m_floatingMediaQuery;
         MediaQueryExp* m_floatingMediaQueryExp;
@@ -285,14 +247,14 @@ namespace WebCore {
             return static_cast<Units>(static_cast<unsigned>(a) | static_cast<unsigned>(b));
         }
 
-        static bool validUnit(Value*, Units, bool strict);
+        static bool validUnit(CSSParserValue*, Units, bool strict);
         
         friend class TransformOperationInfo;
     };
 
-    int cssPropertyID(const ParseString&);
+    int cssPropertyID(const CSSParserString&);
     int cssPropertyID(const String&);
-    int cssValueKeywordID(const ParseString&);
+    int cssValueKeywordID(const CSSParserString&);
 
     class ShorthandScope {
     public:
diff --git a/WebCore/css/CSSParserValues.cpp b/WebCore/css/CSSParserValues.cpp
new file mode 100644 (file)
index 0000000..2199ac9
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "CSSParserValues.h"
+#include "CSSPrimitiveValue.h"
+#include "CSSFunctionValue.h"
+#include "CSSQuirkPrimitiveValue.h"
+
+namespace WebCore {
+
+CSSParserValueList::~CSSParserValueList()
+{
+    size_t numValues = m_values.size();
+    for (size_t i = 0; i < numValues; i++) {
+        if (m_values[i].unit == CSSParserValue::Function)
+            delete m_values[i].function;
+    }
+}
+
+void CSSParserValueList::addValue(const CSSParserValue& v)
+{
+    if (v.unit == CSSPrimitiveValue::CSS_PARSER_VARIABLE)
+        m_variablesCount++;
+    m_values.append(v);
+}
+    
+void CSSParserValueList::deleteValueAt(unsigned i)
+{ 
+    if (m_values[i].unit == CSSPrimitiveValue::CSS_PARSER_VARIABLE)
+        m_variablesCount--;
+    m_values.remove(i);
+}
+
+PassRefPtr<CSSValue> CSSParserValue::createCSSValue()
+{
+    RefPtr<CSSValue> parsedValue;
+    if (id)
+        parsedValue = CSSPrimitiveValue::createIdentifier(id);
+    else if (unit == CSSPrimitiveValue::CSS_NUMBER && isInt)
+        parsedValue = CSSPrimitiveValue::create(fValue, CSSPrimitiveValue::CSS_PARSER_INTEGER);
+    else if (unit == CSSParserValue::Operator) {
+        RefPtr<CSSPrimitiveValue> primitiveValue = CSSPrimitiveValue::createIdentifier(iValue);
+        primitiveValue->setPrimitiveType(CSSPrimitiveValue::CSS_PARSER_OPERATOR);
+        parsedValue = primitiveValue;
+    } else if (unit == CSSParserValue::Function)
+        parsedValue = CSSFunctionValue::create(function);
+    else if (unit == CSSPrimitiveValue::CSS_STRING || unit == CSSPrimitiveValue::CSS_URI || unit == CSSPrimitiveValue::CSS_PARSER_VARIABLE)
+        parsedValue = CSSPrimitiveValue::create(string, (CSSPrimitiveValue::UnitTypes)unit);
+    else if (unit >= CSSPrimitiveValue::CSS_NUMBER && unit <= CSSPrimitiveValue::CSS_KHZ)
+        parsedValue = CSSPrimitiveValue::create(fValue, (CSSPrimitiveValue::UnitTypes)unit);
+    else if (unit >= CSSParserValue::Q_EMS)
+        parsedValue = CSSQuirkPrimitiveValue::create(fValue, CSSPrimitiveValue::CSS_EMS);
+    return parsedValue;
+}
+
+}
+
diff --git a/WebCore/css/CSSParserValues.h b/WebCore/css/CSSParserValues.h
new file mode 100644 (file)
index 0000000..5324de6
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef CSSParserValues_h
+#define CSSParserValues_h
+
+#include "AtomicString.h"
+
+namespace WebCore {
+
+class CSSValue;
+
+struct CSSParserString {
+    UChar* characters;
+    int length;
+
+    void lower();
+
+    operator String() const { return String(characters, length); }
+    operator AtomicString() const { return AtomicString(characters, length); }
+};
+
+struct CSSParserFunction;
+
+struct CSSParserValue {
+    int id;
+    bool isInt;
+    union {
+        double fValue;
+        int iValue;
+        CSSParserString string;
+        CSSParserFunction* function;
+    };
+    enum {
+        Operator = 0x100000,
+        Function = 0x100001,
+        Q_EMS    = 0x100002
+    };
+    int unit;
+    
+    PassRefPtr<CSSValue> createCSSValue();
+};
+
+class CSSParserValueList {
+public:
+    CSSParserValueList()
+        : m_current(0)
+        , m_variablesCount(0)
+    {
+    }
+    ~CSSParserValueList();
+    
+    void addValue(const CSSParserValue&);
+    void deleteValueAt(unsigned);
+
+    unsigned size() const { return m_values.size(); }
+    CSSParserValue* current() { return m_current < m_values.size() ? &m_values[m_current] : 0; }
+    CSSParserValue* next() { ++m_current; return current(); }
+
+    CSSParserValue* valueAt(unsigned i) { return i < m_values.size() ? &m_values[i] : 0; }
+        
+    void clear() { m_values.clear(); }
+
+    bool containsVariables() const { return m_variablesCount; }
+
+private:
+    Vector<CSSParserValue, 16> m_values;
+    unsigned m_current;
+    unsigned m_variablesCount;
+};
+
+struct CSSParserFunction {
+    CSSParserString name;
+    CSSParserValueList* args;
+
+    ~CSSParserFunction() { delete args; }
+};
+
+}
+
+#endif
index 557ae7eef78bc78b8ed210ce022e70b8b0e0774c..3fc6c17dfb0d15aa08cf6867e663299ac61072e3 100644 (file)
@@ -510,6 +510,7 @@ String CSSPrimitiveValue::getStringValue(ExceptionCode& ec) const
         case CSS_STRING:
         case CSS_ATTR:
         case CSS_URI:
+        case CSS_PARSER_VARIABLE:
             return m_value.string;
         case CSS_IDENT:
             return valueOrPropertyName(m_value.ident);
@@ -527,6 +528,7 @@ String CSSPrimitiveValue::getStringValue() const
         case CSS_STRING:
         case CSS_ATTR:
         case CSS_URI:
+        case CSS_PARSER_VARIABLE:
             return m_value.string;
         case CSS_IDENT:
             return valueOrPropertyName(m_value.ident);
@@ -609,6 +611,7 @@ String CSSPrimitiveValue::cssText() const
             // FIXME
             break;
         case CSS_NUMBER:
+        case CSS_PARSER_INTEGER:
             text = String::number(m_value.num);
             break;
         case CSS_PERCENTAGE:
@@ -736,8 +739,81 @@ String CSSPrimitiveValue::cssText() const
             }
             break;
 #endif
+        case CSS_PARSER_VARIABLE:
+            text = "-webkit-var(";
+            text += m_value.string;
+            text += ")";
+            break;
+        case CSS_PARSER_OPERATOR:
+            char c = static_cast<char>(m_value.ident);
+            text = String(&c, 1U);
+            break;
     }
     return text;
 }
 
+CSSParserValue CSSPrimitiveValue::parserValue() const
+{
+    // We only have to handle a subset of types.
+    CSSParserValue value;
+    value.id = 0;
+    value.isInt = false;
+    value.unit = CSSPrimitiveValue::CSS_IDENT;
+    switch (m_type) {
+        case CSS_NUMBER:
+        case CSS_PERCENTAGE:
+        case CSS_EMS:
+        case CSS_EXS:
+        case CSS_PX:
+        case CSS_CM:
+        case CSS_MM:
+        case CSS_IN:
+        case CSS_PT:
+        case CSS_PC:
+        case CSS_DEG:
+        case CSS_RAD:
+        case CSS_GRAD:
+        case CSS_MS:
+        case CSS_S:
+        case CSS_HZ:
+        case CSS_KHZ:
+        case CSS_DIMENSION:
+            value.fValue = m_value.num;
+            value.unit = m_type;
+            break;
+        case CSS_STRING:
+        case CSS_URI:
+        case CSS_PARSER_VARIABLE:
+            value.string.characters = const_cast<UChar*>(m_value.string->characters());
+            value.string.length = m_value.string->length();
+            value.unit = m_type;
+            break;
+        case CSS_IDENT:
+            value.id = m_value.ident;
+            break;
+        case CSS_PARSER_OPERATOR:
+            value.iValue = m_value.ident;
+            value.unit = CSSParserValue::Operator;
+            break;
+        case CSS_PARSER_INTEGER:
+            value.fValue = m_value.num;
+            value.unit = CSSPrimitiveValue::CSS_NUMBER;
+            value.isInt = true;
+            break;
+        case CSS_UNKNOWN:
+        case CSS_ATTR:
+        case CSS_COUNTER:
+        case CSS_RECT:
+        case CSS_RGBCOLOR:
+        case CSS_PAIR:
+#if ENABLE(DASHBOARD_SUPPORT)
+        case CSS_DASHBOARD_REGION:
+#endif
+            ASSERT_NOT_REACHED();
+            break;
+    }
+    
+    return value;
+}
+
 } // namespace WebCore
index 9e4b0106a6598f80979b7072e4288ba5aae8c54a..661bd40a8e91f86ca29c37d586f9282e612cf41f 100644 (file)
@@ -67,7 +67,12 @@ public:
         CSS_RGBCOLOR = 25,
         CSS_PAIR = 100, // We envision this being exposed as a means of getting computed style values for pairs (border-spacing/radius, background-position, etc.)
         CSS_DASHBOARD_REGION = 101, // FIXME: Dashboard region should not be a primitive value.
-        CSS_UNICODE_RANGE = 102
+        CSS_UNICODE_RANGE = 102,
+        
+        // These next types are just used internally to allow us to translate back and forth from CSSPrimitiveValues to CSSParserValues.
+        CSS_PARSER_OPERATOR = 103,
+        CSS_PARSER_INTEGER = 104,
+        CSS_PARSER_VARIABLE = 105
     };
 
     static PassRefPtr<CSSPrimitiveValue> createIdentifier(int ident)
@@ -117,6 +122,9 @@ public:
     float computeLengthFloat(RenderStyle*, double multiplier, bool computingFontSize = false);
     double computeLengthDouble(RenderStyle*, double multiplier = 1.0, bool computingFontSize = false);
 
+    // use with care!!!
+    void setPrimitiveType(unsigned short type) { m_type = type; }
+    
     double getDoubleValue(unsigned short unitType, ExceptionCode&);
     double getDoubleValue(unsigned short unitType);
     double getDoubleValue() const { return m_value.num; }
@@ -156,6 +164,8 @@ public:
 
     virtual bool isQuirkValue() { return false; }
 
+    virtual CSSParserValue parserValue() const;
+
 protected:
     // FIXME: int vs. unsigned overloading is too subtle to distinguish the color and identifier cases.
     CSSPrimitiveValue(int ident);
index 3e3dbc2c7e586874941f8c34c978ac253d93a8a7..718220e3467d6c9e256407773f90d23198b5e64a 100644 (file)
@@ -38,7 +38,8 @@ public:
         IMPORT_RULE,
         MEDIA_RULE,
         FONT_FACE_RULE,
-        PAGE_RULE
+        PAGE_RULE,
+        VARIABLES_RULE
     };
 
     // FIXME: Change to return CSSRuleType.
index d36c05947e421464247f33c09961999ef26d9303..f5c78cc896d155cf45bd43335c9a980ec0ea7631 100644 (file)
@@ -36,6 +36,7 @@ module css {
         const unsigned short MEDIA_RULE = 4;
         const unsigned short FONT_FACE_RULE = 5;
         const unsigned short PAGE_RULE = 6;
+        const unsigned short VARIABLES_RULE = 7;
 
         readonly attribute unsigned short   type;
 
index ae0e124590873ecc29e31b918fdaf7f5f446df85..ac9e5d004eedded4a1cb801de9dc595e4a0d046f 100644 (file)
@@ -140,12 +140,16 @@ void CSSStyleDeclaration::diff(CSSMutableStyleDeclaration* style) const
 PassRefPtr<CSSMutableStyleDeclaration> CSSStyleDeclaration::copyPropertiesInSet(const int* set, unsigned length) const
 {
     DeprecatedValueList<CSSProperty> list;
+    unsigned variableDependentValueCount = 0;
     for (unsigned i = 0; i < length; i++) {
         RefPtr<CSSValue> value = getPropertyCSSValue(set[i]);
-        if (value)
+        if (value) {
             list.append(CSSProperty(set[i], value.release(), false));
+            if (value->isVariableDependentValue())
+                variableDependentValueCount++;
+        }
     }
-    return CSSMutableStyleDeclaration::create(list);
+    return CSSMutableStyleDeclaration::create(list, variableDependentValueCount);
 }
 
 } // namespace WebCore
index 614adb009592e32e611a04920b01555501a9ac07..573f25b485e61c576ef6cb09f5745530b8ef203c 100644 (file)
@@ -32,6 +32,7 @@
 #include "CSSFontFaceSource.h"
 #include "CSSImportRule.h"
 #include "CSSMediaRule.h"
+#include "CSSParser.h"
 #include "CSSPrimitiveValueMappings.h"
 #include "CSSProperty.h"
 #include "CSSPropertyNames.h"
@@ -43,6 +44,9 @@
 #include "CSSTimingFunctionValue.h"
 #include "CSSTransformValue.h"
 #include "CSSValueList.h"
+#include "CSSVariableDependentValue.h"
+#include "CSSVariablesDeclaration.h"
+#include "CSSVariablesRule.h"
 #include "CachedImage.h"
 #include "Counter.h"
 #include "FontFamilyValue.h"
@@ -418,6 +422,69 @@ static void loadDefaultStyle()
     defaultViewSourceStyle->addRulesFromSheet(parseUASheet(sourceUserAgentStyleSheet, sizeof(sourceUserAgentStyleSheet)), screenEval());
 }
 
+void CSSStyleSelector::addMatchedDeclaration(CSSMutableStyleDeclaration* decl)
+{
+    if (!decl->hasVariableDependentValue()) {
+        m_matchedDecls.append(decl);
+        return;
+    }
+
+    // See if we have already resolved the variables in this declaration.
+    RefPtr<CSSMutableStyleDeclaration> resolvedDecl = m_resolvedVariablesDeclarations.get(decl);
+    if (resolvedDecl) {
+        m_matchedDecls.append(resolvedDecl.get());
+        return;
+    }
+
+    // If this declaration has any variables in it, then we need to make a cloned
+    // declaration with as many variables resolved as possible for this style selector's media.
+    RefPtr<CSSMutableStyleDeclaration> newDecl = CSSMutableStyleDeclaration::create(decl->parentRule());
+    *newDecl = *decl;
+    m_matchedDecls.append(newDecl.get());
+    m_resolvedVariablesDeclarations.set(decl, newDecl);
+
+    // Now iterate over the properties in the original declaration.  As we resolve variables we'll end up
+    // mutating the new declaration (possibly expanding shorthands).  The new declaration has no m_node
+    // though, so it can't mistakenly call setChanged on anything.
+    DeprecatedValueListConstIterator<CSSProperty> end;
+    for (DeprecatedValueListConstIterator<CSSProperty> it = decl->valuesIterator(); it != end; ++it) {
+        const CSSProperty& current = *it;
+        if (!current.value()->isVariableDependentValue())
+            continue;
+        CSSValueList* valueList = static_cast<CSSVariableDependentValue*>(current.value())->valueList();
+        if (!valueList)
+            continue;
+        CSSParserValueList resolvedValueList;
+        unsigned s = valueList->length();
+        bool fullyResolved = true;
+        for (unsigned i = 0; i < s; ++i) {
+            CSSValue* val = valueList->item(i);
+            CSSPrimitiveValue* primitiveValue = val->isPrimitiveValue() ? static_cast<CSSPrimitiveValue*>(val) : 0;
+            if (primitiveValue && primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_PARSER_VARIABLE) {
+                CSSVariablesRule* rule = m_variablesMap.get(primitiveValue->getStringValue());
+                if (!rule || !rule->variables()) {
+                    fullyResolved = false;
+                    break;
+                }
+                CSSValue* resolvedVariable = rule->variables()->getParsedVariable(primitiveValue->getStringValue());
+                if (!resolvedVariable) {
+                    fullyResolved = false;
+                    break;
+                }
+                resolvedValueList.addValue(resolvedVariable->parserValue());
+            } else
+                resolvedValueList.addValue(val->parserValue());
+        }
+        
+        if (!fullyResolved)
+            continue;
+
+        // We now have a fully resolved new value list.  We want the parser to use this value list
+        // and parse our new declaration.
+        CSSParser(m_checker.m_strictParsing).parsePropertyWithResolvedVariables(current.id(), current.isImportant(), newDecl.get(), &resolvedValueList);
+    }
+}
+
 void CSSStyleSelector::matchRules(CSSRuleSet* rules, int& firstRuleIndex, int& lastRuleIndex)
 {
     m_matchedRules.clear();
@@ -2118,6 +2185,23 @@ bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Eleme
     return true;
 }
 
+void CSSStyleSelector::addVariables(CSSVariablesRule* variables)
+{
+    CSSVariablesDeclaration* decl = variables->variables();
+    if (!decl)
+        return;
+    unsigned size = decl->length();
+    for (unsigned i = 0; i < size; ++i) {
+        String name = decl->item(i);
+        m_variablesMap.set(name, variables);
+    }
+}
+
+CSSValue* CSSStyleSelector::resolveVariableDependentValue(CSSVariableDependentValue* val)
+{
+    return 0;
+}
+
 // -----------------------------------------------------------------
 
 CSSRuleSet::CSSRuleSet()
@@ -2220,6 +2304,11 @@ void CSSRuleSet::addRulesFromSheet(CSSStyleSheet* sheet, const MediaQueryEvaluat
             // Add this font face to our set.
             const CSSFontFaceRule* fontFaceRule = static_cast<CSSFontFaceRule*>(item);
             styleSelector->fontSelector()->addFontFaceRule(fontFaceRule);
+        } else if (item->isVariablesRule()) {
+            // Evaluate the media query and make sure it matches.
+            CSSVariablesRule* variables = static_cast<CSSVariablesRule*>(item);
+            if (!variables->media() || medium.eval(variables->media(), styleSelector))
+                styleSelector->addVariables(variables);
         }
     }
 }
@@ -2250,7 +2339,9 @@ static Length convertToLength(CSSPrimitiveValue *primitiveValue, RenderStyle *st
 void CSSStyleSelector::applyDeclarations(bool applyFirst, bool isImportant,
                                          int startIndex, int endIndex)
 {
-    if (startIndex == -1) return;
+    if (startIndex == -1)
+        return;
+
     for (int i = startIndex; i <= endIndex; i++) {
         CSSMutableStyleDeclaration* decl = m_matchedDecls[i];
         DeprecatedValueListConstIterator<CSSProperty> end;
index 7de53a6e4718df73e8e0ee97a711ece31037f167..00b9e68d41cf0827b0dce27755e9c32864d14a7b 100644 (file)
@@ -46,6 +46,8 @@ class CSSSelector;
 class CSSStyleRule;
 class CSSStyleSheet;
 class CSSValue;
+class CSSVariableDependentValue;
+class CSSVariablesRule;
 class Document;
 class Element;
 class Frame;
@@ -128,6 +130,9 @@ public:
 
         void allVisitedStateChanged() { m_checker.allVisitedStateChanged(); }
         void visitedStateChanged(unsigned visitedHash) { m_checker.visitedStateChanged(visitedHash); }
+        
+        void addVariables(CSSVariablesRule* variables);
+        CSSValue* resolveVariableDependentValue(CSSVariableDependentValue*);
 
     private:
         enum SelectorMatch { SelectorMatches, SelectorFailsLocally, SelectorFailsCompletely };
@@ -140,14 +145,14 @@ public:
         void adjustRenderStyle(RenderStyle*, Element*);
 
         void addMatchedRule(CSSRuleData* rule) { m_matchedRules.append(rule); }
-        void addMatchedDeclaration(CSSMutableStyleDeclaration* decl) { m_matchedDecls.append(decl); }
+        void addMatchedDeclaration(CSSMutableStyleDeclaration* decl);
 
         void matchRules(CSSRuleSet*, int& firstRuleIndex, int& lastRuleIndex);
         void matchRulesForList(CSSRuleDataList*, int& firstRuleIndex, int& lastRuleIndex);
         void sortMatchedRules(unsigned start, unsigned end);
 
         void applyDeclarations(bool firstPass, bool important, int startIndex, int endIndex);
-
+        
         CSSRuleSet* m_authorStyle;
         CSSRuleSet* m_userStyle;
         RefPtr<CSSStyleSheet> m_userSheet;
@@ -245,6 +250,9 @@ public:
         HashSet<AtomicStringImpl*> m_selectorAttrs;
         Vector<CSSMutableStyleDeclaration*> m_additionalAttributeStyleDecls;
         Vector<MediaQueryResult*> m_viewportDependentMediaQueryResults;
+        
+        HashMap<String, CSSVariablesRule*> m_variablesMap;
+        HashMap<CSSMutableStyleDeclaration*, RefPtr<CSSMutableStyleDeclaration> > m_resolvedVariablesDeclarations;
     };
 
     class CSSRuleData {
index f891845c502cb3bb580c187eadec12431d61ee04..bf5c361f40bd68abe8313669ef20db4be784c875 100644 (file)
@@ -23,6 +23,9 @@
 
 #include "StyleBase.h"
 
+#include "CSSParserValues.h"
+#include <wtf/RefPtr.h>
+
 namespace WebCore {
 
 typedef int ExceptionCode;
@@ -57,6 +60,9 @@ public:
     virtual bool isSVGPaint() const { return false; }
 #endif
 
+    virtual bool isVariableDependentValue() const { return false; }
+    virtual CSSParserValue parserValue() const { ASSERT_NOT_REACHED(); return CSSParserValue(); }
+
 protected:
     CSSValue() : StyleBase(0) { }
 };
index 628e988890d21316a22fc509f0688d1a1b96f4f5..522ee7055505a79a00c7e8e6677c2256b70eaf2e 100644 (file)
@@ -22,6 +22,7 @@
 #include "config.h"
 #include "CSSValueList.h"
 
+#include "CSSParserValues.h"
 #include "PlatformString.h"
 
 namespace WebCore {
@@ -31,6 +32,18 @@ CSSValueList::CSSValueList(bool isSpaceSeparated)
 {
 }
 
+CSSValueList::CSSValueList(CSSParserValueList* list)
+    : m_isSpaceSeparated(true)
+{
+    if (list) {
+        unsigned s = list->size();
+        for (unsigned i = 0; i < s; ++i) {
+            CSSParserValue* v = list->valueAt(i);
+            append(v->createCSSValue());
+        }
+    }
+}
+
 CSSValueList::~CSSValueList()
 {
 }
@@ -75,4 +88,15 @@ String CSSValueList::cssText() const
     return result;
 }
 
+CSSParserValueList* CSSValueList::createParserValueList() const
+{
+    unsigned s = m_values.size();
+    if (!s)
+        return 0;
+    CSSParserValueList* result = new CSSParserValueList;
+    for (unsigned i = 0; i < s; ++i)
+        result->addValue(m_values[i]->parserValue());
+    return result;
+}
+
 } // namespace WebCore
index b61aa6a7f0c46a53cf306bbb7229bed5f8c5e8f6..6268e985a44f29e98e6d72e47692bddad6f167c0 100644 (file)
@@ -27,6 +27,8 @@
 
 namespace WebCore {
 
+class CSSParserValueList;
+
 class CSSValueList : public CSSValue {
 public:
     static PassRefPtr<CSSValueList> createCommaSeparated()
@@ -37,6 +39,10 @@ public:
     {
         return adoptRef(new CSSValueList(true));
     }
+    static PassRefPtr<CSSValueList> createFromParserValueList(CSSParserValueList* list)
+    {
+        return adoptRef(new CSSValueList(list));
+    }
 
     virtual ~CSSValueList();
 
@@ -49,9 +55,12 @@ public:
 
     virtual String cssText() const;
 
+    CSSParserValueList* createParserValueList() const;
+
 private:
     CSSValueList(bool isSpaceSeparated);
-
+    CSSValueList(CSSParserValueList*);
+    
     virtual bool isValueList() { return true; }
 
     virtual unsigned short cssValueType() const;
diff --git a/WebCore/css/CSSVariableDependentValue.cpp b/WebCore/css/CSSVariableDependentValue.cpp
new file mode 100644 (file)
index 0000000..42d6022
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "CSSVariableDependentValue.h"
+
+#include "CSSValueList.h"
+
+namespace WebCore {
+
+CSSVariableDependentValue::CSSVariableDependentValue(const PassRefPtr<CSSValueList>& list)
+: m_list(list)
+{
+}
+
+CSSVariableDependentValue::~CSSVariableDependentValue()
+{
+}
+
+String CSSVariableDependentValue::cssText() const
+{
+    if (m_list)
+        return m_list->cssText();
+    return "";
+}
+
+}
diff --git a/WebCore/css/CSSVariableDependentValue.h b/WebCore/css/CSSVariableDependentValue.h
new file mode 100644 (file)
index 0000000..8b29a81
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef CSSVariableDependentValue_h
+#define CSSVariableDependentValue_h
+
+#include "CSSValue.h"
+
+namespace WebCore {
+
+class CSSValueList;
+
+class CSSVariableDependentValue : public CSSValue {
+public:
+    static PassRefPtr<CSSVariableDependentValue> create(const PassRefPtr<CSSValueList>& valueList)
+    {
+        return adoptRef(new CSSVariableDependentValue(valueList));
+    }
+    ~CSSVariableDependentValue();
+    
+    virtual String cssText() const;
+
+    bool isVariableDependentValue() const { return true; }
+
+    CSSValueList* valueList() const { return m_list.get(); }
+
+private:
+    CSSVariableDependentValue(const PassRefPtr<CSSValueList>&);
+    
+    RefPtr<CSSValueList> m_list;
+};
+
+}
+#endif
+
diff --git a/WebCore/css/CSSVariablesDeclaration.cpp b/WebCore/css/CSSVariablesDeclaration.cpp
new file mode 100644 (file)
index 0000000..86187a0
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "CSSVariablesDeclaration.h"
+
+#include "CSSParser.h"
+#include "CSSRule.h"
+#include "CSSValue.h"
+#include "ExceptionCode.h"
+
+namespace WebCore {
+
+CSSVariablesDeclaration::CSSVariablesDeclaration(StyleBase* parent, const Vector<String>& names, const Vector<RefPtr<CSSValue> >& values)
+    : StyleBase(parent)
+{
+    m_variableNames = names;
+    ASSERT(names.size() == values.size());
+    unsigned s = names.size();
+    for (unsigned i = 0; i < s; ++i)
+        addParsedVariable(names[i], values[i], false);
+}
+
+CSSVariablesDeclaration::~CSSVariablesDeclaration()
+{
+}
+
+String CSSVariablesDeclaration::getVariableValue(const String& variableName)
+{
+    CSSValue* val = getParsedVariable(variableName);
+    if (val)
+        return val->cssText();
+    return "";
+}
+
+String CSSVariablesDeclaration::removeVariable(const String& variableName, ExceptionCode&)
+{
+    // FIXME: The spec has this method taking an exception code but no exceptions are
+    // specified as being thrown.
+    RefPtr<CSSValue> val = m_variablesMap.take(variableName);
+    String result = val ? val->cssText() : "";
+    if (val) {
+        int s = m_variableNames.size();
+        for (int i = 0; i < s; ++i) {
+            if (m_variableNames[i] == variableName) {
+                m_variableNames.remove(i);
+                i--;
+                s--;
+            }
+        }
+    }
+    
+    // FIXME: Communicate this change so that the document will update.
+    return result;
+}
+
+void CSSVariablesDeclaration::setVariable(const String& variableName, const String& variableValue, ExceptionCode& excCode)
+{
+    // Try to parse the variable value into a Value*.  If it fails we throw an exception.
+    CSSParser parser(useStrictParsing());
+    if (!parser.parseVariable(this, variableName, variableValue)) // If the parse succeeds, it will call addParsedVariable (our internal method for doing the add) with the parsed Value*.
+        excCode = SYNTAX_ERR;
+}
+
+void CSSVariablesDeclaration::addParsedVariable(const String& variableName, PassRefPtr<CSSValue> variableValue, bool updateNamesList)
+{
+    // Don't leak duplicates.  For multiple variables with the same name, the last one
+    // declared will win.
+    CSSValue* current = m_variablesMap.take(variableName).get();
+    if (!current && updateNamesList)
+        m_variableNames.append(variableName);
+    m_variablesMap.set(variableName, variableValue);
+    
+    // FIXME: Communicate this change so the document will update.
+}
+
+CSSValue* CSSVariablesDeclaration::getParsedVariable(const String& variableName)
+{
+    return m_variablesMap.get(variableName).get();
+}
+
+unsigned CSSVariablesDeclaration::length() const
+{
+    return m_variableNames.size();
+}
+
+const String& CSSVariablesDeclaration::item(unsigned index)
+{
+    return m_variableNames[index];
+}
+
+CSSRule* CSSVariablesDeclaration::parentRule()
+{
+    return (parent() && parent()->isRule()) ? static_cast<CSSRule*>(parent()) : 0;
+}
+
+String CSSVariablesDeclaration::cssText() const
+{
+    String result = "{ ";
+    unsigned s = m_variableNames.size();
+    for (unsigned i = 0; i < s; ++i) {
+        result += m_variableNames[i] + ": ";
+        result += m_variablesMap.get(m_variableNames[i])->cssText();
+        if (i < s - 1)
+            result += "; ";
+    }
+    result += " }";
+    return result;
+}
+
+}
diff --git a/WebCore/css/CSSVariablesDeclaration.h b/WebCore/css/CSSVariablesDeclaration.h
new file mode 100644 (file)
index 0000000..7207c4d
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef CSSVariablesDeclaration_h
+#define CSSVariablesDeclaration_h
+
+#include "PlatformString.h"
+#include "StringHash.h"
+#include "StyleBase.h"
+#include <wtf/HashMap.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+typedef int ExceptionCode;
+
+class CSSRule;
+class CSSValue;
+
+class CSSVariablesDeclaration : public StyleBase {
+public:
+    static PassRefPtr<CSSVariablesDeclaration> create(StyleBase* owningRule, const Vector<String>& names, const Vector<RefPtr<CSSValue> >& values)
+    {
+        return adoptRef(new CSSVariablesDeclaration(owningRule, names, values));
+    }
+    virtual ~CSSVariablesDeclaration();
+
+    String getVariableValue(const String&);
+    String removeVariable(const String&, ExceptionCode&);
+    void setVariable(const String&, const String&, ExceptionCode&);
+
+    unsigned length() const;
+    const String& item(unsigned index);
+
+    CSSRule* parentRule();
+
+    String cssText() const; // FIXME: The spec contradicts itself regarding whether or not cssText is settable.
+
+    void addParsedVariable(const String& variableName, PassRefPtr<CSSValue> variableValue, bool updateNamesList = true);
+    CSSValue* getParsedVariable(const String& variableName);
+
+private:
+    CSSVariablesDeclaration(StyleBase* owningRule, const Vector<String>& names, const Vector<RefPtr<CSSValue> >& values);
+
+protected:
+    Vector<String> m_variableNames;
+    HashMap<String, RefPtr<CSSValue> > m_variablesMap;
+};
+
+} // namespace WebCore
+
+#endif // CSSVariablesDeclaration_h
diff --git a/WebCore/css/CSSVariablesRule.cpp b/WebCore/css/CSSVariablesRule.cpp
new file mode 100644 (file)
index 0000000..e20b01c
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "CSSVariablesRule.h"
+
+#include "CSSVariablesDeclaration.h"
+#include "MediaList.h"
+#include "PlatformString.h"
+#include <wtf/HashMap.h>
+
+namespace WebCore {
+
+CSSVariablesRule::CSSVariablesRule(CSSStyleSheet* parent, MediaList* mediaList)
+    : CSSRule(parent)
+{
+    m_lstMedia = mediaList;
+}
+
+CSSVariablesRule::~CSSVariablesRule()
+{
+}
+
+String CSSVariablesRule::cssText() const
+{
+    String result = "@-webkit-variables ";
+    if (m_lstMedia) {
+        result += m_lstMedia->mediaText();
+        result += " ";
+    }
+    if (m_variables)
+        result += m_variables->cssText();
+    result += ";";
+    return result;
+}
+
+}
diff --git a/WebCore/css/CSSVariablesRule.h b/WebCore/css/CSSVariablesRule.h
new file mode 100644 (file)
index 0000000..3dd31d3
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef CSSVariablesRule_h
+#define CSSVariablesRule_h
+
+#include "CSSRule.h"
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class CSSStyleSheet;
+class CSSVariablesDeclaration;
+class MediaList;
+
+class CSSVariablesRule : public CSSRule {
+public:
+    CSSVariablesRule(CSSStyleSheet* parent, MediaList*);
+    virtual ~CSSVariablesRule();
+
+    // CSSVariablesRule interface
+    MediaList* media() const { return m_lstMedia.get(); }
+    CSSVariablesDeclaration* variables() { return m_variables.get(); }
+
+    // Inherited from CSSRule
+    virtual unsigned short type() const { return VARIABLES_RULE; }
+    virtual String cssText() const;
+    virtual bool isVariablesRule() { return true; }
+
+    // Used internally.  Does not notify the document of the change.  Only intended
+    // for use on initial parse.
+    void setDeclaration(CSSVariablesDeclaration* decl) { m_variables = decl; }
+
+protected:
+    RefPtr<MediaList> m_lstMedia;
+    RefPtr<CSSVariablesDeclaration> m_variables;
+};
+
+} // namespace WebCore
+
+#endif // CSSVariablesRule_h
index 54340b8ea9a31535f8d3b8a2def6a6c78875e393..7ba6d8440ffb4e9eb7fb9e79e33bfd12a625ce43 100644 (file)
 
 namespace WebCore {
 
-MediaQueryExp::MediaQueryExp(const AtomicString& mediaFeature, ValueList* valueList)
+MediaQueryExp::MediaQueryExp(const AtomicString& mediaFeature, CSSParserValueList* valueList)
     : m_mediaFeature(mediaFeature)
     , m_value(0)
 {
     if (valueList) {
         if (valueList->size() == 1) {
-            Value* value = valueList->current();
+            CSSParserValue* value = valueList->current();
 
             if (value->id != 0)
                 m_value = CSSPrimitiveValue::createIdentifier(value->id);
@@ -56,11 +56,11 @@ MediaQueryExp::MediaQueryExp(const AtomicString& mediaFeature, ValueList* valueL
             // currently accepts only <integer>/<integer>
 
             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
-            Value* value = 0;
+            CSSParserValue* value = 0;
             bool isValid = true;
 
             while ((value = valueList->current()) && isValid) {
-                if (value->unit == Value::Operator && value->iValue == '/')
+                if (value->unit == CSSParserValue::Operator && value->iValue == '/')
                     list->append(CSSPrimitiveValue::create("/", CSSPrimitiveValue::CSS_STRING));
                 else if (value->unit == CSSPrimitiveValue::CSS_NUMBER)
                     list->append(CSSPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_NUMBER));
index 14cb123db92ed4f6920848e07b4c726e7cdf7955..daae2324ea9b47c8802e104ce3b4c939025a5b6a 100644 (file)
 #include <wtf/RefPtr.h>
 
 namespace WebCore {
-class ValueList;
+class CSSParserValueList;
 
 class MediaQueryExp
 {
 public:
-    MediaQueryExp(const AtomicString& mediaFeature, ValueList* values);
+    MediaQueryExp(const AtomicString& mediaFeature, CSSParserValueList* values);
     ~MediaQueryExp();
 
     AtomicString mediaFeature() const { return m_mediaFeature; }
index 4dffea8ee13be70c4b6577e57dd17328578add3a..fcc839122e94a42b8d8a949055c3b577cdef78f0 100644 (file)
@@ -39,7 +39,7 @@ namespace WebCore {
 
 bool CSSParser::parseSVGValue(int propId, bool important)
 {
-    Value* value = m_valueList->current();
+    CSSParserValue* value = m_valueList->current();
     if (!value)
         return false;
 
@@ -303,7 +303,7 @@ bool CSSParser::parseSVGValue(int propId, bool important)
             parsedValue = CSSPrimitiveValue::create(value->string, (CSSPrimitiveValue::UnitTypes) value->unit);
         else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
             parsedValue = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
-        else if (value->unit >= Value::Q_EMS)
+        else if (value->unit >= CSSParserValue::Q_EMS)
             parsedValue = CSSQuirkPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_EMS);
         m_valueList->next();
     }
@@ -317,7 +317,7 @@ bool CSSParser::parseSVGValue(int propId, bool important)
 PassRefPtr<CSSValue> CSSParser::parseSVGStrokeDasharray()
 {
     RefPtr<CSSValueList> ret = CSSValueList::createCommaSeparated();
-    Value* value = m_valueList->current();
+    CSSParserValue* value = m_valueList->current();
     bool valid_primitive = true;
     while (value) {
         valid_primitive = validUnit(value, FLength | FPercent |FNonNeg, false);
@@ -328,7 +328,7 @@ PassRefPtr<CSSValue> CSSParser::parseSVGStrokeDasharray()
         else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
             ret->append(CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit));
         value = m_valueList->next();
-        if (value && value->unit == Value::Operator && value->iValue == ',')
+        if (value && value->unit == CSSParserValue::Operator && value->iValue == ',')
             value = m_valueList->next();
     }
     if (!valid_primitive)
index b012c3243ba011d6ed50b2ef5713ba5860aadcb9..1f13b53a2a57761e06bbb15a457119a9ffb5ff25 100644 (file)
@@ -51,6 +51,8 @@ namespace WebCore {
         virtual bool isFontFaceRule() { return false; }
         virtual bool isImportRule() { return false; }
         virtual bool isMediaRule() { return false; }
+        virtual bool isVariablesRule() { return false; }
+        
         virtual bool isRule() { return false; }
         virtual bool isStyleRule() { return false; }
         virtual bool isStyleSheet() const { return false; }
index 214b5bf4387c2c0457130aa47cc383b9b6d7f5ab..e439fd4a35ca01844ade83e1d714c3ba53930e51 100644 (file)
@@ -59,6 +59,8 @@ nth             (-?[0-9]*n[\+-][0-9]+)|(-?[0-9]*n)
 "@-webkit-decls"        {yyTok = WEBKIT_DECLS_SYM; return yyTok; }
 "@-webkit-value"        {yyTok = WEBKIT_VALUE_SYM; return yyTok; }
 "@-webkit-mediaquery"   {BEGIN(mediaquery); yyTok = WEBKIT_MEDIAQUERY_SYM; return yyTok; }
+"@-webkit-variables"    {yyTok = WEBKIT_VARIABLES_SYM; return yyTok; }
+"@-webkit-variables-decls" { yyTok = WEBKIT_VARIABLES_DECLS_SYM; return yyTok; }
 
 "!"{w}"important"       {yyTok = IMPORTANT_SYM; return yyTok;}
 
@@ -86,6 +88,7 @@ nth             (-?[0-9]*n[\+-][0-9]+)|(-?[0-9]*n)
 "not("                  {yyTok = NOTFUNCTION; return yyTok;}
 "url("{w}{string}{w}")" {yyTok = URI; return yyTok;}
 "url("{w}{url}{w}")"    {yyTok = URI; return yyTok;}
+"-webkit-var("{w}{ident}{w}")" { yyTok = VARCALL; return yyTok; }
 {ident}"("              {yyTok = FUNCTION; return yyTok;}
 
 U\+{range}              {yyTok = UNICODERANGE; return yyTok;}