CSS calc parsing stage
authormikelawther@chromium.org <mikelawther@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 28 Jan 2012 00:05:00 +0000 (00:05 +0000)
committermikelawther@chromium.org <mikelawther@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 28 Jan 2012 00:05:00 +0000 (00:05 +0000)
https://bugs.webkit.org/show_bug.cgi?id=57082

This is the parsing stage of calc. The expressions are evaluated and
expression trees are generated. CSS values are not created yet - that
will happen in a subsequent commit.

Reviewed by David Hyatt.

No functional change - covered by existing tests in LayoutTests/css3/calc.

* CMakeLists.txt:
* GNUmakefile.list.am:
* Target.pri:
* WebCore.gypi:
* WebCore.vcproj/WebCore.vcproj:
* WebCore.xcodeproj/project.pbxproj:
* css/CSSCalculationValue.cpp: Added.
(WebCore):
(WebCore::unitCategory):
(WebCore::CSSCalcValue::customCssText):
(WebCore::CSSCalcExpressionNode::~CSSCalcExpressionNode):
(CSSCalcPrimitiveValue):
(WebCore::CSSCalcPrimitiveValue::create):
(WebCore::CSSCalcPrimitiveValue::cssText):
(WebCore::CSSCalcPrimitiveValue::CSSCalcPrimitiveValue):
():
(CSSCalcBinaryOperation):
(WebCore::CSSCalcBinaryOperation::create):
(WebCore::CSSCalcBinaryOperation::CSSCalcBinaryOperation):
(WebCore::checkDepthAndIndex):
(CSSCalcExpressionNodeParser):
(WebCore::CSSCalcExpressionNodeParser::parseCalc):
(Value):
(WebCore::CSSCalcExpressionNodeParser::operatorValue):
(WebCore::CSSCalcExpressionNodeParser::parseValue):
(WebCore::CSSCalcExpressionNodeParser::parseValueTerm):
(WebCore::CSSCalcExpressionNodeParser::parseValueMultiplicativeExpression):
(WebCore::CSSCalcExpressionNodeParser::parseAdditiveValueExpression):
(WebCore::CSSCalcExpressionNodeParser::parseValueExpression):
(WebCore::CSSCalcValue::create):
* css/CSSCalculationValue.h: Added.
(WebCore):
():
(CSSCalcExpressionNode):
(WebCore::CSSCalcExpressionNode::category):
(WebCore::CSSCalcExpressionNode::isInt):
(WebCore::CSSCalcExpressionNode::isZero):
(WebCore::CSSCalcExpressionNode::CSSCalcExpressionNode):
(CSSCalcValue):
(WebCore::CSSCalcValue::category):
(WebCore::CSSCalcValue::isInt):
(WebCore::CSSCalcValue::CSSCalcValue):
* css/CSSParser.cpp:
(WebCore::CSSParser::validCalculationUnit):
(WebCore):
(WebCore::CSSParser::validUnit):
(WebCore::CSSParser::createPrimitiveNumericValue):
(WebCore::CSSParser::parseValidPrimitive):
(WebCore::CSSParser::parseValue):
(WebCore::CSSParser::parseFillPositionComponent):
(WebCore::CSSParser::parsedDouble):
(WebCore::CSSParser::isCalculation):
(WebCore::CSSParser::colorIntFromValue):
(WebCore::CSSParser::parseColorParameters):
(WebCore::CSSParser::parseHSLParameters):
(WebCore::ShadowParseContext::ShadowParseContext):
(WebCore::ShadowParseContext::commitLength):
(WebCore::ShadowParseContext::commitStyle):
(ShadowParseContext):
(WebCore::CSSParser::parseShadow):
(WebCore::BorderImageSliceParseContext::BorderImageSliceParseContext):
(WebCore::BorderImageSliceParseContext::commitNumber):
(WebCore::BorderImageSliceParseContext::commitBorderImageSlice):
(BorderImageSliceParseContext):
(WebCore::CSSParser::parseBorderImageSlice):
(WebCore::BorderImageQuadParseContext::BorderImageQuadParseContext):
(WebCore::BorderImageQuadParseContext::commitNumber):
(WebCore::BorderImageQuadParseContext::commitBorderImageQuad):
(BorderImageQuadParseContext):
(WebCore::CSSParser::parseBorderImageQuad):
(WebCore::CSSParser::parseCalculation):
* css/CSSParser.h:
():
(CSSParser):
* css/CSSValue.cpp:
(WebCore::CSSValue::cssText):
(WebCore::CSSValue::destroy):
* css/CSSValue.h:
(WebCore::CSSValue::isCalculationValue):
():
* css/SVGCSSParser.cpp:
(WebCore::CSSParser::parseSVGValue):
* platform/CalculationValue.cpp: Added.
(WebCore):
* platform/CalculationValue.h: Added.
(WebCore):
():

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

16 files changed:
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.list.am
Source/WebCore/Target.pri
Source/WebCore/WebCore.gypi
Source/WebCore/WebCore.vcproj/WebCore.vcproj
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/css/CSSCalculationValue.cpp [new file with mode: 0755]
Source/WebCore/css/CSSCalculationValue.h [new file with mode: 0755]
Source/WebCore/css/CSSParser.cpp
Source/WebCore/css/CSSParser.h
Source/WebCore/css/CSSValue.cpp
Source/WebCore/css/CSSValue.h
Source/WebCore/css/SVGCSSParser.cpp
Source/WebCore/platform/CalculationValue.cpp [new file with mode: 0755]
Source/WebCore/platform/CalculationValue.h [new file with mode: 0755]

