Diff
Modified: trunk/Source/WebCore/CMakeLists.txt (205367 => 205368)
--- trunk/Source/WebCore/CMakeLists.txt 2016-09-02 20:22:32 UTC (rev 205367)
+++ trunk/Source/WebCore/CMakeLists.txt 2016-09-02 20:49:27 UTC (rev 205368)
@@ -1409,6 +1409,7 @@
css/parser/CSSParser.cpp
css/parser/CSSParserFastPaths.cpp
+ css/parser/CSSParserIdioms.cpp
css/parser/CSSParserObserverWrapper.cpp
css/parser/CSSParserToken.cpp
css/parser/CSSParserTokenRange.cpp
@@ -1417,6 +1418,8 @@
css/parser/CSSPropertyParserHelpers.cpp
css/parser/CSSTokenizer.cpp
css/parser/CSSTokenizerInputStream.cpp
+ css/parser/MediaQueryBlockWatcher.cpp
+ css/parser/MediaQueryParser.cpp
css/parser/SVGCSSParser.cpp
cssjit/SelectorCompiler.cpp
Modified: trunk/Source/WebCore/ChangeLog (205367 => 205368)
--- trunk/Source/WebCore/ChangeLog 2016-09-02 20:22:32 UTC (rev 205367)
+++ trunk/Source/WebCore/ChangeLog 2016-09-02 20:49:27 UTC (rev 205368)
@@ -1,3 +1,68 @@
+2016-09-02 Dave Hyatt <[email protected]>
+
+ Add support for media query parsing using new CSS Parser
+ https://bugs.webkit.org/show_bug.cgi?id=161537
+
+ Reviewed by Dean Jackson.
+
+ * CMakeLists.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * css/MediaQueryExp.cpp:
+ (WebCore::featureWithValidIdent):
+ (WebCore::featureWithValidDensity):
+ (WebCore::featureWithValidPositiveLength):
+ (WebCore::featureWithPositiveInteger):
+ (WebCore::featureWithPositiveNumber):
+ (WebCore::featureWithZeroOrOne):
+ (WebCore::isFeatureValidWithIdentifier):
+ (WebCore::MediaQueryExpression::MediaQueryExpression):
+ * css/MediaQueryExp.h:
+ * css/parser/CSSParserIdioms.cpp: Added.
+ (WebCore::convertToASCIILowercaseInPlace):
+ * css/parser/CSSParserIdioms.h:
+ * css/parser/CSSParserToken.cpp:
+ (WebCore::convertToASCIILowercaseInPlace):
+ * css/parser/MediaQueryBlockWatcher.cpp: Added.
+ (WebCore::MediaQueryBlockWatcher::MediaQueryBlockWatcher):
+ (WebCore::MediaQueryBlockWatcher::handleToken):
+ * css/parser/MediaQueryBlockWatcher.h: Added.
+ (WebCore::MediaQueryBlockWatcher::blockLevel):
+ * css/parser/MediaQueryParser.cpp: Added.
+ (WebCore::MediaQueryParser::parseMediaQuerySet):
+ (WebCore::MediaQueryParser::parseMediaCondition):
+ (WebCore::MediaQueryParser::MediaQueryParser):
+ (WebCore::MediaQueryParser::~MediaQueryParser):
+ (WebCore::MediaQueryParser::setStateAndRestrict):
+ (WebCore::MediaQueryParser::readRestrictor):
+ (WebCore::MediaQueryParser::readMediaNot):
+ (WebCore::isRestrictorOrLogicalOperator):
+ (WebCore::MediaQueryParser::readMediaType):
+ (WebCore::MediaQueryParser::commitMediaQuery):
+ (WebCore::MediaQueryParser::readAnd):
+ (WebCore::MediaQueryParser::readFeatureStart):
+ (WebCore::MediaQueryParser::readFeature):
+ (WebCore::MediaQueryParser::readFeatureColon):
+ (WebCore::MediaQueryParser::readFeatureValue):
+ (WebCore::MediaQueryParser::readFeatureEnd):
+ (WebCore::MediaQueryParser::skipUntilComma):
+ (WebCore::MediaQueryParser::skipUntilBlockEnd):
+ (WebCore::MediaQueryParser::done):
+ (WebCore::MediaQueryParser::handleBlocks):
+ (WebCore::MediaQueryParser::processToken):
+ (WebCore::MediaQueryParser::parseInternal):
+ (WebCore::MediaQueryData::MediaQueryData):
+ (WebCore::MediaQueryData::clear):
+ (WebCore::MediaQueryData::addExpression):
+ (WebCore::MediaQueryData::tryAddParserToken):
+ (WebCore::MediaQueryData::setMediaType):
+ * css/parser/MediaQueryParser.h: Added.
+ (WebCore::MediaQueryData::restrictor):
+ (WebCore::MediaQueryData::expressions):
+ (WebCore::MediaQueryData::mediaType):
+ (WebCore::MediaQueryData::currentMediaQueryChanged):
+ (WebCore::MediaQueryData::setRestrictor):
+ (WebCore::MediaQueryData::setMediaFeature):
+
2016-07-08 Jer Noble <[email protected]>
Refactor WebPlaybackSessionModelMediaElement to be client based.
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (205367 => 205368)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2016-09-02 20:22:32 UTC (rev 205367)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2016-09-02 20:49:27 UTC (rev 205368)
@@ -3350,7 +3350,7 @@
946D373B1D6CDFC00077084F /* CSSTokenizerInputStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 946D37351D6CDF980077084F /* CSSTokenizerInputStream.cpp */; };
946D373C1D6CDFC00077084F /* CSSTokenizerInputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 946D37381D6CDF980077084F /* CSSTokenizerInputStream.h */; };
946D373F1D6CE3C20077084F /* CSSParserToken.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 946D373E1D6CE31A0077084F /* CSSParserToken.cpp */; };
- 946D37401D6CE3C20077084F /* CSSParserToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 946D373D1D6CE31A0077084F /* CSSParserToken.h */; };
+ 946D37401D6CE3C20077084F /* CSSParserToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 946D373D1D6CE31A0077084F /* CSSParserToken.h */; settings = {ATTRIBUTES = (Private, ); }; };
946D37441D6CF7B20077084F /* CSSParserIdioms.h in Headers */ = {isa = PBXBuildFile; fileRef = 946D37431D6CF7880077084F /* CSSParserIdioms.h */; };
946D37451D6D01D40077084F /* CSSPropertyParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 946D37411D6CF6320077084F /* CSSPropertyParser.cpp */; };
946D37461D6D01D40077084F /* CSSPropertyParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 946D37421D6CF6320077084F /* CSSPropertyParser.h */; };
@@ -3358,6 +3358,10 @@
946D374A1D6D06280077084F /* CSSMarkup.h in Headers */ = {isa = PBXBuildFile; fileRef = 946D37481D6D060C0077084F /* CSSMarkup.h */; };
946D374D1D6D08A60077084F /* CSSParserTokenRange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 946D374B1D6D07F50077084F /* CSSParserTokenRange.cpp */; };
946D374E1D6D08AA0077084F /* CSSParserTokenRange.h in Headers */ = {isa = PBXBuildFile; fileRef = 946D374C1D6D07F50077084F /* CSSParserTokenRange.h */; };
+ 9493B6BE1D74B4120088E780 /* MediaQueryBlockWatcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9493B6B61D74B3950088E780 /* MediaQueryBlockWatcher.cpp */; };
+ 9493B6BF1D74B4120088E780 /* MediaQueryBlockWatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 9493B6B71D74B3950088E780 /* MediaQueryBlockWatcher.h */; };
+ 9493B6C01D74B4120088E780 /* MediaQueryParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9493B6B81D74B3950088E780 /* MediaQueryParser.cpp */; };
+ 9493B6C11D74B4120088E780 /* MediaQueryParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 9493B6B91D74B3950088E780 /* MediaQueryParser.h */; };
949C77001D6E1D9800C0DE4F /* CSSParserFastPaths.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 949C76FE1D6E1D8C00C0DE4F /* CSSParserFastPaths.cpp */; };
949C77011D6E1D9800C0DE4F /* CSSParserFastPaths.h in Headers */ = {isa = PBXBuildFile; fileRef = 949C76FF1D6E1D8C00C0DE4F /* CSSParserFastPaths.h */; };
949C77041D6E39EA00C0DE4F /* CSSPropertyParserHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 949C77021D6E393500C0DE4F /* CSSPropertyParserHelpers.cpp */; };
@@ -3365,6 +3369,7 @@
949C77081D6E498700C0DE4F /* CSSParserObserverWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 949C77061D6E48ED00C0DE4F /* CSSParserObserverWrapper.cpp */; };
949C77091D6E498700C0DE4F /* CSSParserObserverWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 949C77071D6E48ED00C0DE4F /* CSSParserObserverWrapper.h */; };
949C770B1D6E49ED00C0DE4F /* CSSParserObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 949C770A1D6E49C300C0DE4F /* CSSParserObserver.h */; };
+ 94DE5C7E1D78CB2E00164F2A /* CSSParserIdioms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94DE5C7D1D78CB2500164F2A /* CSSParserIdioms.cpp */; };
96ABA42314BCB80E00D56204 /* GraphicsContext3DOpenGLCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 96ABA42214BCB80E00D56204 /* GraphicsContext3DOpenGLCommon.cpp */; };
9703E1BF15DC4E37001F24C8 /* JSVoidCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97E9EC8B15DC492F004F2E71 /* JSVoidCallback.cpp */; };
97059977107D975200A50A7C /* PolicyCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97059973107D975200A50A7C /* PolicyCallback.cpp */; };
@@ -10495,6 +10500,10 @@
946D37481D6D060C0077084F /* CSSMarkup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSMarkup.h; sourceTree = "<group>"; };
946D374B1D6D07F50077084F /* CSSParserTokenRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CSSParserTokenRange.cpp; path = parser/CSSParserTokenRange.cpp; sourceTree = "<group>"; };
946D374C1D6D07F50077084F /* CSSParserTokenRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSParserTokenRange.h; path = parser/CSSParserTokenRange.h; sourceTree = "<group>"; };
+ 9493B6B61D74B3950088E780 /* MediaQueryBlockWatcher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MediaQueryBlockWatcher.cpp; path = parser/MediaQueryBlockWatcher.cpp; sourceTree = "<group>"; };
+ 9493B6B71D74B3950088E780 /* MediaQueryBlockWatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MediaQueryBlockWatcher.h; path = parser/MediaQueryBlockWatcher.h; sourceTree = "<group>"; };
+ 9493B6B81D74B3950088E780 /* MediaQueryParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MediaQueryParser.cpp; path = parser/MediaQueryParser.cpp; sourceTree = "<group>"; };
+ 9493B6B91D74B3950088E780 /* MediaQueryParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MediaQueryParser.h; path = parser/MediaQueryParser.h; sourceTree = "<group>"; };
949C76FE1D6E1D8C00C0DE4F /* CSSParserFastPaths.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CSSParserFastPaths.cpp; path = parser/CSSParserFastPaths.cpp; sourceTree = "<group>"; };
949C76FF1D6E1D8C00C0DE4F /* CSSParserFastPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSParserFastPaths.h; path = parser/CSSParserFastPaths.h; sourceTree = "<group>"; };
949C77021D6E393500C0DE4F /* CSSPropertyParserHelpers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CSSPropertyParserHelpers.cpp; path = parser/CSSPropertyParserHelpers.cpp; sourceTree = "<group>"; };
@@ -10502,6 +10511,7 @@
949C77061D6E48ED00C0DE4F /* CSSParserObserverWrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CSSParserObserverWrapper.cpp; path = parser/CSSParserObserverWrapper.cpp; sourceTree = "<group>"; };
949C77071D6E48ED00C0DE4F /* CSSParserObserverWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSParserObserverWrapper.h; path = parser/CSSParserObserverWrapper.h; sourceTree = "<group>"; };
949C770A1D6E49C300C0DE4F /* CSSParserObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSParserObserver.h; path = parser/CSSParserObserver.h; sourceTree = "<group>"; };
+ 94DE5C7D1D78CB2500164F2A /* CSSParserIdioms.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CSSParserIdioms.cpp; path = parser/CSSParserIdioms.cpp; sourceTree = "<group>"; };
950C4C02BED8936F818E2F99 /* JSSVGGraphicsElement.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSSVGGraphicsElement.h; sourceTree = "<group>"; };
96ABA42214BCB80E00D56204 /* GraphicsContext3DOpenGLCommon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GraphicsContext3DOpenGLCommon.cpp; sourceTree = "<group>"; };
97059973107D975200A50A7C /* PolicyCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PolicyCallback.cpp; sourceTree = "<group>"; };
@@ -18138,6 +18148,7 @@
946D37291D6CB28B0077084F /* CSSParser.h */,
949C76FE1D6E1D8C00C0DE4F /* CSSParserFastPaths.cpp */,
949C76FF1D6E1D8C00C0DE4F /* CSSParserFastPaths.h */,
+ 94DE5C7D1D78CB2500164F2A /* CSSParserIdioms.cpp */,
946D37431D6CF7880077084F /* CSSParserIdioms.h */,
946D372A1D6CB28B0077084F /* CSSParserMode.h */,
949C770A1D6E49C300C0DE4F /* CSSParserObserver.h */,
@@ -18157,6 +18168,10 @@
946D37371D6CDF980077084F /* CSSTokenizer.h */,
946D37351D6CDF980077084F /* CSSTokenizerInputStream.cpp */,
946D37381D6CDF980077084F /* CSSTokenizerInputStream.h */,
+ 9493B6B61D74B3950088E780 /* MediaQueryBlockWatcher.cpp */,
+ 9493B6B71D74B3950088E780 /* MediaQueryBlockWatcher.h */,
+ 9493B6B81D74B3950088E780 /* MediaQueryParser.cpp */,
+ 9493B6B91D74B3950088E780 /* MediaQueryParser.h */,
946D37321D6CC3720077084F /* SVGCSSParser.cpp */,
);
name = parser;
@@ -25996,6 +26011,7 @@
ABDDFE7A0A5C6E7000A3E11D /* RenderMenuList.h in Headers */,
A454424F119B3687009BE912 /* RenderMeter.h in Headers */,
1A3586E015264C450022A659 /* RenderMultiColumnFlowThread.h in Headers */,
+ 9493B6C11D74B4120088E780 /* MediaQueryParser.h in Headers */,
BCE32B9C1517C0B200F542EC /* RenderMultiColumnSet.h in Headers */,
BC1A7D9818FCB5B000421879 /* RenderMultiColumnSpannerPlaceholder.h in Headers */,
8AC822FD180FC03300FB64D5 /* RenderNamedFlowFragment.h in Headers */,
@@ -26905,6 +26921,7 @@
A14832CC187F67C400DA63A6 /* WebCoreThreadRun.h in Headers */,
A14832CD187F682E00DA63A6 /* WebCoreThreadSafe.h in Headers */,
A14832CF187F684700DA63A6 /* WebCoreThreadSystemInterface.h in Headers */,
+ 9493B6BF1D74B4120088E780 /* MediaQueryBlockWatcher.h in Headers */,
0F099D0917B968A100FF84B9 /* WebCoreTypedArrayController.h in Headers */,
37F818FD0D657606005E1F05 /* WebCoreURLResponse.h in Headers */,
44A20DB90F84166C00B3E1FE /* WebCoreURLResponseIOS.h in Headers */,
@@ -27447,6 +27464,7 @@
1A8A645B1D19FCFC00D0E00F /* ApplePayShippingContactSelectedEvent.cpp in Sources */,
1A8A645F1D19FCFC00D0E00F /* ApplePayShippingMethodSelectedEvent.cpp in Sources */,
1A8A64621D19FCFC00D0E00F /* ApplePayValidateMerchantEvent.cpp in Sources */,
+ 9493B6BE1D74B4120088E780 /* MediaQueryBlockWatcher.cpp in Sources */,
1A8F6BBC0DB55CDC001DB794 /* ApplicationCache.cpp in Sources */,
1A8F6BBE0DB55CDC001DB794 /* ApplicationCacheGroup.cpp in Sources */,
24F54EAC101FE914000AE741 /* ApplicationCacheHost.cpp in Sources */,
@@ -28130,6 +28148,7 @@
499B3ED6128CD31400E726C2 /* GraphicsLayerCA.cpp in Sources */,
0FA24D79162DF91900A3F4C0 /* GraphicsLayerUpdater.cpp in Sources */,
B2A015AA0AF6CD53006BCE0E /* GraphicsTypes.cpp in Sources */,
+ 9493B6C01D74B4120088E780 /* MediaQueryParser.cpp in Sources */,
CDF7483E18FEBCEC0006ECC0 /* GridPositionsResolver.cpp in Sources */,
F55B3DBF1251F12D003EF269 /* HiddenInputType.cpp in Sources */,
515BE19B1D54F6C100DD7C68 /* HIDGamepad.cpp in Sources */,
@@ -29447,6 +29466,7 @@
8AF4E55511DC5A36000ED3DE /* PerformanceNavigation.cpp in Sources */,
86512EDE154A2AEF00A90426 /* PerformanceResourceTiming.cpp in Sources */,
0F43C85D189E10CF00019AE2 /* PerformanceTiming.cpp in Sources */,
+ 94DE5C7E1D78CB2E00164F2A /* CSSParserIdioms.cpp in Sources */,
FD581FB41520F93B003A7A75 /* PeriodicWave.cpp in Sources */,
49D5DC2D0F423A73008F20FD /* PerspectiveTransformOperation.cpp in Sources */,
D0FF2A5D11F8C45A007E74E0 /* PingLoader.cpp in Sources */,
Modified: trunk/Source/WebCore/css/MediaQueryExp.cpp (205367 => 205368)
--- trunk/Source/WebCore/css/MediaQueryExp.cpp 2016-09-02 20:22:32 UTC (rev 205367)
+++ trunk/Source/WebCore/css/MediaQueryExp.cpp 2016-09-02 20:49:27 UTC (rev 205368)
@@ -30,6 +30,8 @@
#include "CSSAspectRatioValue.h"
#include "CSSParser.h"
+#include "CSSParserIdioms.h"
+#include "CSSParserToken.h"
#include "CSSPrimitiveValue.h"
#include "CSSValueList.h"
#include "MediaFeatureNames.h"
@@ -37,23 +39,93 @@
namespace WebCore {
-static inline bool isFeatureValidWithIdentifier(const AtomicString& mediaFeature, const CSSParserValue& value)
+static inline bool featureWithValidIdent(const AtomicString& mediaFeature)
{
- if (!value.id)
- return false;
-
return mediaFeature == MediaFeatureNames::orientation
#if ENABLE(VIEW_MODE_CSS_MEDIA)
- || mediaFeature == MediaFeatureNames::viewMode
+ || mediaFeature == MediaFeatureNames::viewMode
#endif
- || mediaFeature == MediaFeatureNames::colorGamut
- || mediaFeature == MediaFeatureNames::anyHover
- || mediaFeature == MediaFeatureNames::anyPointer
- || mediaFeature == MediaFeatureNames::hover
- || mediaFeature == MediaFeatureNames::invertedColors
- || mediaFeature == MediaFeatureNames::pointer;
+ || mediaFeature == MediaFeatureNames::colorGamut
+ || mediaFeature == MediaFeatureNames::anyHover
+ || mediaFeature == MediaFeatureNames::anyPointer
+ || mediaFeature == MediaFeatureNames::hover
+ || mediaFeature == MediaFeatureNames::invertedColors
+ || mediaFeature == MediaFeatureNames::pointer;
}
+
+static inline bool featureWithValidDensity(const String& mediaFeature, const CSSParserToken& token)
+{
+ if ((token.unitType() != CSSPrimitiveValue::UnitTypes::CSS_DPPX && token.unitType() != CSSPrimitiveValue::UnitTypes::CSS_DPI && token.unitType() != CSSPrimitiveValue::UnitTypes::CSS_DPCM) || token.numericValue() <= 0)
+ return false;
+
+ return mediaFeature == MediaFeatureNames::resolution
+ || mediaFeature == MediaFeatureNames::minResolution
+ || mediaFeature == MediaFeatureNames::maxResolution;
+}
+static inline bool featureWithValidPositiveLength(const String& mediaFeature, const CSSParserToken& token)
+{
+ if (!(CSSPrimitiveValue::isLength(token.unitType()) || (token.type() == NumberToken && !token.numericValue())) || token.numericValue() < 0)
+ return false;
+
+
+ return mediaFeature == MediaFeatureNames::height
+ || mediaFeature == MediaFeatureNames::maxHeight
+ || mediaFeature == MediaFeatureNames::minHeight
+ || mediaFeature == MediaFeatureNames::width
+ || mediaFeature == MediaFeatureNames::maxWidth
+ || mediaFeature == MediaFeatureNames::minWidth
+ || mediaFeature == MediaFeatureNames::deviceHeight
+ || mediaFeature == MediaFeatureNames::maxDeviceHeight
+ || mediaFeature == MediaFeatureNames::minDeviceHeight
+ || mediaFeature == MediaFeatureNames::deviceWidth
+ || mediaFeature == MediaFeatureNames::minDeviceWidth
+ || mediaFeature == MediaFeatureNames::maxDeviceWidth;
+}
+
+static inline bool featureWithPositiveInteger(const String& mediaFeature, const CSSParserToken& token)
+{
+ if (token.numericValueType() != IntegerValueType || token.numericValue() < 0)
+ return false;
+
+ return mediaFeature == MediaFeatureNames::color
+ || mediaFeature == MediaFeatureNames:: maxColor
+ || mediaFeature == MediaFeatureNames:: minColor
+ || mediaFeature == MediaFeatureNames::colorIndex
+ || mediaFeature == MediaFeatureNames::maxColorIndex
+ || mediaFeature == MediaFeatureNames::minColorIndex
+ || mediaFeature == MediaFeatureNames::monochrome
+ || mediaFeature == MediaFeatureNames::maxMonochrome
+ || mediaFeature == MediaFeatureNames::minMonochrome;
+}
+
+static inline bool featureWithPositiveNumber(const String& mediaFeature, const CSSParserToken& token)
+{
+ if (token.type() != NumberToken || token.numericValue() < 0)
+ return false;
+
+ return mediaFeature == MediaFeatureNames::transform3d
+ || mediaFeature == MediaFeatureNames::devicePixelRatio
+ || mediaFeature == MediaFeatureNames::maxDevicePixelRatio
+ || mediaFeature == MediaFeatureNames::minDevicePixelRatio;
+}
+
+static inline bool featureWithZeroOrOne(const String& mediaFeature, const CSSParserToken& token)
+{
+ if (token.numericValueType() != IntegerValueType || !(token.numericValue() == 1 || !token.numericValue()))
+ return false;
+
+ return mediaFeature == MediaFeatureNames::grid;
+}
+
+static inline bool isFeatureValidWithIdentifier(const AtomicString& mediaFeature, CSSValueID id)
+{
+ if (!id)
+ return false;
+
+ return featureWithValidIdent(mediaFeature);
+}
+
static inline bool isFeatureValidWithNonNegativeLengthOrNumber(const AtomicString& mediaFeature, const CSSParserValue& value)
{
if (!(CSSPrimitiveValue::isLength(value.unit) || value.unit == CSSPrimitiveValue::CSS_NUMBER) || value.fValue < 0)
@@ -189,7 +261,7 @@
m_isValid = true;
} else if (valueList->size() == 1) {
auto& value = *valueList->valueAt(0);
- if (isFeatureValidWithIdentifier(mediaFeature, value)) {
+ if (isFeatureValidWithIdentifier(mediaFeature, value.id)) {
m_value = CSSPrimitiveValue::createIdentifier(value.id);
m_isValid = true;
} else if (isFeatureValidWithNumberWithUnit(mediaFeature, value) || isFeatureValidWithNonNegativeLengthOrNumber(mediaFeature, value)) {
@@ -211,6 +283,59 @@
}
}
+MediaQueryExpression::MediaQueryExpression(const String& feature, const Vector<CSSParserToken, 4>& tokenList)
+ : m_mediaFeature(feature)
+ , m_isValid(false)
+{
+ // Create value for media query _expression_ that must have 1 or more values.
+ if (!tokenList.size() && isFeatureValidWithoutValue(m_mediaFeature)) {
+ // Valid, creates a MediaQueryExp with an 'invalid' MediaQueryExpValue
+ m_isValid = true;
+ } else if (tokenList.size() == 1) {
+ CSSParserToken token = tokenList.first();
+ if (token.type() == IdentToken) {
+ CSSValueID ident = token.id();
+ if (!featureWithValidIdent(m_mediaFeature))
+ return;
+ m_value = CSSPrimitiveValue::createIdentifier(ident);
+ m_isValid = true;
+ } else if (token.type() == NumberToken || token.type() == PercentageToken || token.type() == DimensionToken) {
+ // Check for numeric token types since it is only safe for these types to call numericValue.
+ if (featureWithValidDensity(m_mediaFeature, token)
+ || featureWithValidPositiveLength(m_mediaFeature, token)) {
+ // Media features that must have non-negative <density>, ie. dppx, dpi or dpcm,
+ // or Media features that must have non-negative <length> or number value.
+ m_value = CSSPrimitiveValue::create(token.numericValue(), (CSSPrimitiveValue::UnitTypes) token.unitType());
+ m_isValid = true;
+ } else if (featureWithPositiveInteger(m_mediaFeature, token)
+ || featureWithPositiveNumber(m_mediaFeature, token)
+ || featureWithZeroOrOne(m_mediaFeature, token)) {
+ // Media features that must have non-negative integer value,
+ // or media features that must have non-negative number value,
+ // or media features that must have (0|1) value.
+ m_value = CSSPrimitiveValue::create(token.numericValue(), CSSPrimitiveValue::UnitTypes::CSS_NUMBER);
+ m_isValid = true;
+ }
+ }
+ } else if (tokenList.size() == 3 && isAspectRatioFeature(m_mediaFeature)) {
+ // FIXME: <ratio> is supposed to allow whitespace around the '/'
+ // Applicable to device-aspect-ratio and aspect-ratio.
+ const CSSParserToken& numerator = tokenList[0];
+ const CSSParserToken& delimiter = tokenList[1];
+ const CSSParserToken& denominator = tokenList[2];
+ if (delimiter.type() != DelimiterToken || delimiter.delimiter() != '/')
+ return;
+ if (numerator.type() != NumberToken || numerator.numericValue() <= 0 || numerator.numericValueType() != IntegerValueType)
+ return;
+ if (denominator.type() != NumberToken || denominator.numericValue() <= 0 || denominator.numericValueType() != IntegerValueType)
+ return;
+
+ m_value = CSSAspectRatioValue::create(numerator.numericValue(), denominator.numericValue());
+ m_isValid = true;
+
+ }
+}
+
String MediaQueryExpression::serialize() const
{
if (!m_serializationCache.isNull())
Modified: trunk/Source/WebCore/css/MediaQueryExp.h (205367 => 205368)
--- trunk/Source/WebCore/css/MediaQueryExp.h 2016-09-02 20:22:32 UTC (rev 205367)
+++ trunk/Source/WebCore/css/MediaQueryExp.h 2016-09-02 20:49:27 UTC (rev 205368)
@@ -27,6 +27,7 @@
#pragma once
+#include "CSSParserToken.h"
#include "CSSValue.h"
#include <memory>
@@ -39,6 +40,7 @@
WTF_MAKE_FAST_ALLOCATED;
public:
explicit MediaQueryExpression(const AtomicString& mediaFeature = emptyAtom, CSSParserValueList* values = nullptr);
+ explicit MediaQueryExpression(const String& mediaFeature, const Vector<CSSParserToken, 4>& tokenList);
const AtomicString& mediaFeature() const;
CSSValue* value() const;
Added: trunk/Source/WebCore/css/parser/CSSParserIdioms.cpp (0 => 205368)
--- trunk/Source/WebCore/css/parser/CSSParserIdioms.cpp (rev 0)
+++ trunk/Source/WebCore/css/parser/CSSParserIdioms.cpp 2016-09-02 20:49:27 UTC (rev 205368)
@@ -0,0 +1,51 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Copyright (C) 2016 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:
+//
+// * 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 "CSSParserIdioms.h"
+
+namespace WebCore {
+
+template<typename CharacterType> ALWAYS_INLINE static void convertToASCIILowercaseInPlace(CharacterType* characters, unsigned length)
+{
+ for (unsigned i = 0; i < length; ++i)
+ characters[i] = toASCIILower(characters[i]);
+}
+
+// FIXME-NEWPARSER: Would like to get rid of this operation. Blink uses HTMLParser static lowercase
+// string hashing, but we don't have that code in our HTMLParser.
+void convertToASCIILowercaseInPlace(StringView& stringView)
+{
+ if (stringView.is8Bit())
+ WebCore::convertToASCIILowercaseInPlace(const_cast<LChar*>(stringView.characters8()), stringView.length());
+ else
+ WebCore::convertToASCIILowercaseInPlace(const_cast<UChar*>(stringView.characters16()), stringView.length());
+}
+
+} // namespace WebCore
Modified: trunk/Source/WebCore/css/parser/CSSParserIdioms.h (205367 => 205368)
--- trunk/Source/WebCore/css/parser/CSSParserIdioms.h 2016-09-02 20:22:32 UTC (rev 205367)
+++ trunk/Source/WebCore/css/parser/CSSParserIdioms.h 2016-09-02 20:49:27 UTC (rev 205368)
@@ -33,6 +33,7 @@
#define CSSParserIdioms_h
#include <wtf/ASCIICType.h>
+#include <wtf/text/StringView.h>
namespace WebCore {
@@ -57,6 +58,8 @@
return isNameStartCodePoint(c) || isASCIIDigit(c) || c == '-';
}
+void convertToASCIILowercaseInPlace(StringView&);
+
}
#endif
Added: trunk/Source/WebCore/css/parser/MediaQueryBlockWatcher.cpp (0 => 205368)
--- trunk/Source/WebCore/css/parser/MediaQueryBlockWatcher.cpp (rev 0)
+++ trunk/Source/WebCore/css/parser/MediaQueryBlockWatcher.cpp 2016-09-02 20:49:27 UTC (rev 205368)
@@ -0,0 +1,51 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Copyright (C) 2016 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:
+//
+// * 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 "MediaQueryBlockWatcher.h"
+
+#include "CSSParserToken.h"
+
+namespace WebCore {
+
+MediaQueryBlockWatcher::MediaQueryBlockWatcher()
+{
+}
+
+void MediaQueryBlockWatcher::handleToken(const CSSParserToken& token)
+{
+ if (token.getBlockType() == CSSParserToken::BlockStart)
+ ++m_blockLevel;
+ else if (token.getBlockType() == CSSParserToken::BlockEnd) {
+ ASSERT(m_blockLevel);
+ --m_blockLevel;
+ }
+}
+
+} // namespace WebCore
Added: trunk/Source/WebCore/css/parser/MediaQueryBlockWatcher.h (0 => 205368)
--- trunk/Source/WebCore/css/parser/MediaQueryBlockWatcher.h (rev 0)
+++ trunk/Source/WebCore/css/parser/MediaQueryBlockWatcher.h 2016-09-02 20:49:27 UTC (rev 205368)
@@ -0,0 +1,49 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Copyright (C) 2016 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:
+//
+// * 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 MediaQueryBlockWatcher_h
+#define MediaQueryBlockWatcher_h
+
+namespace WebCore {
+
+class CSSParserToken;
+
+class MediaQueryBlockWatcher {
+public:
+ MediaQueryBlockWatcher();
+ void handleToken(const CSSParserToken&);
+ unsigned blockLevel() const { return m_blockLevel; }
+
+private:
+ unsigned m_blockLevel { 0 };
+};
+
+} // namespace WebCore
+
+#endif // MediaQueryBlockWatcher_h
Added: trunk/Source/WebCore/css/parser/MediaQueryParser.cpp (0 => 205368)
--- trunk/Source/WebCore/css/parser/MediaQueryParser.cpp (rev 0)
+++ trunk/Source/WebCore/css/parser/MediaQueryParser.cpp 2016-09-02 20:49:27 UTC (rev 205368)
@@ -0,0 +1,312 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Copyright (C) 2016 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:
+//
+// * 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 "MediaQueryParser.h"
+
+#include "CSSParserIdioms.h"
+#include "CSSTokenizer.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+RefPtr<MediaQuerySet> MediaQueryParser::parseMediaQuerySet(const String& queryString)
+{
+ return parseMediaQuerySet(CSSTokenizer::Scope(queryString).tokenRange());
+}
+
+RefPtr<MediaQuerySet> MediaQueryParser::parseMediaQuerySet(CSSParserTokenRange range)
+{
+ return MediaQueryParser(MediaQuerySetParser).parseInternal(range);
+}
+
+RefPtr<MediaQuerySet> MediaQueryParser::parseMediaCondition(CSSParserTokenRange range)
+{
+ return MediaQueryParser(MediaConditionParser).parseInternal(range);
+}
+
+const MediaQueryParser::State MediaQueryParser::ReadRestrictor = &MediaQueryParser::readRestrictor;
+const MediaQueryParser::State MediaQueryParser::ReadMediaNot = &MediaQueryParser::readMediaNot;
+const MediaQueryParser::State MediaQueryParser::ReadMediaType = &MediaQueryParser::readMediaType;
+const MediaQueryParser::State MediaQueryParser::ReadAnd = &MediaQueryParser::readAnd;
+const MediaQueryParser::State MediaQueryParser::ReadFeatureStart = &MediaQueryParser::readFeatureStart;
+const MediaQueryParser::State MediaQueryParser::ReadFeature = &MediaQueryParser::readFeature;
+const MediaQueryParser::State MediaQueryParser::ReadFeatureColon = &MediaQueryParser::readFeatureColon;
+const MediaQueryParser::State MediaQueryParser::ReadFeatureValue = &MediaQueryParser::readFeatureValue;
+const MediaQueryParser::State MediaQueryParser::ReadFeatureEnd = &MediaQueryParser::readFeatureEnd;
+const MediaQueryParser::State MediaQueryParser::SkipUntilComma = &MediaQueryParser::skipUntilComma;
+const MediaQueryParser::State MediaQueryParser::SkipUntilBlockEnd = &MediaQueryParser::skipUntilBlockEnd;
+const MediaQueryParser::State MediaQueryParser::Done = &MediaQueryParser::done;
+
+MediaQueryParser::MediaQueryParser(ParserType parserType)
+ : m_parserType(parserType)
+ , m_querySet(MediaQuerySet::create())
+{
+ if (parserType == MediaQuerySetParser)
+ m_state = &MediaQueryParser::readRestrictor;
+ else // MediaConditionParser
+ m_state = &MediaQueryParser::readMediaNot;
+}
+
+MediaQueryParser::~MediaQueryParser() { }
+
+void MediaQueryParser::setStateAndRestrict(State state, MediaQuery::Restrictor restrictor)
+{
+ m_mediaQueryData.setRestrictor(restrictor);
+ m_state = state;
+}
+
+// State machine member functions start here
+void MediaQueryParser::readRestrictor(CSSParserTokenType type, const CSSParserToken& token)
+{
+ readMediaType(type, token);
+}
+
+void MediaQueryParser::readMediaNot(CSSParserTokenType type, const CSSParserToken& token)
+{
+ if (type == IdentToken && equalIgnoringASCIICase(token.value(), "not"))
+ setStateAndRestrict(ReadFeatureStart, MediaQuery::Not);
+ else
+ readFeatureStart(type, token);
+}
+
+static bool isRestrictorOrLogicalOperator(const CSSParserToken& token)
+{
+ // FIXME: it would be more efficient to use lower-case always for tokenValue.
+ return equalIgnoringASCIICase(token.value(), "not")
+ || equalIgnoringASCIICase(token.value(), "and")
+ || equalIgnoringASCIICase(token.value(), "or")
+ || equalIgnoringASCIICase(token.value(), "only");
+}
+
+void MediaQueryParser::readMediaType(CSSParserTokenType type, const CSSParserToken& token)
+{
+ if (type == LeftParenthesisToken) {
+ if (m_mediaQueryData.restrictor() != MediaQuery::None)
+ m_state = SkipUntilComma;
+ else
+ m_state = ReadFeature;
+ } else if (type == IdentToken) {
+ if (m_state == ReadRestrictor && equalIgnoringASCIICase(token.value(), "not"))
+ setStateAndRestrict(ReadMediaType, MediaQuery::Not);
+ else if (m_state == ReadRestrictor && equalIgnoringASCIICase(token.value(), "only"))
+ setStateAndRestrict(ReadMediaType, MediaQuery::Only);
+ else if (m_mediaQueryData.restrictor() != MediaQuery::None
+ && isRestrictorOrLogicalOperator(token)) {
+ m_state = SkipUntilComma;
+ } else {
+ StringView stringView = token.value();
+ convertToASCIILowercaseInPlace(stringView);
+ m_mediaQueryData.setMediaType(stringView.toString());
+ m_state = ReadAnd;
+ }
+ } else if (type == EOFToken && (!m_querySet->queryVector().size() || m_state != ReadRestrictor))
+ m_state = Done;
+ else {
+ m_state = SkipUntilComma;
+ if (type == CommaToken)
+ skipUntilComma(type, token);
+ }
+}
+
+void MediaQueryParser::commitMediaQuery()
+{
+ // FIXME-NEWPARSER: Convoluted and awful, but we can't change the MediaQuerySet yet because of the
+ // old parser.
+ MediaQuery mediaQuery = MediaQuery(m_mediaQueryData.restrictor(), m_mediaQueryData.mediaType(), WTFMove(m_mediaQueryData.expressions()));
+ m_mediaQueryData.clear();
+ m_querySet->addMediaQuery(WTFMove(mediaQuery));
+}
+
+void MediaQueryParser::readAnd(CSSParserTokenType type, const CSSParserToken& token)
+{
+ if (type == IdentToken && equalIgnoringASCIICase(token.value(), "and")) {
+ m_state = ReadFeatureStart;
+ } else if (type == CommaToken && m_parserType != MediaConditionParser) {
+ commitMediaQuery();
+ m_state = ReadRestrictor;
+ } else if (type == EOFToken)
+ m_state = Done;
+ else
+ m_state = SkipUntilComma;
+}
+
+void MediaQueryParser::readFeatureStart(CSSParserTokenType type, const CSSParserToken& /*token*/)
+{
+ if (type == LeftParenthesisToken)
+ m_state = ReadFeature;
+ else
+ m_state = SkipUntilComma;
+}
+
+void MediaQueryParser::readFeature(CSSParserTokenType type, const CSSParserToken& token)
+{
+ if (type == IdentToken) {
+ m_mediaQueryData.setMediaFeature(token.value().toString());
+ m_state = ReadFeatureColon;
+ } else
+ m_state = SkipUntilComma;
+}
+
+void MediaQueryParser::readFeatureColon(CSSParserTokenType type, const CSSParserToken& token)
+{
+ if (type == ColonToken)
+ m_state = ReadFeatureValue;
+ else if (type == RightParenthesisToken || type == EOFToken)
+ readFeatureEnd(type, token);
+ else
+ m_state = SkipUntilBlockEnd;
+}
+
+void MediaQueryParser::readFeatureValue(CSSParserTokenType type, const CSSParserToken& token)
+{
+ if (type == DimensionToken && token.unitType() == CSSPrimitiveValue::UnitTypes::CSS_UNKNOWN)
+ m_state = SkipUntilComma;
+ else {
+ if (m_mediaQueryData.tryAddParserToken(type, token))
+ m_state = ReadFeatureEnd;
+ else
+ m_state = SkipUntilBlockEnd;
+ }
+}
+
+void MediaQueryParser::readFeatureEnd(CSSParserTokenType type, const CSSParserToken& token)
+{
+ if (type == RightParenthesisToken || type == EOFToken) {
+ if (m_mediaQueryData.addExpression())
+ m_state = ReadAnd;
+ else
+ m_state = SkipUntilComma;
+ } else if (type == DelimiterToken && token.delimiter() == '/') {
+ m_mediaQueryData.tryAddParserToken(type, token);
+ m_state = ReadFeatureValue;
+ } else
+ m_state = SkipUntilBlockEnd;
+}
+
+void MediaQueryParser::skipUntilComma(CSSParserTokenType type, const CSSParserToken& /*token*/)
+{
+ if ((type == CommaToken && !m_blockWatcher.blockLevel()) || type == EOFToken) {
+ m_state = ReadRestrictor;
+ m_mediaQueryData.clear();
+ MediaQuery query = MediaQuery(MediaQuery::None, "all", Vector<MediaQueryExpression>());
+ m_querySet->addMediaQuery(WTFMove(query));
+ }
+}
+
+void MediaQueryParser::skipUntilBlockEnd(CSSParserTokenType /*type */, const CSSParserToken& token)
+{
+ if (token.getBlockType() == CSSParserToken::BlockEnd && !m_blockWatcher.blockLevel())
+ m_state = SkipUntilComma;
+}
+
+void MediaQueryParser::done(CSSParserTokenType /*type*/, const CSSParserToken& /*token*/) { }
+
+void MediaQueryParser::handleBlocks(const CSSParserToken& token)
+{
+ if (token.getBlockType() == CSSParserToken::BlockStart
+ && (token.type() != LeftParenthesisToken || m_blockWatcher.blockLevel()))
+ m_state = SkipUntilBlockEnd;
+}
+
+void MediaQueryParser::processToken(const CSSParserToken& token)
+{
+ CSSParserTokenType type = token.type();
+
+ handleBlocks(token);
+ m_blockWatcher.handleToken(token);
+
+ // Call the function that handles current state
+ if (type != WhitespaceToken)
+ ((this)->*(m_state))(type, token);
+}
+
+// The state machine loop
+RefPtr<MediaQuerySet> MediaQueryParser::parseInternal(CSSParserTokenRange range)
+{
+ while (!range.atEnd())
+ processToken(range.consume());
+
+ // FIXME: Can we get rid of this special case?
+ if (m_parserType == MediaQuerySetParser)
+ processToken(CSSParserToken(EOFToken));
+
+ if (m_state != ReadAnd && m_state != ReadRestrictor && m_state != Done && m_state != ReadMediaNot) {
+ MediaQuery query = MediaQuery(MediaQuery::None, "all", Vector<MediaQueryExpression>());
+ m_querySet->addMediaQuery(WTFMove(query));
+ } else if (m_mediaQueryData.currentMediaQueryChanged())
+ commitMediaQuery();
+
+ return m_querySet;
+}
+
+MediaQueryData::MediaQueryData()
+ : m_restrictor(MediaQuery::None)
+ , m_mediaType("all")
+ , m_mediaTypeSet(false)
+{
+}
+
+void MediaQueryData::clear()
+{
+ m_restrictor = MediaQuery::None;
+ m_mediaType = "all";
+ m_mediaTypeSet = false;
+ m_mediaFeature = String();
+ m_valueList.clear();
+ m_expressions.clear();
+}
+
+bool MediaQueryData::addExpression()
+{
+ MediaQueryExpression _expression_ = MediaQueryExpression(m_mediaFeature, m_valueList);
+ bool isValid = _expression_.isValid();
+ m_expressions.append(WTFMove(_expression_));
+ m_valueList.clear();
+ return isValid;
+}
+
+bool MediaQueryData::tryAddParserToken(CSSParserTokenType type, const CSSParserToken& token)
+{
+ if (type == NumberToken || type == PercentageToken || type == DimensionToken
+ || type == DelimiterToken || type == IdentToken) {
+ m_valueList.append(token);
+ return true;
+ }
+
+ return false;
+}
+
+void MediaQueryData::setMediaType(const String& mediaType)
+{
+ m_mediaType = mediaType;
+ m_mediaTypeSet = true;
+}
+
+} // namespace WebCsore
Added: trunk/Source/WebCore/css/parser/MediaQueryParser.h (0 => 205368)
--- trunk/Source/WebCore/css/parser/MediaQueryParser.h (rev 0)
+++ trunk/Source/WebCore/css/parser/MediaQueryParser.h 2016-09-02 20:49:27 UTC (rev 205368)
@@ -0,0 +1,140 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Copyright (C) 2016 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:
+//
+// * 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 MediaQueryParser_h
+#define MediaQueryParser_h
+
+#include "CSSParserToken.h"
+#include "CSSParserTokenRange.h"
+#include "MediaList.h"
+#include "MediaQuery.h"
+#include "MediaQueryBlockWatcher.h"
+#include "MediaQueryExp.h"
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class MediaQuerySet;
+
+class MediaQueryData {
+ WTF_MAKE_NONCOPYABLE(MediaQueryData);
+public:
+ MediaQueryData();
+ void clear();
+ bool addExpression();
+ bool tryAddParserToken(CSSParserTokenType, const CSSParserToken&);
+ void setMediaType(const String&);
+
+ MediaQuery::Restrictor restrictor() const { return m_restrictor; };
+ Vector<MediaQueryExpression>& expressions() { return m_expressions; }
+ String mediaType() const { return m_mediaType; }
+
+ inline bool currentMediaQueryChanged() const
+ {
+ return (m_restrictor != MediaQuery::None || m_mediaTypeSet || m_expressions.size() > 0);
+ }
+ inline MediaQuery::Restrictor restrictor() { return m_restrictor; }
+
+ inline void setRestrictor(MediaQuery::Restrictor restrictor) { m_restrictor = restrictor; }
+
+ inline void setMediaFeature(const String& str) { m_mediaFeature = str; }
+
+private:
+ MediaQuery::Restrictor m_restrictor;
+ String m_mediaType;
+ Vector<MediaQueryExpression> m_expressions;
+ String m_mediaFeature;
+ Vector<CSSParserToken, 4> m_valueList;
+ bool m_mediaTypeSet;
+};
+
+class MediaQueryParser {
+ WTF_MAKE_NONCOPYABLE(MediaQueryParser);
+public:
+ static RefPtr<MediaQuerySet> parseMediaQuerySet(const String&);
+ static RefPtr<MediaQuerySet> parseMediaQuerySet(CSSParserTokenRange);
+ static RefPtr<MediaQuerySet> parseMediaCondition(CSSParserTokenRange);
+
+private:
+ enum ParserType {
+ MediaQuerySetParser,
+ MediaConditionParser,
+ };
+
+ MediaQueryParser(ParserType);
+ virtual ~MediaQueryParser();
+
+ RefPtr<MediaQuerySet> parseInternal(CSSParserTokenRange);
+
+ void processToken(const CSSParserToken&);
+
+ void readRestrictor(CSSParserTokenType, const CSSParserToken&);
+ void readMediaNot(CSSParserTokenType, const CSSParserToken&);
+ void readMediaType(CSSParserTokenType, const CSSParserToken&);
+ void readAnd(CSSParserTokenType, const CSSParserToken&);
+ void readFeatureStart(CSSParserTokenType, const CSSParserToken&);
+ void readFeature(CSSParserTokenType, const CSSParserToken&);
+ void readFeatureColon(CSSParserTokenType, const CSSParserToken&);
+ void readFeatureValue(CSSParserTokenType, const CSSParserToken&);
+ void readFeatureEnd(CSSParserTokenType, const CSSParserToken&);
+ void skipUntilComma(CSSParserTokenType, const CSSParserToken&);
+ void skipUntilBlockEnd(CSSParserTokenType, const CSSParserToken&);
+ void done(CSSParserTokenType, const CSSParserToken&);
+
+ using State = void (MediaQueryParser::*)(CSSParserTokenType, const CSSParserToken&);
+
+ void setStateAndRestrict(State, MediaQuery::Restrictor);
+ void handleBlocks(const CSSParserToken&);
+
+ void commitMediaQuery();
+
+ State m_state;
+ ParserType m_parserType;
+ MediaQueryData m_mediaQueryData;
+ RefPtr<MediaQuerySet> m_querySet;
+ MediaQueryBlockWatcher m_blockWatcher;
+
+ const static State ReadRestrictor;
+ const static State ReadMediaNot;
+ const static State ReadMediaType;
+ const static State ReadAnd;
+ const static State ReadFeatureStart;
+ const static State ReadFeature;
+ const static State ReadFeatureColon;
+ const static State ReadFeatureValue;
+ const static State ReadFeatureEnd;
+ const static State SkipUntilComma;
+ const static State SkipUntilBlockEnd;
+ const static State Done;
+
+};
+
+} // namespace WebCore
+
+#endif // MediaQueryParser_h