index 01b02b3..9cdaa08 100644 (file)
@@ -432,6 +432,7 @@ SET(WebCore_SOURCES
     css/CSSAspectRatioValue.cpp
     css/CSSBorderImage.cpp
     css/CSSBorderImageSliceValue.cpp
+    css/CSSCalculationValue.cpp
     css/CSSCanvasValue.cpp
     css/CSSCharsetRule.cpp
     css/CSSComputedStyleDeclaration.cpp
@@ -1045,6 +1046,7 @@ SET(WebCore_SOURCES
     page/animation/KeyframeAnimation.cpp
 
     platform/Arena.cpp
+    platform/CalculationValue.cpp
     platform/Clock.cpp
     platform/ContextMenu.cpp
     platform/ContextMenuItem.cpp
index a6234e1..e38e5b4 100644 (file)
@@ -1,3 +1,104 @@
+2012-01-27  Mike Lawther  <mikelawther@chromium.org>
+
+        CSS calc parsing stage
+        https://bugs.webkit.org/show_bug.cgi?id=57082
+
+        This is the parsing stage of calc. The expressions are evaluated and 
+        expression trees are generated. CSS values are not created yet - that
+        will happen in a subsequent commit. 
+
+        Reviewed by David Hyatt.
+
+        No functional change - covered by existing tests in LayoutTests/css3/calc.
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * Target.pri:
+        * WebCore.gypi:
+        * WebCore.vcproj/WebCore.vcproj:
+        * WebCore.xcodeproj/project.pbxproj:
+        * css/CSSCalculationValue.cpp: Added.
+        (WebCore):
+        (WebCore::unitCategory):
+        (WebCore::CSSCalcValue::customCssText):
+        (WebCore::CSSCalcExpressionNode::~CSSCalcExpressionNode):
+        (CSSCalcPrimitiveValue):
+        (WebCore::CSSCalcPrimitiveValue::create):
+        (WebCore::CSSCalcPrimitiveValue::cssText):
+        (WebCore::CSSCalcPrimitiveValue::CSSCalcPrimitiveValue):
+        ():
+        (CSSCalcBinaryOperation):
+        (WebCore::CSSCalcBinaryOperation::create):
+        (WebCore::CSSCalcBinaryOperation::CSSCalcBinaryOperation):
+        (WebCore::checkDepthAndIndex):
+        (CSSCalcExpressionNodeParser):
+        (WebCore::CSSCalcExpressionNodeParser::parseCalc):
+        (Value):
+        (WebCore::CSSCalcExpressionNodeParser::operatorValue):
+        (WebCore::CSSCalcExpressionNodeParser::parseValue):
+        (WebCore::CSSCalcExpressionNodeParser::parseValueTerm):
+        (WebCore::CSSCalcExpressionNodeParser::parseValueMultiplicativeExpression):
+        (WebCore::CSSCalcExpressionNodeParser::parseAdditiveValueExpression):
+        (WebCore::CSSCalcExpressionNodeParser::parseValueExpression):
+        (WebCore::CSSCalcValue::create):
+        * css/CSSCalculationValue.h: Added.
+        (WebCore):
+        ():
+        (CSSCalcExpressionNode):
+        (WebCore::CSSCalcExpressionNode::category):
+        (WebCore::CSSCalcExpressionNode::isInt):
+        (WebCore::CSSCalcExpressionNode::isZero):
+        (WebCore::CSSCalcExpressionNode::CSSCalcExpressionNode):
+        (CSSCalcValue):
+        (WebCore::CSSCalcValue::category):
+        (WebCore::CSSCalcValue::isInt):
+        (WebCore::CSSCalcValue::CSSCalcValue):
+        * css/CSSParser.cpp:
+        (WebCore::CSSParser::validCalculationUnit):
+        (WebCore):
+        (WebCore::CSSParser::validUnit):
+        (WebCore::CSSParser::createPrimitiveNumericValue):
+        (WebCore::CSSParser::parseValidPrimitive):
+        (WebCore::CSSParser::parseValue):
+        (WebCore::CSSParser::parseFillPositionComponent):
+        (WebCore::CSSParser::parsedDouble):
+        (WebCore::CSSParser::isCalculation):
+        (WebCore::CSSParser::colorIntFromValue):
+        (WebCore::CSSParser::parseColorParameters):
+        (WebCore::CSSParser::parseHSLParameters):
+        (WebCore::ShadowParseContext::ShadowParseContext):
+        (WebCore::ShadowParseContext::commitLength):
+        (WebCore::ShadowParseContext::commitStyle):
+        (ShadowParseContext):
+        (WebCore::CSSParser::parseShadow):
+        (WebCore::BorderImageSliceParseContext::BorderImageSliceParseContext):
+        (WebCore::BorderImageSliceParseContext::commitNumber):
+        (WebCore::BorderImageSliceParseContext::commitBorderImageSlice):
+        (BorderImageSliceParseContext):
+        (WebCore::CSSParser::parseBorderImageSlice):
+        (WebCore::BorderImageQuadParseContext::BorderImageQuadParseContext):
+        (WebCore::BorderImageQuadParseContext::commitNumber):
+        (WebCore::BorderImageQuadParseContext::commitBorderImageQuad):
+        (BorderImageQuadParseContext):
+        (WebCore::CSSParser::parseBorderImageQuad):
+        (WebCore::CSSParser::parseCalculation):
+        * css/CSSParser.h:
+        ():
+        (CSSParser):
+        * css/CSSValue.cpp:
+        (WebCore::CSSValue::cssText):
+        (WebCore::CSSValue::destroy):
+        * css/CSSValue.h:
+        (WebCore::CSSValue::isCalculationValue):
+        ():
+        * css/SVGCSSParser.cpp:
+        (WebCore::CSSParser::parseSVGValue):
+        * platform/CalculationValue.cpp: Added.
+        (WebCore):
+        * platform/CalculationValue.h: Added.
+        (WebCore):
+        ():
+
 2012-01-27  Anders Carlsson  <andersca@apple.com>
 
         WebTileLayers should honor the acceleratesDrawing flag
index 8c4c1e0..5afee1e 100644 (file)
@@ -1291,6 +1291,8 @@ webcore_sources += \
        Source/WebCore/css/CSSCanvasValue.h \
        Source/WebCore/css/CSSCharsetRule.cpp \
        Source/WebCore/css/CSSCharsetRule.h \
+       Source/WebCore/css/CSSCalculationValue.cpp \
+       Source/WebCore/css/CSSCalculationValue.h \
        Source/WebCore/css/CSSComputedStyleDeclaration.cpp \
        Source/WebCore/css/CSSComputedStyleDeclaration.h \
        Source/WebCore/css/CSSCrossfadeValue.cpp \
@@ -2796,6 +2798,8 @@ webcore_sources += \
        Source/WebCore/platform/AsyncFileSystem.cpp \
        Source/WebCore/platform/AsyncFileSystem.h \
        Source/WebCore/platform/AutodrainedPool.h \
+       Source/WebCore/platform/CalculationValue.cpp \
+       Source/WebCore/platform/CalculationValue.h \
        Source/WebCore/platform/Clock.cpp \
        Source/WebCore/platform/Clock.h \
        Source/WebCore/platform/ClockGeneric.cpp \
index d21ab66..c718e39 100644 (file)
@@ -395,6 +395,7 @@ SOURCES += \
     css/CSSAspectRatioValue.cpp \
     css/CSSBorderImageSliceValue.cpp \
     css/CSSBorderImage.cpp \
+    css/CSSCalculationValue.cpp \
     css/CSSCanvasValue.cpp \
     css/CSSCharsetRule.cpp \
     css/CSSComputedStyleDeclaration.cpp \
@@ -1027,6 +1028,7 @@ SOURCES += \
     platform/text/LocalizedDateNone.cpp \
     platform/text/LocalizedNumberNone.cpp \
     platform/text/QuotedPrintable.cpp \
+    platform/CalculationValue.cpp \
     platform/Clock.cpp \
     platform/ClockGeneric.cpp \
     platform/ContentType.cpp \
@@ -1507,7 +1509,10 @@ v8 {
 HEADERS += \
     css/CSSAspectRatioValue.h \
     css/CSSBorderImageSliceValue.h \
+    css/CSSBorderImageValue.h \
     css/CSSBorderImage.h \
+    css/CSSBorderImageValue.h \
+    css/CSSCalculationValue.h \
     css/CSSCanvasValue.h \
     css/CSSCharsetRule.h \
     css/CSSComputedStyleDeclaration.h \
@@ -2077,6 +2082,7 @@ HEADERS += \
     platform/animation/AnimationUtilities.h \
     platform/Arena.h \
     platform/AsyncFileStream.h \
+    platform/CalculationValue.h \
     platform/Clock.h \
     platform/ClockGeneric.h \
     platform/ContentType.h \
index 5b69c36..0d4d280 100644 (file)
             'css/CSSBorderImageSliceValue.h',
             'css/CSSCanvasValue.cpp',
             'css/CSSCanvasValue.h',
+            'css/CSSCalculationValue.cpp',
+            'css/CSSCalculationValue.h',
             'css/CSSCharsetRule.cpp',
             'css/CSSCharsetRule.h',
             'css/CSSComputedStyleDeclaration.cpp',
             'platform/AsyncFileSystem.h',
             'platform/AsyncFileSystemCallbacks.h',
             'platform/AutodrainedPool.h',
+            'platform/CalculationValue.cpp',
+            'platform/CalculationValue.h',
             'platform/Clock.cpp',
             'platform/Clock.h',
             'platform/ContentType.cpp',
index 4ed8c75..8e2e861 100755 (executable)
                                >
                        </File>
                        <File
+                               RelativePath="..\platform\CalculationValue.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\platform\CalculationValue.h"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\platform\Clock.cpp"
                                >
                        </File>
                                >
                        </File>
                        <File
+                               RelativePath="..\css\CSSCalculationValue.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\css\CSSCalculationValue.h"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\css\CSSCanvasValue.cpp"
                                >
                                <FileConfiguration
index 6516440..116dbb7 100644 (file)
                499B3ED6128CD31400E726C2 /* GraphicsLayerCA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 499B3ED4128CD31400E726C2 /* GraphicsLayerCA.cpp */; };
                499B3ED7128CD31400E726C2 /* GraphicsLayerCA.h in Headers */ = {isa = PBXBuildFile; fileRef = 499B3ED5128CD31400E726C2 /* GraphicsLayerCA.h */; settings = {ATTRIBUTES = (Private, ); }; };
                499B3EDD128DB50200E726C2 /* PlatformCAAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 499B3EDC128DB50100E726C2 /* PlatformCAAnimation.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               49AE2D8E134EE50C0072920A /* CSSCalculationValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49AE2D8C134EE50C0072920A /* CSSCalculationValue.cpp */; };
+               49AE2D8F134EE50C0072920A /* CSSCalculationValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 49AE2D8D134EE50C0072920A /* CSSCalculationValue.h */; };
+               49AE2D96134EE5F90072920A /* CalculationValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49AE2D94134EE5F90072920A /* CalculationValue.cpp */; };
+               49AE2D97134EE5F90072920A /* CalculationValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 49AE2D95134EE5F90072920A /* CalculationValue.h */; };
                49AF2D6914435D050016A784 /* DisplayRefreshMonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 49AF2D6814435D050016A784 /* DisplayRefreshMonitor.h */; };
                49AF2D6C14435D210016A784 /* DisplayRefreshMonitorMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49AF2D6B14435D210016A784 /* DisplayRefreshMonitorMac.cpp */; };
                49C7B9931042D2D30009D447 /* JSWebGLBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49C7B9801042D2D30009D447 /* JSWebGLBuffer.cpp */; };
                499B3ED4128CD31400E726C2 /* GraphicsLayerCA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GraphicsLayerCA.cpp; path = ca/GraphicsLayerCA.cpp; sourceTree = "<group>"; };
                499B3ED5128CD31400E726C2 /* GraphicsLayerCA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GraphicsLayerCA.h; path = ca/GraphicsLayerCA.h; sourceTree = "<group>"; };
                499B3EDC128DB50100E726C2 /* PlatformCAAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlatformCAAnimation.h; path = ca/PlatformCAAnimation.h; sourceTree = "<group>"; };
+               49AE2D8C134EE50C0072920A /* CSSCalculationValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSCalculationValue.cpp; sourceTree = "<group>"; };
+               49AE2D8D134EE50C0072920A /* CSSCalculationValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSCalculationValue.h; sourceTree = "<group>"; };
+               49AE2D94134EE5F90072920A /* CalculationValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CalculationValue.cpp; sourceTree = "<group>"; };
+               49AE2D95134EE5F90072920A /* CalculationValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CalculationValue.h; sourceTree = "<group>"; };
                49AF2D6814435D050016A784 /* DisplayRefreshMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DisplayRefreshMonitor.h; sourceTree = "<group>"; };
                49AF2D6B14435D210016A784 /* DisplayRefreshMonitorMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DisplayRefreshMonitorMac.cpp; sourceTree = "<group>"; };
                49C7B9801042D2D30009D447 /* JSWebGLBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWebGLBuffer.cpp; sourceTree = "<group>"; };
                                89D08D9D12228451001241DF /* AsyncFileSystem.h */,
                                89D08D9E12228451001241DF /* AsyncFileSystemCallbacks.h */,
                                51E1ECB10C91C55600DC255B /* AutodrainedPool.h */,
+                               49AE2D94134EE5F90072920A /* CalculationValue.cpp */,
+                               49AE2D95134EE5F90072920A /* CalculationValue.h */,
                                CDEA76331460B462008B31F1 /* Clock.cpp */,
                                CDEA762C14608224008B31F1 /* Clock.h */,
                                CDEA76321460AE29008B31F1 /* ClockGeneric.cpp */,
                                E16A84F814C85CCC002977DF /* CSSBorderImage.h */,
                                BC274B30140EBED800EADFA6 /* CSSBorderImageSliceValue.cpp */,
                                BC274B2E140EBEB200EADFA6 /* CSSBorderImageSliceValue.h */,
+                               49AE2D8C134EE50C0072920A /* CSSCalculationValue.cpp */,
+                               49AE2D8D134EE50C0072920A /* CSSCalculationValue.h */,
                                BC604A420DB5634E00204739 /* CSSCanvasValue.cpp */,
                                BC6049CB0DB560C200204739 /* CSSCanvasValue.h */,
                                E1EBBBD30AAC9B87001FE8E2 /* CSSCharsetRule.cpp */,
                                0753860314489E9800B78452 /* CachedTextTrack.h in Headers */,
                                BCB16C280979C3BD00467741 /* CachedXSLStyleSheet.h in Headers */,
                                93F1995008245E59001E9ABC /* CachePolicy.h in Headers */,
+                               49AE2D97134EE5F90072920A /* CalculationValue.h in Headers */,
                                B1D5ECB5134B58DA0087C78F /* CallbackFunction.h in Headers */,
                                6E4E91AD10F7FB3100A2779C /* CanvasContextAttributes.h in Headers */,
                                49484FC2102CF23C00187DD3 /* CanvasGradient.h in Headers */,
                                CAE9F910146441F000C245B0 /* CSSAspectRatioValue.h in Headers */,
                                E16A84FA14C85CCC002977DF /* CSSBorderImage.h in Headers */,
                                BC274B2F140EBEB200EADFA6 /* CSSBorderImageSliceValue.h in Headers */,
+                               49AE2D8F134EE50C0072920A /* CSSCalculationValue.h in Headers */,
                                BC6049CC0DB560C200204739 /* CSSCanvasValue.h in Headers */,
                                A80E6CF90A1989CA007FB8C5 /* CSSCharsetRule.h in Headers */,
                                BCEA4790097CAAC80094C9E4 /* CSSComputedStyleDeclaration.h in Headers */,
                0867D690FE84028FC02AAC07 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
+                               BuildIndependentTargetsInParallel = YES;
                                LastUpgradeCheck = 0440;
                        };
                        buildConfigurationList = 149C284308902B11008A9EFC /* Build configuration list for PBXProject "WebCore" */;
                                5038BE401472AD980095E0D1 /* CachedShader.cpp in Sources */,
                                0753860214489E9800B78452 /* CachedTextTrack.cpp in Sources */,
                                BCB16C270979C3BD00467741 /* CachedXSLStyleSheet.cpp in Sources */,
+                               49AE2D96134EE5F90072920A /* CalculationValue.cpp in Sources */,
                                B1827493134CA4C100B98C2D /* CallbackFunction.cpp in Sources */,
                                6E4E91AC10F7FB3100A2779C /* CanvasContextAttributes.cpp in Sources */,
                                49484FC1102CF23C00187DD3 /* CanvasGradient.cpp in Sources */,
                                CAE9F90F146441F000C245B0 /* CSSAspectRatioValue.cpp in Sources */,
                                E16A84F914C85CCC002977DF /* CSSBorderImage.cpp in Sources */,
                                BC274B31140EBED800EADFA6 /* CSSBorderImageSliceValue.cpp in Sources */,
+                               49AE2D8E134EE50C0072920A /* CSSCalculationValue.cpp in Sources */,
                                BC604A430DB5634E00204739 /* CSSCanvasValue.cpp in Sources */,
                                E1EBBBD40AAC9B87001FE8E2 /* CSSCharsetRule.cpp in Sources */,
                                BCEA478F097CAAC80094C9E4 /* CSSComputedStyleDeclaration.cpp in Sources */,
diff --git a/Source/WebCore/css/CSSCalculationValue.cpp b/Source/WebCore/css/CSSCalculationValue.cpp
new file mode 100755 (executable)
index 0000000..11907f2
--- /dev/null
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2011 Google 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:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER 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 "CSSCalculationValue.h"
+
+#include "CSSStyleSelector.h"
+#include "CSSValueList.h"
+#include "Length.h"
+
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/text/StringBuilder.h>
+
+static const int maxExpressionDepth = 100;
+
+enum ParseState {
+    OK,
+    TooDeep,
+    NoMoreTokens
+};
+
+namespace WebCore {
+
+static CalculationCategory unitCategory(CSSPrimitiveValue::UnitTypes type)
+{
+    switch (type) {
+    case CSSPrimitiveValue::CSS_NUMBER:
+    case CSSPrimitiveValue::CSS_PARSER_INTEGER:
+        return CalcNumber;
+    case CSSPrimitiveValue::CSS_PERCENTAGE:
+        return CalcPercent;
+    case CSSPrimitiveValue::CSS_EMS:
+    case CSSPrimitiveValue::CSS_EXS:
+    case CSSPrimitiveValue::CSS_PX:
+    case CSSPrimitiveValue::CSS_CM:
+    case CSSPrimitiveValue::CSS_MM:
+    case CSSPrimitiveValue::CSS_IN:
+    case CSSPrimitiveValue::CSS_PT:
+    case CSSPrimitiveValue::CSS_PC:
+    case CSSPrimitiveValue::CSS_REMS:
+        return CalcLength;
+    default:
+        return CalcOther;
+    }
+}
+    
+String CSSCalcValue::customCssText() const
+{
+    return "";
+}
+    
+CSSCalcExpressionNode::~CSSCalcExpressionNode() 
+{
+}
+    
+class CSSCalcPrimitiveValue : public CSSCalcExpressionNode {
+public:
+
+    static PassRefPtr<CSSCalcPrimitiveValue> create(CSSPrimitiveValue* value, bool isInteger)
+    {
+        return adoptRef(new CSSCalcPrimitiveValue(value, isInteger));
+    }
+    
+    virtual String cssText() const
+    {
+        return m_value->cssText();
+    }
+
+    
+private:
+    explicit CSSCalcPrimitiveValue(CSSPrimitiveValue* value, bool isInteger)
+        : CSSCalcExpressionNode(unitCategory((CSSPrimitiveValue::UnitTypes)value->primitiveType()), isInteger)
+        , m_value(value)                 
+    {
+    }
+
+    RefPtr<CSSPrimitiveValue> m_value;
+};
+
+static const CalculationCategory addSubtractResult[CalcOther][CalcOther] = {
+    { CalcNumber,        CalcOther,         CalcPercentNumber, CalcPercentNumber, CalcOther },
+    { CalcOther,         CalcLength,        CalcPercentLength, CalcOther,         CalcPercentLength },
+    { CalcPercentNumber, CalcPercentLength, CalcPercent,       CalcPercentNumber, CalcPercentLength },
+    { CalcPercentNumber, CalcOther,         CalcPercentNumber, CalcPercentNumber, CalcOther },
+    { CalcOther,         CalcPercentLength, CalcPercentLength, CalcOther,         CalcPercentLength },
+};    
+    
+class CSSCalcBinaryOperation : public CSSCalcExpressionNode {
+public:
+    static PassRefPtr<CSSCalcBinaryOperation> create(PassRefPtr<CSSCalcExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide, CalcOperator op)
+    {
+        CalculationCategory leftCategory = leftSide->category();
+        CalculationCategory rightCategory = rightSide->category();
+        CalculationCategory newCategory = CalcOther;
+        
+        ASSERT(leftCategory != CalcOther && rightCategory != CalcOther);
+        
+        switch (op) {
+        case CalcAdd:
+        case CalcSubtract:             
+            if (leftCategory == CalcOther || rightCategory == CalcOther)
+                return 0;
+            newCategory = addSubtractResult[leftCategory][rightCategory];
+            break;   
+                
+        case CalcMultiply:
+            if (leftCategory != CalcNumber && rightCategory != CalcNumber) 
+                return 0;
+            
+            newCategory = leftCategory == CalcNumber ? rightCategory : leftCategory;
+            break;
+                
+        case CalcDivide:
+        case CalcMod:
+            if (rightCategory != CalcNumber || rightSide->isZero())
+                return 0;
+            newCategory = leftCategory;
+            break;
+        }
+        
+        if (newCategory == CalcOther)
+            return 0;
+            
+        return adoptRef(new CSSCalcBinaryOperation(leftSide, rightSide, op, newCategory));
+    }
+    
+private:
+    CSSCalcBinaryOperation(PassRefPtr<CSSCalcExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide, CalcOperator op, CalculationCategory category)
+        : CSSCalcExpressionNode(category, leftSide->isInteger() && rightSide->isInteger())
+        , m_leftSide(leftSide)
+        , m_rightSide(rightSide)
+        , m_operator(op)
+    {
+    }
+    
+    const RefPtr<CSSCalcExpressionNode> m_leftSide;
+    const RefPtr<CSSCalcExpressionNode> m_rightSide;
+    const CalcOperator m_operator;
+};
+
+static ParseState checkDepthAndIndex(int* depth, unsigned index, CSSParserValueList* tokens)
+{
+    (*depth)++;
+    if (*depth > maxExpressionDepth)
+        return TooDeep;
+    if (index >= tokens->size())
+        return NoMoreTokens;
+    return OK;
+}
+
+class CSSCalcExpressionNodeParser {
+public:
+    PassRefPtr<CSSCalcExpressionNode> parseCalc(CSSParserValueList* tokens)
+    {
+        unsigned index = 0;
+        Value result;
+        bool ok = parseValueExpression(tokens, 0, &index, &result);
+        ASSERT(index <= tokens->size());
+        if (!ok || index != tokens->size())
+            return 0;
+        return result.value;
+    }
+
+private:
+    struct Value {
+        RefPtr<CSSCalcExpressionNode> value;
+    };
+
+    char operatorValue(CSSParserValueList* tokens, unsigned index)
+    {
+        if (index >= tokens->size())
+            return 0;
+        CSSParserValue* value = tokens->valueAt(index);
+        if (value->unit != CSSParserValue::Operator)
+            return 0;
+
+        return value->iValue;
+    }
+
+    bool parseValue(CSSParserValueList* tokens, unsigned* index, Value* result)
+    {
+        CSSParserValue* parserValue = tokens->valueAt(*index);
+        if (parserValue->unit == CSSParserValue::Operator || parserValue->unit == CSSParserValue::Function)
+            return false;
+
+        RefPtr<CSSValue> value = parserValue->createCSSValue();
+        if (!value || !value->isPrimitiveValue())
+            return false;
+
+        CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value.get());
+        result->value = CSSCalcPrimitiveValue::create(primitiveValue, parserValue->isInt);
+
+        ++*index;
+        return true;
+    }
+
+    bool parseValueTerm(CSSParserValueList* tokens, int depth, unsigned* index, Value* result)
+    {
+        if (checkDepthAndIndex(&depth, *index, tokens) != OK)
+            return false;    
+        
+        if (operatorValue(tokens, *index) == '(') {
+            unsigned currentIndex = *index + 1;
+            if (!parseValueExpression(tokens, depth, &currentIndex, result))
+                return false;
+
+            if (operatorValue(tokens, currentIndex) != ')')
+                return false;
+            *index = currentIndex + 1;
+            return true;
+        }
+
+        return parseValue(tokens, index, result);
+    }
+
+    bool parseValueMultiplicativeExpression(CSSParserValueList* tokens, int depth, unsigned* index, Value* result)
+    {
+        if (checkDepthAndIndex(&depth, *index, tokens) != OK)
+            return false;    
+
+        if (!parseValueTerm(tokens, depth, index, result))
+            return false;
+
+        while (*index < tokens->size() - 1) {
+            char operatorCharacter = operatorValue(tokens, *index);
+            if (operatorCharacter != CalcMultiply && operatorCharacter != CalcDivide && operatorCharacter != CalcMod)
+                break;
+            ++*index;
+
+            Value rhs;
+            if (!parseValueTerm(tokens, depth, index, &rhs))
+                return false;
+
+            result->value = CSSCalcBinaryOperation::create(result->value, rhs.value, static_cast<CalcOperator>(operatorCharacter));
+            if (!result->value)
+                return false;
+        }
+
+        ASSERT(*index <= tokens->size());
+        return true;
+    }
+
+    bool parseAdditiveValueExpression(CSSParserValueList* tokens, int depth, unsigned* index, Value* result)
+    {
+        if (checkDepthAndIndex(&depth, *index, tokens) != OK)
+            return false;    
+
+        if (!parseValueMultiplicativeExpression(tokens, depth, index, result))
+            return false;
+
+        while (*index < tokens->size() - 1) {
+            char operatorCharacter = operatorValue(tokens, *index);
+            if (operatorCharacter != CalcAdd && operatorCharacter != CalcSubtract)
+                break;
+            ++*index;
+
+            Value rhs;
+            if (!parseValueMultiplicativeExpression(tokens, depth, index, &rhs))
+                return false;
+
+            result->value = CSSCalcBinaryOperation::create(result->value, rhs.value, static_cast<CalcOperator>(operatorCharacter));
+            if (!result->value)
+                return false;
+        }
+
+        ASSERT(*index <= tokens->size());
+        return true;
+    }
+
+    bool parseValueExpression(CSSParserValueList* tokens, int depth, unsigned* index, Value* result)
+    {
+        return parseAdditiveValueExpression(tokens, depth, index, result);
+    }
+};
+
+PassRefPtr<CSSCalcValue> CSSCalcValue::create(CSSParserString name, CSSParserValueList* parserValueList)
+{    
+    CSSCalcExpressionNodeParser parser;    
+    RefPtr<CSSCalcExpressionNode> expression;
+    
+    if (equalIgnoringCase(name, "-webkit-calc("))
+        expression = parser.parseCalc(parserValueList);    
+    // FIXME calc (http://webkit.org/b/16662) Add parsing for min and max here
+
+    return expression ? adoptRef(new CSSCalcValue(expression)) : 0;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/css/CSSCalculationValue.h b/Source/WebCore/css/CSSCalculationValue.h
new file mode 100755 (executable)
index 0000000..4d4639d
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2011 Google 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:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER 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 CSSCalculationValue_h
+#define CSSCalculationValue_h
+
+#include "CSSParserValues.h"
+#include "CSSValue.h"
+#include "CalculationValue.h"
+#include <wtf/PassOwnPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class CSSParserValueList;
+class CSSValueList;
+class RenderStyle;
+class CalcValue;
+class CalcExpressionNode;
+
+enum CalculationCategory {
+    CalcNumber = 0,
+    CalcLength,
+    CalcPercent,
+    CalcPercentNumber,
+    CalcPercentLength,
+    CalcOther
+};
+    
+class CSSCalcExpressionNode : public RefCounted<CSSCalcExpressionNode> {
+public:
+    
+    virtual ~CSSCalcExpressionNode() = 0;    
+    
+    CalculationCategory category() const { return m_category; }    
+    bool isInteger() const { return m_isInteger; }
+    bool isZero() const { return false; }
+    
+protected:
+    CSSCalcExpressionNode(CalculationCategory category, bool isInteger)
+        : m_category(category)
+        , m_isInteger(isInteger)
+    {
+    }
+    
+    CalculationCategory m_category;
+    bool m_isInteger;
+};
+        
+class CSSCalcValue : public CSSValue {
+public:
+    static PassRefPtr<CSSCalcValue> create(CSSParserString name, CSSParserValueList*);
+
+    CalculationCategory category() const { return m_expression->category(); }
+    bool isInt() const { return m_expression->isInteger(); }
+        
+    String customCssText() const;
+    
+private:    
+    CSSCalcValue(PassRefPtr<CSSCalcExpressionNode> expression)
+        : CSSValue(CalculationClass)
+        , m_expression(expression)
+    {
+    }
+    
+    const RefPtr<CSSCalcExpressionNode> m_expression;
+};
+    
+} // namespace WebCore
+
+#endif // CSSCalculationValue_h
index eaf6703..4c04e36 100644 (file)
@@ -692,13 +692,54 @@ Document* CSSParser::findDocument() const
     return m_styleSheet->findDocument();
 }
 
+bool CSSParser::validCalculationUnit(CSSParserValue* value, Units unitflags)
+{
+    if (!parseCalculation(value))
+        return false;
+
+    bool b = false;
+    switch (m_parsedCalculation->category()) {
+    case CalcLength:
+        b = (unitflags & FLength);
+        break;
+    case CalcPercent:
+        b = (unitflags & FPercent);
+        // FIXME calc (http://webkit.org/b/16662): test FNonNeg here, eg
+        // if (b && (unitflags & FNonNeg) && m_parsedCalculation->doubleValue() < 0)
+        //    b = false;
+        break;
+    case CalcNumber:
+        b = (unitflags & FNumber);
+        if (!b && (unitflags & FInteger) && m_parsedCalculation->isInt())
+            b = true;
+        // FIXME calc (http://webkit.org/b/16662): test FNonNeg here, eg
+        // if (b && (unitflags & FNonNeg) && m_parsedCalculation->doubleValue() < 0)
+        //    b = false;
+        break;
+    case CalcPercentLength:
+        b = (unitflags & FPercent) && (unitflags & FLength);
+        break;
+    case CalcPercentNumber:
+        b = (unitflags & FPercent) && (unitflags & FNumber);
+        break;
+    case CalcOther:
+        break;
+    }
+    if (!b)
+        m_parsedCalculation.release();
+    return b;    
+}
+
 bool CSSParser::validUnit(CSSParserValue* value, Units unitflags, bool strict)
 {
+    if (isCalculation(value))
+        return validCalculationUnit(value, unitflags);
+        
     bool b = false;
     switch (value->unit) {
     case CSSPrimitiveValue::CSS_NUMBER:
         b = (unitflags & FNumber);
-        if (!b && ((unitflags & (FLength | FAngle | FTime)) && (value->fValue == 0 || !strict))) {
+        if (!b && ((unitflags & (FLength | FAngle | FTime)) && (!value->fValue || !strict))) {
             value->unit = (unitflags & FLength) ? CSSPrimitiveValue::CSS_PX :
                           ((unitflags & FAngle) ? CSSPrimitiveValue::CSS_DEG : CSSPrimitiveValue::CSS_MS);
             b = true;
@@ -744,6 +785,14 @@ bool CSSParser::validUnit(CSSParserValue* value, Units unitflags, bool strict)
 
 inline PassRefPtr<CSSPrimitiveValue> CSSParser::createPrimitiveNumericValue(CSSParserValue* value)
 {
+    if (m_parsedCalculation) {
+        ASSERT(isCalculation(value));
+        // FIXME calc() http://webkit.org/b/16662: create a CSSPrimitiveValue here, ie
+        // return CSSPrimitiveValue::create(m_parsedCalculation.release());
+        m_parsedCalculation.release();
+        return 0;
+    }
+               
     ASSERT((value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
            || (value->unit >= CSSPrimitiveValue::CSS_TURN && value->unit <= CSSPrimitiveValue::CSS_REMS));
     return cssValuePool()->createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit));
@@ -841,6 +890,11 @@ inline PassRefPtr<CSSPrimitiveValue> CSSParser::parseValidPrimitive(int id, CSSP
         return createPrimitiveNumericValue(value);
     if (value->unit >= CSSParserValue::Q_EMS)
         return CSSPrimitiveValue::createAllowingMarginQuirk(value->fValue, CSSPrimitiveValue::CSS_EMS);
+    if (isCalculation(value))
+        // FIXME calc()  http://webkit.org/b/16662: create a primitive value here, ie
+        // return CSSPrimitiveValue::create(m_parsedCalculation.release());
+        m_parsedCalculation.release();
+
     return 0;
 }
 
@@ -854,6 +908,10 @@ bool CSSParser::parseValue(int propId, bool important)
     if (!value)
         return false;
 
+    // Note: m_parsedCalculation is used to pass the calc value to validUnit and then cleared at the end of this function.
+    // FIXME: This is to avoid having to pass parsedCalc to all validUnit callers.
+    ASSERT(!m_parsedCalculation);
+    
     int id = value->id;
 
     // In quirks mode, we will look for units that have been incorrectly separated from the number they belong to
@@ -2281,6 +2339,7 @@ bool CSSParser::parseValue(int propId, bool important)
         parsedValue = parseValidPrimitive(id, value);
         m_valueList->next();
     }
+    ASSERT(!m_parsedCalculation);
     if (parsedValue) {
         if (!m_valueList->current() || inShorthand()) {
             addProperty(propId, parsedValue.release(), important);
@@ -2988,8 +3047,11 @@ PassRefPtr<CSSValue> CSSParser::parseFillPositionComponent(CSSParserValueList* v
         } else if (cumulativeFlags & (XFillPosition | AmbiguousFillPosition)) {
             cumulativeFlags |= YFillPosition;
             individualFlag = YFillPosition;
-        } else
+        } else {
+            if (m_parsedCalculation)
+                m_parsedCalculation.release();
             return 0;
+        }
         return createPrimitiveNumericValue(valueList->current());
     }
     return 0;
@@ -4871,22 +4933,49 @@ bool CSSParser::fastParseColor(RGBA32& rgb, const String& name, bool strict)
     }
     return false;
 }
+    
+inline double CSSParser::parsedDouble(CSSParserValue *v, ReleaseParsedCalcValueCondition releaseCalc)
+{
+    // FIXME calc (http://webkit.org/b/16662): evaluate calc here, eg
+    // const double result = m_parsedCalculation ? m_parsedCalculation->doubleValue() : v->fValue;
+    const double result = m_parsedCalculation ? 0 : v->fValue;
+    if (releaseCalc == ReleaseParsedCalcValue)
+        m_parsedCalculation.release();
+    return result;
+}
+
+bool CSSParser::isCalculation(CSSParserValue* value) 
+{
+    return (value->unit == CSSParserValue::Function) 
+        && (equalIgnoringCase(value->function->name, "-webkit-calc(")
+            || equalIgnoringCase(value->function->name, "-webkit-min(")
+            || equalIgnoringCase(value->function->name, "-webkit-max("));
+}
 
-static inline int colorIntFromValue(CSSParserValue* v)
+inline int CSSParser::colorIntFromValue(CSSParserValue* v)
 {
-    if (v->fValue <= 0.0)
+    bool isPercent;
+    
+    if (m_parsedCalculation)
+        isPercent = m_parsedCalculation->category() == CalcPercent;
+    else
+        isPercent = v->unit == CSSPrimitiveValue::CSS_PERCENTAGE;
+
+    const double value = parsedDouble(v, ReleaseParsedCalcValue);
+    
+    if (value <= 0.0)
         return 0;
 
-    if (v->unit == CSSPrimitiveValue::CSS_PERCENTAGE) {
-        if (v->fValue >= 100.0)
+    if (isPercent) {
+        if (value >= 100.0)
             return 255;
-        return static_cast<int>(v->fValue * 256.0 / 100.0);
+        return static_cast<int>(value * 256.0 / 100.0);
     }
 
-    if (v->fValue >= 255.0)
+    if (value >= 255.0)
         return 255;
 
-    return static_cast<int>(v->fValue);
+    return static_cast<int>(value);
 }
 
 bool CSSParser::parseColorParameters(CSSParserValue* value, int* colorArray, bool parseAlpha)
@@ -4901,6 +4990,7 @@ bool CSSParser::parseColorParameters(CSSParserValue* value, int* colorArray, boo
         unitType = FPercent;
     else
         return false;
+    
     colorArray[0] = colorIntFromValue(v);
     for (int i = 1; i < 3; i++) {
         v = args->next();
@@ -4918,9 +5008,10 @@ bool CSSParser::parseColorParameters(CSSParserValue* value, int* colorArray, boo
         v = args->next();
         if (!validUnit(v, FNumber, true))
             return false;
+        const double value = parsedDouble(v, ReleaseParsedCalcValue);
         // Convert the floating pointer number of alpha to an integer in the range [0, 256),
         // with an equal distribution across all 256 values.
-        colorArray[3] = static_cast<int>(max(0.0, min(1.0, v->fValue)) * nextafter(256.0, 0.0));
+        colorArray[3] = static_cast<int>(max(0.0, min(1.0, value)) * nextafter(256.0, 0.0));
     }
     return true;
 }
@@ -4938,7 +5029,7 @@ bool CSSParser::parseHSLParameters(CSSParserValue* value, double* colorArray, bo
     if (!validUnit(v, FNumber, true))
         return false;
     // normalize the Hue value and change it to be between 0 and 1.0
-    colorArray[0] = (((static_cast<int>(v->fValue) % 360) + 360) % 360) / 360.0;
+    colorArray[0] = (((static_cast<int>(parsedDouble(v, ReleaseParsedCalcValue)) % 360) + 360) % 360) / 360.0;
     for (int i = 1; i < 3; i++) {
         v = args->next();
         if (v->unit != CSSParserValue::Operator && v->iValue != ',')
@@ -4946,7 +5037,7 @@ bool CSSParser::parseHSLParameters(CSSParserValue* value, double* colorArray, bo
         v = args->next();
         if (!validUnit(v, FPercent, true))
             return false;
-        colorArray[i] = max(0.0, min(100.0, v->fValue)) / 100.0; // needs to be value between 0 and 1.0
+        colorArray[i] = max(0.0, min(100.0, parsedDouble(v, ReleaseParsedCalcValue))) / 100.0; // needs to be value between 0 and 1.0
     }
     if (parseAlpha) {
         v = args->next();
@@ -4955,7 +5046,7 @@ bool CSSParser::parseHSLParameters(CSSParserValue* value, double* colorArray, bo
         v = args->next();
         if (!validUnit(v, FNumber, true))
             return false;
-        colorArray[3] = max(0.0, min(1.0, v->fValue));
+        colorArray[3] = max(0.0, min(1.0, parsedDouble(v, ReleaseParsedCalcValue)));
     }
     return true;
 }
@@ -5023,9 +5114,9 @@ bool CSSParser::parseColorFromValue(CSSParserValue* value, RGBA32& c)
 // This class tracks parsing state for shadow values.  If it goes out of scope (e.g., due to an early return)
 // without the allowBreak bit being set, then it will clean up all of the objects and destroy them.
 struct ShadowParseContext {
-    ShadowParseContext(CSSPropertyID prop, CSSValuePool* cssValuePool)
+    ShadowParseContext(CSSPropertyID prop, CSSParser* parser)
         : property(prop)
-        , m_cssValuePool(cssValuePool)
+        , m_parser(parser)
         , allowX(true)
         , allowY(false)
         , allowBlur(false)
@@ -5068,7 +5159,7 @@ struct ShadowParseContext {
 
     void commitLength(CSSParserValue* v)
     {
-        RefPtr<CSSPrimitiveValue> val = m_cssValuePool->createValue(v->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(v->unit));
+        RefPtr<CSSPrimitiveValue> val = m_parser->createPrimitiveNumericValue(v);
 
         if (allowX) {
             x = val.release();
@@ -5110,7 +5201,7 @@ struct ShadowParseContext {
 
     void commitStyle(CSSParserValue* v)
     {
-        style = m_cssValuePool->createIdentifierValue(v->id);
+        style = m_parser->cssValuePool()->createIdentifierValue(v->id);
         allowStyle = false;
         if (allowX)
             allowBreak = false;
@@ -5122,7 +5213,7 @@ struct ShadowParseContext {
     }
 
     CSSPropertyID property;
-    CSSValuePool* m_cssValuePool;
+    CSSParser* m_parser;
 
     RefPtr<CSSValueList> values;
     RefPtr<CSSPrimitiveValue> x;
@@ -5143,7 +5234,7 @@ struct ShadowParseContext {
 
 PassRefPtr<CSSValueList> CSSParser::parseShadow(CSSParserValueList* valueList, int propId)
 {
-    ShadowParseContext context(static_cast<CSSPropertyID>(propId), cssValuePool());
+    ShadowParseContext context(static_cast<CSSPropertyID>(propId), this);
     CSSParserValue* val;
     while ((val = valueList->current())) {
         // Check for a comma break first.
@@ -5527,8 +5618,8 @@ bool CSSParser::parseBorderImageRepeat(RefPtr<CSSValue>& result)
 
 class BorderImageSliceParseContext {
 public:
-    BorderImageSliceParseContext(CSSValuePool* cssValuePool)
-    : m_cssValuePool(cssValuePool)
+    BorderImageSliceParseContext(CSSParser* parser)
+    : m_parser(parser)
     , m_allowNumber(true)
     , m_allowFill(false)
     , m_allowFinalCommit(false)
@@ -5542,7 +5633,7 @@ public:
 
     void commitNumber(CSSParserValue* v)
     {
-        RefPtr<CSSPrimitiveValue> val = m_cssValuePool->createValue(v->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(v->unit));
+        RefPtr<CSSPrimitiveValue> val = m_parser->createPrimitiveNumericValue(v);
         if (!m_top)
             m_top = val;
         else if (!m_right)
@@ -5588,11 +5679,11 @@ public:
         quad->setLeft(m_left);
 
         // Make our new border image value now.
-        return CSSBorderImageSliceValue::create(m_cssValuePool->createValue(quad.release()), m_fill);
+        return CSSBorderImageSliceValue::create(m_parser->cssValuePool()->createValue(quad.release()), m_fill);
     }
 
 private:
-    CSSValuePool* m_cssValuePool;
+    CSSParser* m_parser;
 
     bool m_allowNumber;
     bool m_allowFill;
@@ -5608,10 +5699,11 @@ private:
 
 bool CSSParser::parseBorderImageSlice(int propId, RefPtr<CSSBorderImageSliceValue>& result)
 {
-    BorderImageSliceParseContext context(cssValuePool());
+    BorderImageSliceParseContext context(this);
     CSSParserValue* val;
     while ((val = m_valueList->current())) {
-        if (context.allowNumber() && validUnit(val, FInteger | FNonNeg | FPercent, true)) {
+        // FIXME calc() http://webkit.org/b/16662 : calc is parsed but values are not created yet.
+        if (context.allowNumber() && !isCalculation(val) && validUnit(val, FInteger | FNonNeg | FPercent, true)) {
             context.commitNumber(val);
         } else if (context.allowFill() && val->id == CSSValueFill)
             context.commitFill();
@@ -5644,8 +5736,8 @@ bool CSSParser::parseBorderImageSlice(int propId, RefPtr<CSSBorderImageSliceValu
 
 class BorderImageQuadParseContext {
 public:
-    BorderImageQuadParseContext(CSSValuePool* cssValuePool)
-    : m_cssValuePool(cssValuePool)
+    BorderImageQuadParseContext(CSSParser* parser)
+    : m_parser(parser)
     , m_allowNumber(true)
     , m_allowFinalCommit(false)
     { }
@@ -5658,9 +5750,9 @@ public:
     {
         RefPtr<CSSPrimitiveValue> val;
         if (v->id == CSSValueAuto)
-            val = m_cssValuePool->createIdentifierValue(v->id);
+            val = m_parser->cssValuePool()->createIdentifierValue(v->id);
         else
-            val = m_cssValuePool->createValue(v->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(v->unit));
+            val = m_parser->createPrimitiveNumericValue(v);
 
         if (!m_top)
             m_top = val;
@@ -5704,11 +5796,11 @@ public:
         quad->setLeft(m_left);
 
         // Make our new value now.
-        return m_cssValuePool->createValue(quad.release());
+        return m_parser->cssValuePool()->createValue(quad.release());
     }
 
 private:
-    CSSValuePool* m_cssValuePool;
+    CSSParser* m_parser;
 
     bool m_allowNumber;
     bool m_allowFinalCommit;
@@ -5721,7 +5813,7 @@ private:
 
 bool CSSParser::parseBorderImageQuad(Units validUnits, RefPtr<CSSPrimitiveValue>& result)
 {
-    BorderImageQuadParseContext context(cssValuePool());
+    BorderImageQuadParseContext context(this);
     CSSParserValue* val;
     while ((val = m_valueList->current())) {
         if (context.allowNumber() && (validUnit(val, validUnits, true) || val->id == CSSValueAuto)) {
@@ -7325,6 +7417,23 @@ bool CSSParser::parseFontVariantLigatures(bool important)
     return true;
 }
 
+bool CSSParser::parseCalculation(CSSParserValue* value) 
+{
+    ASSERT(isCalculation(value));
+    
+    CSSParserValueList* args = value->function->args.get();
+    if (!args || !args->size())
+        return false;
+
+    ASSERT(!m_parsedCalculation);
+    m_parsedCalculation = CSSCalcValue::create(value->function->name, args);
+    
+    if (!m_parsedCalculation)
+        return false;
+    
+    return true;
+}
+    
 static inline int yyerror(const char*) { return 1; }
 
 #define END_TOKEN 0
index 3bf045e..f2acaf7 100644 (file)
@@ -23,6 +23,7 @@
 #ifndef CSSParser_h
 #define CSSParser_h
 
+#include "CSSCalculationValue.h"
 #include "CSSGradientValue.h"
 #include "CSSParserValues.h"
 #include "CSSPropertySourceData.h"
@@ -211,6 +212,7 @@ public:
     bool parseTextEmphasisStyle(bool important);
 
     bool parseLineBoxContain(bool important);
+    bool parseCalculation(CSSParserValue*);
 
     bool parseFontFeatureTag(CSSValueList*);
     bool parseFontFeatureSettings(bool important);
@@ -322,6 +324,9 @@ public:
     void countLines();
     int lex();
 
+    PassRefPtr<CSSPrimitiveValue> createPrimitiveNumericValue(CSSParserValue*);
+    PassRefPtr<CSSPrimitiveValue> createPrimitiveStringValue(CSSParserValue*);
+        
 private:
     void setStyleSheet(CSSStyleSheet*);
     void ensureCSSValuePool();
@@ -388,6 +393,8 @@ private:
     Vector<OwnPtr<CSSParserSelector> > m_reusableSelectorVector;
     Vector<OwnPtr<CSSParserSelector> > m_reusableRegionSelectorVector;
 
+    RefPtr<CSSCalcValue> m_parsedCalculation;
+
     // defines units allowed for a certain property, used in parseUnit
     enum Units {
         FUnknown   = 0x0000,
@@ -407,13 +414,19 @@ private:
         return static_cast<Units>(static_cast<unsigned>(a) | static_cast<unsigned>(b));
     }
 
-    static bool validUnit(CSSParserValue*, Units, bool strict);
+    bool validCalculationUnit(CSSParserValue*, Units);
+    bool validUnit(CSSParserValue*, Units, bool strict);
 
     bool parseBorderImageQuad(Units, RefPtr<CSSPrimitiveValue>&);
-
-    PassRefPtr<CSSPrimitiveValue> createPrimitiveNumericValue(CSSParserValue*);
-    PassRefPtr<CSSPrimitiveValue> createPrimitiveStringValue(CSSParserValue*);
-
+    int colorIntFromValue(CSSParserValue*);
+
+    enum ReleaseParsedCalcValueCondition {
+        ReleaseParsedCalcValue,
+        DoNotReleaseParsedCalcValue
+    };    
+    double parsedDouble(CSSParserValue*, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue);
+    bool isCalculation(CSSParserValue*);
+    
     friend class TransformOperationInfo;
 #if ENABLE(CSS_FILTERS)
     friend class FilterOperationInfo;
index 0b88f55..016cb0b 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "CSSAspectRatioValue.h"
 #include "CSSBorderImageSliceValue.h"
+#include "CSSCalculationValue.h"
 #include "CSSCanvasValue.h"
 #include "CSSCrossfadeValue.h"
 #include "CSSCursorImageValue.h"
@@ -149,6 +150,8 @@ String CSSValue::cssText() const
         return static_cast<const CSSLineBoxContainValue*>(this)->customCssText();
     case FlexClass:
         return static_cast<const CSSFlexValue*>(this)->customCssText();
+    case CalculationClass:
+        return static_cast<const CSSCalcValue*>(this)->customCssText();
 #if ENABLE(CSS_FILTERS)
     case WebKitCSSFilterClass:
         return static_cast<const WebKitCSSFilterValue*>(this)->customCssText();
@@ -249,6 +252,9 @@ void CSSValue::destroy()
     case FlexClass:
         delete static_cast<CSSFlexValue*>(this);
         return;
+    case CalculationClass:
+        delete static_cast<CSSCalcValue*>(this);
+        return;
 #if ENABLE(CSS_FILTERS)
     case WebKitCSSFilterClass:
         delete static_cast<WebKitCSSFilterValue*>(this);
index 2d33242..6123321 100644 (file)
@@ -76,6 +76,7 @@ public:
     bool isWebKitCSSTransformValue() const { return m_classType == WebKitCSSTransformClass; }
     bool isCSSLineBoxContainValue() const { return m_classType == LineBoxContainClass; }
     bool isFlexValue() const { return m_classType == FlexClass; }
+    bool isCalculationValue() const {return m_classType == CalculationClass; }
 #if ENABLE(CSS_FILTERS)
     bool isWebKitCSSFilterValue() const { return m_classType == WebKitCSSFilterClass; }
 #if ENABLE(CSS_SHADERS)
@@ -126,6 +127,7 @@ protected:
         UnicodeRangeClass,
         LineBoxContainClass,
         FlexClass,
+        CalculationClass,
 #if ENABLE(CSS_FILTERS) && ENABLE(CSS_SHADERS)
         WebKitCSSShaderClass,
 #endif
index dd738fb..2c29576 100644 (file)
@@ -314,6 +314,12 @@ bool CSSParser::parseSVGValue(int propId, bool important)
             parsedValue = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
         else if (value->unit >= CSSParserValue::Q_EMS)
             parsedValue = CSSPrimitiveValue::createAllowingMarginQuirk(value->fValue, CSSPrimitiveValue::CSS_EMS);
+        if (isCalculation(value)) {
+            // FIXME calc() http://webkit.org/b/16662 : actually create a CSSPrimitiveValue here, ie
+            // parsedValue = CSSPrimitiveValue::create(m_parsedCalculation.release());
+            m_parsedCalculation.release();
+            parsedValue = 0;
+        }
         m_valueList->next();
     }
     if (!parsedValue || (m_valueList->current() && !inShorthand()))
diff --git a/Source/WebCore/platform/CalculationValue.cpp b/Source/WebCore/platform/CalculationValue.cpp
new file mode 100755 (executable)
index 0000000..b9e3858
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2011 Google 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:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER 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 "CalculationValue.h"
+
+namespace WebCore {
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/CalculationValue.h b/Source/WebCore/platform/CalculationValue.h
new file mode 100755 (executable)
index 0000000..44a52d5
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 Google 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:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER 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 CalculationValue_h
+#define CalculationValue_h
+
+#include "Length.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+enum CalcOperator {
+    CalcAdd = '+',
+    CalcSubtract = '-',
+    CalcMultiply = '*',
+    CalcDivide = '/',
+    CalcMod = '%'
+};
+
+} // namespace WebCore
+
+#endif // CalculationValue_h