Diff
Modified: trunk/Source/WebCore/CMakeLists.txt (205659 => 205660)
--- trunk/Source/WebCore/CMakeLists.txt 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/CMakeLists.txt 2016-09-08 21:09:04 UTC (rev 205660)
@@ -1359,6 +1359,7 @@
css/parser/CSSParserValues.cpp
css/parser/CSSPropertyParser.cpp
css/parser/CSSPropertyParserHelpers.cpp
+ css/parser/CSSSelectorParser.cpp
css/parser/CSSTokenizer.cpp
css/parser/CSSTokenizerInputStream.cpp
css/parser/MediaQueryBlockWatcher.cpp
Modified: trunk/Source/WebCore/ChangeLog (205659 => 205660)
--- trunk/Source/WebCore/ChangeLog 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/ChangeLog 2016-09-08 21:09:04 UTC (rev 205660)
@@ -1,3 +1,127 @@
+2016-09-08 Dave Hyatt <[email protected]>
+
+ [CSS Parser] Add support for new CSS selector parsing
+ https://bugs.webkit.org/show_bug.cgi?id=161749
+
+ Reviewed by Dean Jackson.
+
+ * CMakeLists.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * contentextensions/ContentExtensionParser.cpp:
+ (WebCore::ContentExtensions::isValidSelector):
+ * css/CSSDefaultStyleSheets.cpp:
+ (WebCore::parseUASheet):
+ * css/CSSFontFaceSet.cpp:
+ (WebCore::CSSFontFaceSet::matchingFaces):
+ * css/CSSGrammar.y.in:
+ * css/CSSSelector.cpp:
+ (WebCore::CSSSelector::selectorText):
+ * css/CSSSelector.h:
+ * css/DOMCSSNamespace.cpp:
+ (WebCore::DOMCSSNamespace::supports):
+ * css/FontFace.cpp:
+ (WebCore::FontFace::parseString):
+ (WebCore::FontFace::setVariant):
+ * css/MediaList.cpp:
+ (WebCore::MediaQuerySet::internalParse):
+ (WebCore::MediaQuerySet::parse):
+ * css/SelectorChecker.cpp:
+ (WebCore::SelectorChecker::matchRecursively):
+ * css/SelectorFilter.cpp:
+ (WebCore::SelectorFilter::collectIdentifierHashes):
+ * css/SelectorPseudoClassAndCompatibilityElementMap.in:
+ * css/SelectorPseudoTypeMap.h:
+ * css/SourceSizeList.cpp:
+ (WebCore::parseSizesAttribute):
+ * css/StyleProperties.cpp:
+ (WebCore::MutableStyleProperties::MutableStyleProperties):
+ * css/StyleProperties.h:
+ * css/StyleRuleImport.cpp:
+ (WebCore::StyleRuleImport::setCSSStyleSheet):
+ * css/StyleSheetContents.cpp:
+ (WebCore::StyleSheetContents::StyleSheetContents):
+ (WebCore::StyleSheetContents::parserAddNamespace):
+ (WebCore::StyleSheetContents::namespaceURIFromPrefix):
+ (WebCore::StyleSheetContents::determineNamespace): Deleted.
+ * css/StyleSheetContents.h:
+ * css/WebKitCSSMatrix.cpp:
+ (WebCore::WebKitCSSMatrix::setMatrixValue):
+ * css/makeSelectorPseudoClassAndCompatibilityElementMap.py:
+ * css/parser/CSSParser.cpp:
+ (WebCore::strictCSSParserContext):
+ (WebCore::CSSParserContext::CSSParserContext):
+ (WebCore::CSSParser::parseColor):
+ (WebCore::CSSParser::shouldAcceptUnitLessValues):
+ (WebCore::CSSParser::parseValue):
+ (WebCore::CSSParser::parseColumnWidth):
+ (WebCore::CSSParser::parseColumnCount):
+ (WebCore::CSSParser::parseFontWeight):
+ (WebCore::CSSParser::parseColorParameters):
+ (WebCore::CSSParser::parseHSLParameters):
+ (WebCore::CSSParser::parseShadow):
+ (WebCore::CSSParser::parseBorderImageSlice):
+ (WebCore::CSSParser::parseBorderImageQuad):
+ (WebCore::CSSParser::parseDeprecatedLinearGradient):
+ (WebCore::CSSParser::parseLinearGradient):
+ (WebCore::CSSParser::parseTransformValue):
+ (WebCore::CSSParser::parseBuiltinFilterArguments):
+ (WebCore::CSSParser::determineNameInNamespace):
+ * css/parser/CSSParser.h:
+ (WebCore::CSSParser::inStrictMode):
+ (WebCore::CSSParser::inQuirksMode):
+ * css/parser/CSSParserMode.h:
+ (WebCore::isQuirksModeBehavior):
+ (WebCore::isUASheetBehavior):
+ (WebCore::isUnitLessLengthParsingEnabledForMode):
+ (WebCore::isCSSViewportParsingEnabledForMode):
+ (WebCore::strictToCSSParserMode):
+ (WebCore::isStrictParserMode):
+ * css/parser/CSSParserValues.cpp:
+ (WebCore::CSSParserSelector::parsePseudoElementSelectorFromStringView):
+ (WebCore::CSSParserSelector::parsePseudoClassSelectorFromStringView):
+ (WebCore::CSSParserSelector::setSelectorList):
+ (WebCore::CSSParserSelector::appendTagHistory):
+ (WebCore::CSSParserSelector::releaseTagHistory):
+ (WebCore::CSSParserSelector::isHostPseudoSelector):
+ * css/parser/CSSParserValues.h:
+ (WebCore::CSSParserSelector::match):
+ (WebCore::CSSParserSelector::pseudoElementType):
+ (WebCore::CSSParserSelector::selectorList):
+ (WebCore::CSSParserSelector::needsImplicitShadowCombinatorForMatching):
+ * css/parser/CSSPropertyParser.h:
+ (WebCore::CSSPropertyParser::inQuirksMode):
+ * css/parser/CSSSelectorParser.cpp: Added.
+ (WebCore::CSSSelectorParser::parseSelector):
+ (WebCore::CSSSelectorParser::CSSSelectorParser):
+ (WebCore::CSSSelectorParser::consumeComplexSelectorList):
+ (WebCore::CSSSelectorParser::consumeCompoundSelectorList):
+ (WebCore::CSSSelectorParser::consumeComplexSelector):
+ (WebCore::CSSSelectorParser::consumeCompoundSelector):
+ (WebCore::CSSSelectorParser::consumeSimpleSelector):
+ (WebCore::CSSSelectorParser::consumeName):
+ (WebCore::CSSSelectorParser::consumeId):
+ (WebCore::CSSSelectorParser::consumeClass):
+ (WebCore::CSSSelectorParser::consumeAttribute):
+ (WebCore::CSSSelectorParser::consumePseudo):
+ (WebCore::CSSSelectorParser::consumeCombinator):
+ (WebCore::CSSSelectorParser::consumeAttributeMatch):
+ (WebCore::CSSSelectorParser::consumeAttributeFlags):
+ (WebCore::CSSSelectorParser::consumeANPlusB):
+ (WebCore::CSSSelectorParser::defaultNamespace):
+ (WebCore::CSSSelectorParser::determineNamespace):
+ (WebCore::CSSSelectorParser::prependTypeSelectorIfNeeded):
+ (WebCore::CSSSelectorParser::addSimpleSelectorToCompound):
+ (WebCore::CSSSelectorParser::splitCompoundAtImplicitShadowCrossingCombinator):
+ * css/parser/CSSSelectorParser.h: Added.
+ (WebCore::CSSSelectorParser::DisallowPseudoElementsScope::DisallowPseudoElementsScope):
+ (WebCore::CSSSelectorParser::DisallowPseudoElementsScope::~DisallowPseudoElementsScope):
+ * cssjit/SelectorCompiler.cpp:
+ (WebCore::SelectorCompiler::fragmentRelationForSelectorRelation):
+ * dom/StyledElement.cpp:
+ (WebCore::StyledElement::rebuildPresentationAttributeStyle):
+ * svg/SVGFontFaceElement.cpp:
+ (WebCore::SVGFontFaceElement::SVGFontFaceElement):
+
2016-09-08 Simon Fraser <[email protected]>
Don't run transitions to or from undefined Lengths
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (205659 => 205660)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2016-09-08 21:09:04 UTC (rev 205660)
@@ -3374,6 +3374,8 @@
94DE5C7E1D78CB2E00164F2A /* CSSParserIdioms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94DE5C7D1D78CB2500164F2A /* CSSParserIdioms.cpp */; };
94DE5C811D7F3A1400164F2A /* CSSAtRuleID.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94DE5C7F1D7F39D000164F2A /* CSSAtRuleID.cpp */; };
94DE5C821D7F3A1400164F2A /* CSSAtRuleID.h in Headers */ = {isa = PBXBuildFile; fileRef = 94DE5C801D7F39D000164F2A /* CSSAtRuleID.h */; };
+ 94DE5C8D1D80802700164F2A /* CSSSelectorParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94DE5C8B1D80801500164F2A /* CSSSelectorParser.cpp */; };
+ 94DE5C8E1D80802700164F2A /* CSSSelectorParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 94DE5C8C1D80801500164F2A /* CSSSelectorParser.h */; };
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 */; };
@@ -10525,6 +10527,8 @@
94DE5C7D1D78CB2500164F2A /* CSSParserIdioms.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CSSParserIdioms.cpp; path = parser/CSSParserIdioms.cpp; sourceTree = "<group>"; };
94DE5C7F1D7F39D000164F2A /* CSSAtRuleID.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CSSAtRuleID.cpp; path = parser/CSSAtRuleID.cpp; sourceTree = "<group>"; };
94DE5C801D7F39D000164F2A /* CSSAtRuleID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSAtRuleID.h; path = parser/CSSAtRuleID.h; sourceTree = "<group>"; };
+ 94DE5C8B1D80801500164F2A /* CSSSelectorParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CSSSelectorParser.cpp; path = parser/CSSSelectorParser.cpp; sourceTree = "<group>"; };
+ 94DE5C8C1D80801500164F2A /* CSSSelectorParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSSelectorParser.h; path = parser/CSSSelectorParser.h; 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>"; };
@@ -18184,6 +18188,8 @@
946D37421D6CF6320077084F /* CSSPropertyParser.h */,
949C77021D6E393500C0DE4F /* CSSPropertyParserHelpers.cpp */,
949C77031D6E393500C0DE4F /* CSSPropertyParserHelpers.h */,
+ 94DE5C8B1D80801500164F2A /* CSSSelectorParser.cpp */,
+ 94DE5C8C1D80801500164F2A /* CSSSelectorParser.h */,
946D37341D6CDF980077084F /* CSSTokenizer.cpp */,
946D37371D6CDF980077084F /* CSSTokenizer.h */,
946D37351D6CDF980077084F /* CSSTokenizerInputStream.cpp */,
@@ -26651,6 +26657,7 @@
B2227A940D00BF220071B782 /* SVGPolylineElement.h in Headers */,
B2227A970D00BF220071B782 /* SVGPreserveAspectRatio.h in Headers */,
088A0E0A126EF1DB00978F7A /* SVGProperty.h in Headers */,
+ 94DE5C8E1D80802700164F2A /* CSSSelectorParser.h in Headers */,
081DD49C13BA1A6000DC7627 /* SVGPropertyInfo.h in Headers */,
088A0E0B126EF1DB00978F7A /* SVGPropertyTearOff.h in Headers */,
088A0E0C126EF1DB00978F7A /* SVGPropertyTraits.h in Headers */,
@@ -28929,6 +28936,7 @@
BCE0139A0C0BEF180043860A /* JSStyleSheet.cpp in Sources */,
BC98A27D0C0C9950004BEBF7 /* JSStyleSheetCustom.cpp in Sources */,
A84EBD840CB8C97700079609 /* JSStyleSheetList.cpp in Sources */,
+ 94DE5C8D1D80802700164F2A /* CSSSelectorParser.cpp in Sources */,
A84EBD780CB8C89200079609 /* JSStyleSheetListCustom.cpp in Sources */,
B20111070AB7740500DB0E68 /* JSSVGAElement.cpp in Sources */,
24D9129113CA951E00D21915 /* JSSVGAltGlyphDefElement.cpp in Sources */,
Modified: trunk/Source/WebCore/contentextensions/ContentExtensionParser.cpp (205659 => 205660)
--- trunk/Source/WebCore/contentextensions/ContentExtensionParser.cpp 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/contentextensions/ContentExtensionParser.cpp 2016-09-08 21:09:04 UTC (rev 205660)
@@ -186,7 +186,7 @@
static bool isValidSelector(const String& selector)
{
- CSSParserContext context(CSSQuirksMode);
+ CSSParserContext context(HTMLQuirksMode);
CSSParser parser(context);
CSSSelectorList selectorList;
parser.parseSelector(selector, selectorList);
Modified: trunk/Source/WebCore/css/CSSDefaultStyleSheets.cpp (205659 => 205660)
--- trunk/Source/WebCore/css/CSSDefaultStyleSheets.cpp 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/CSSDefaultStyleSheets.cpp 2016-09-08 21:09:04 UTC (rev 205660)
@@ -95,7 +95,7 @@
static StyleSheetContents* parseUASheet(const String& str)
{
- StyleSheetContents& sheet = StyleSheetContents::create().leakRef(); // leak the sheet on purpose
+ StyleSheetContents& sheet = StyleSheetContents::create(CSSParserContext(UASheetMode)).leakRef(); // leak the sheet on purpose
sheet.parseString(str);
return &sheet;
}
Modified: trunk/Source/WebCore/css/CSSFontFaceSet.cpp (205659 => 205660)
--- trunk/Source/WebCore/css/CSSFontFaceSet.cpp 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/CSSFontFaceSet.cpp 2016-09-08 21:09:04 UTC (rev 205660)
@@ -328,7 +328,7 @@
{
Vector<std::reference_wrapper<CSSFontFace>> result;
auto style = MutableStyleProperties::create();
- auto parseResult = CSSParser::parseValue(style, CSSPropertyFont, font, true, CSSStrictMode, nullptr);
+ auto parseResult = CSSParser::parseValue(style, CSSPropertyFont, font, true, HTMLStandardMode, nullptr);
if (parseResult == CSSParser::ParseResult::Error) {
ec = SYNTAX_ERR;
return result;
Modified: trunk/Source/WebCore/css/CSSGrammar.y.in (205659 => 205660)
--- trunk/Source/WebCore/css/CSSGrammar.y.in 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/CSSGrammar.y.in 2016-09-08 21:09:04 UTC (rev 205660)
@@ -1256,7 +1256,7 @@
IDSEL {
$$ = new CSSParserSelector;
$$->setMatch(CSSSelector::Id);
- if (parser->m_context.mode == CSSQuirksMode)
+ if (parser->m_context.mode == HTMLQuirksMode)
$1.convertToASCIILowercaseInPlace();
$$->setValue($1);
}
@@ -1266,7 +1266,7 @@
else {
$$ = new CSSParserSelector;
$$->setMatch(CSSSelector::Id);
- if (parser->m_context.mode == CSSQuirksMode)
+ if (parser->m_context.mode == HTMLQuirksMode)
$1.convertToASCIILowercaseInPlace();
$$->setValue($1);
}
@@ -1280,7 +1280,7 @@
'.' IDENT {
$$ = new CSSParserSelector;
$$->setMatch(CSSSelector::Class);
- if (parser->m_context.mode == CSSQuirksMode)
+ if (parser->m_context.mode == HTMLQuirksMode)
$2.convertToASCIILowercaseInPlace();
$$->setValue($2);
}
Modified: trunk/Source/WebCore/css/CSSSelector.cpp (205659 => 205660)
--- trunk/Source/WebCore/css/CSSSelector.cpp 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/CSSSelector.cpp 2016-09-08 21:09:04 UTC (rev 205660)
@@ -735,6 +735,8 @@
return tagHistory->selectorText(" " + str.toString() + rightSide);
case CSSSelector::Child:
return tagHistory->selectorText(" > " + str.toString() + rightSide);
+ case CSSSelector::ShadowDeep:
+ return tagHistory->selectorText(" /deep/ " + str.toString() + rightSide);
case CSSSelector::DirectAdjacent:
return tagHistory->selectorText(" + " + str.toString() + rightSide);
case CSSSelector::IndirectAdjacent:
@@ -745,6 +747,8 @@
FALLTHROUGH;
#endif
case CSSSelector::ShadowDescendant:
+ case CSSSelector::ShadowPseudo:
+ case CSSSelector::ShadowSlot:
return tagHistory->selectorText(str.toString() + rightSide);
}
}
Modified: trunk/Source/WebCore/css/CSSSelector.h (205659 => 205660)
--- trunk/Source/WebCore/css/CSSSelector.h 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/CSSSelector.h 2016-09-08 21:09:04 UTC (rev 205660)
@@ -87,7 +87,10 @@
DirectAdjacent,
IndirectAdjacent,
SubSelector,
- ShadowDescendant,
+ ShadowDescendant, // FIXME-NEWPARSER: Remove this in favor of the new shadow values below.
+ ShadowPseudo, // Special case of shadow DOM pseudo elements / shadow pseudo element
+ ShadowDeep, // /deep/ combinator
+ ShadowSlot // slotted to <slot> e
};
enum PseudoClassType {
@@ -217,6 +220,11 @@
RightBottomMarginBox,
};
+ enum AttributeMatchType {
+ CaseSensitive,
+ CaseInsensitive,
+ };
+
static PseudoElementType parsePseudoElementType(const String&);
static PseudoId pseudoId(PseudoElementType);
Modified: trunk/Source/WebCore/css/DOMCSSNamespace.cpp (205659 => 205660)
--- trunk/Source/WebCore/css/DOMCSSNamespace.cpp 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/DOMCSSNamespace.cpp 2016-09-08 21:09:04 UTC (rev 205660)
@@ -69,12 +69,12 @@
return false;
auto dummyStyle = MutableStyleProperties::create();
- return CSSParser::parseValue(dummyStyle, propertyID, normalizedValue, false, CSSStrictMode, nullptr) != CSSParser::ParseResult::Error;
+ return CSSParser::parseValue(dummyStyle, propertyID, normalizedValue, false, HTMLStandardMode, nullptr) != CSSParser::ParseResult::Error;
}
bool DOMCSSNamespace::supports(const String& conditionText)
{
- CSSParserContext context(CSSStrictMode);
+ CSSParserContext context(HTMLStandardMode);
CSSParser parser(context);
return parser.parseSupportsCondition(conditionText);
}
Modified: trunk/Source/WebCore/css/FontFace.cpp (205659 => 205660)
--- trunk/Source/WebCore/css/FontFace.cpp 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/FontFace.cpp 2016-09-08 21:09:04 UTC (rev 205660)
@@ -130,7 +130,7 @@
RefPtr<CSSValue> FontFace::parseString(const String& string, CSSPropertyID propertyID)
{
auto style = MutableStyleProperties::create();
- if (CSSParser::parseValue(style, propertyID, string, true, CSSStrictMode, nullptr) == CSSParser::ParseResult::Error)
+ if (CSSParser::parseValue(style, propertyID, string, true, HTMLStandardMode, nullptr) == CSSParser::ParseResult::Error)
return nullptr;
return style->getPropertyCSSValue(propertyID);
}
@@ -204,7 +204,7 @@
}
auto style = MutableStyleProperties::create();
- auto result = CSSParser::parseValue(style, CSSPropertyFontVariant, variant, true, CSSStrictMode, nullptr);
+ auto result = CSSParser::parseValue(style, CSSPropertyFontVariant, variant, true, HTMLStandardMode, nullptr);
if (result == CSSParser::ParseResult::Error) {
ec = SYNTAX_ERR;
return;
Modified: trunk/Source/WebCore/css/MediaList.cpp (205659 => 205660)
--- trunk/Source/WebCore/css/MediaList.cpp 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/MediaList.cpp 2016-09-08 21:09:04 UTC (rev 205660)
@@ -129,13 +129,13 @@
Optional<MediaQuery> MediaQuerySet::internalParse(const String& queryString)
{
- CSSParser parser(CSSStrictMode);
+ CSSParser parser(HTMLStandardMode);
return internalParse(parser, queryString);
}
bool MediaQuerySet::parse(const String& mediaString)
{
- CSSParser parser(CSSStrictMode);
+ CSSParser parser(HTMLStandardMode);
Vector<MediaQuery> result;
Vector<String> list;
Modified: trunk/Source/WebCore/css/SelectorChecker.cpp (205659 => 205660)
--- trunk/Source/WebCore/css/SelectorChecker.cpp 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/SelectorChecker.cpp 2016-09-08 21:09:04 UTC (rev 205660)
@@ -452,8 +452,16 @@
return MatchResult::updateWithMatchType(result, matchType);
}
+
+ case CSSSelector::ShadowPseudo:
+ case CSSSelector::ShadowDeep:
+ case CSSSelector::ShadowSlot:
+ // FIXME-NEWPARSER: Have to implement these.
+ ASSERT_NOT_REACHED();
+ return MatchResult::fails(Match::SelectorFailsCompletely);
}
+
ASSERT_NOT_REACHED();
return MatchResult::fails(Match::SelectorFailsCompletely);
}
Modified: trunk/Source/WebCore/css/SelectorFilter.cpp (205659 => 205660)
--- trunk/Source/WebCore/css/SelectorFilter.cpp 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/SelectorFilter.cpp 2016-09-08 21:09:04 UTC (rev 205660)
@@ -138,8 +138,14 @@
case CSSSelector::ShadowDescendant:
skipOverSubselectors = true;
break;
+ case CSSSelector::ShadowSlot:
+ // Disable fastRejectSelector.
+ *identifierHashes = 0;
+ return;
case CSSSelector::Descendant:
case CSSSelector::Child:
+ case CSSSelector::ShadowPseudo:
+ case CSSSelector::ShadowDeep:
skipOverSubselectors = false;
collectDescendantSelectorIdentifierHashes(selector, hash);
break;
Modified: trunk/Source/WebCore/css/SelectorPseudoClassAndCompatibilityElementMap.in (205659 => 205660)
--- trunk/Source/WebCore/css/SelectorPseudoClassAndCompatibilityElementMap.in 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/SelectorPseudoClassAndCompatibilityElementMap.in 2016-09-08 21:09:04 UTC (rev 205660)
@@ -27,7 +27,7 @@
focus
focus-within
horizontal
-host
+host, PseudoClassHost, PseudoElementUnknown
hover
in-range
increment
Modified: trunk/Source/WebCore/css/SelectorPseudoTypeMap.h (205659 => 205660)
--- trunk/Source/WebCore/css/SelectorPseudoTypeMap.h 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/SelectorPseudoTypeMap.h 2016-09-08 21:09:04 UTC (rev 205660)
@@ -38,6 +38,7 @@
};
PseudoClassOrCompatibilityPseudoElement parsePseudoClassAndCompatibilityElementString(const CSSParserString& pseudoTypeString);
+PseudoClassOrCompatibilityPseudoElement parsePseudoClassAndCompatibilityElementString(const StringView& pseudoTypeString);
CSSSelector::PseudoElementType parsePseudoElementString(const StringImpl& pseudoTypeString);
} // namespace WebCore
Modified: trunk/Source/WebCore/css/SourceSizeList.cpp (205659 => 205660)
--- trunk/Source/WebCore/css/SourceSizeList.cpp 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/SourceSizeList.cpp 2016-09-08 21:09:04 UTC (rev 205660)
@@ -74,7 +74,7 @@
if (!renderer)
return 0;
auto& style = renderer->style();
- for (auto& sourceSize : CSSParser(CSSStrictMode).parseSizesAttribute(sizesAttribute)) {
+ for (auto& sourceSize : CSSParser(HTMLStandardMode).parseSizesAttribute(sizesAttribute)) {
if (match(sourceSize._expression_, style, document))
return computeLength(sourceSize.length.get(), style, *renderer);
}
Modified: trunk/Source/WebCore/css/StyleProperties.cpp (205659 => 205660)
--- trunk/Source/WebCore/css/StyleProperties.cpp 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/StyleProperties.cpp 2016-09-08 21:09:04 UTC (rev 205660)
@@ -76,7 +76,7 @@
}
MutableStyleProperties::MutableStyleProperties(const CSSProperty* properties, unsigned length)
- : StyleProperties(CSSStrictMode)
+ : StyleProperties(HTMLStandardMode)
{
m_propertyVector.reserveInitialCapacity(length);
for (unsigned i = 0; i < length; ++i)
Modified: trunk/Source/WebCore/css/StyleProperties.h (205659 => 205660)
--- trunk/Source/WebCore/css/StyleProperties.h 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/StyleProperties.h 2016-09-08 21:09:04 UTC (rev 205660)
@@ -134,9 +134,9 @@
int findPropertyIndex(CSSPropertyID) const;
int findCustomPropertyIndex(const String& propertyName) const;
- unsigned m_cssParserMode : 2;
+ unsigned m_cssParserMode : 3;
mutable unsigned m_isMutable : 1;
- unsigned m_arraySize : 29;
+ unsigned m_arraySize : 28;
private:
String getShorthandValue(const StylePropertyShorthand&) const;
@@ -186,7 +186,7 @@
class MutableStyleProperties final : public StyleProperties {
public:
- WEBCORE_EXPORT static Ref<MutableStyleProperties> create(CSSParserMode = CSSQuirksMode);
+ WEBCORE_EXPORT static Ref<MutableStyleProperties> create(CSSParserMode = HTMLQuirksMode);
static Ref<MutableStyleProperties> create(const CSSProperty* properties, unsigned count);
WEBCORE_EXPORT ~MutableStyleProperties();
Modified: trunk/Source/WebCore/css/StyleRuleImport.cpp (205659 => 205660)
--- trunk/Source/WebCore/css/StyleRuleImport.cpp 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/StyleRuleImport.cpp 2016-09-08 21:09:04 UTC (rev 205660)
@@ -66,7 +66,7 @@
if (m_styleSheet)
m_styleSheet->clearOwnerRule();
- CSSParserContext context = m_parentStyleSheet ? m_parentStyleSheet->parserContext() : CSSStrictMode;
+ CSSParserContext context = m_parentStyleSheet ? m_parentStyleSheet->parserContext() : HTMLStandardMode;
context.charset = charset;
if (!baseURL.isNull())
context.baseURL = baseURL;
Modified: trunk/Source/WebCore/css/StyleSheetContents.cpp (205659 => 205660)
--- trunk/Source/WebCore/css/StyleSheetContents.cpp 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/StyleSheetContents.cpp 2016-09-08 21:09:04 UTC (rev 205660)
@@ -62,6 +62,7 @@
StyleSheetContents::StyleSheetContents(StyleRuleImport* ownerRule, const String& originalURL, const CSSParserContext& context)
: m_ownerRule(ownerRule)
, m_originalURL(originalURL)
+ , m_defaultNamespace(starAtom)
, m_loadCompleted(false)
, m_isUserStyleSheet(ownerRule && ownerRule->parentStyleSheet() && ownerRule->parentStyleSheet()->isUserStyleSheet())
, m_hasSyntacticallyValidCSSHeader(true)
@@ -82,6 +83,7 @@
, m_importRules(o.m_importRules.size())
, m_childRules(o.m_childRules.size())
, m_namespaces(o.m_namespaces)
+ , m_defaultNamespace(o.m_defaultNamespace)
, m_loadCompleted(true)
, m_isUserStyleSheet(o.m_isUserStyleSheet)
, m_hasSyntacticallyValidCSSHeader(o.m_hasSyntacticallyValidCSSHeader)
@@ -269,8 +271,11 @@
void StyleSheetContents::parserAddNamespace(const AtomicString& prefix, const AtomicString& uri)
{
- if (uri.isNull() || prefix.isNull())
+ ASSERT(!uri.isNull());
+ if (prefix.isNull()) {
+ m_defaultNamespace = uri;
return;
+ }
PrefixNamespaceURIMap::AddResult result = m_namespaces.add(prefix, uri);
if (result.isNewEntry)
return;
@@ -277,7 +282,7 @@
result.iterator->value = uri;
}
-const AtomicString& StyleSheetContents::determineNamespace(const AtomicString& prefix)
+const AtomicString& StyleSheetContents::namespaceURIFromPrefix(const AtomicString& prefix)
{
PrefixNamespaceURIMap::const_iterator it = m_namespaces.find(prefix);
if (it == m_namespaces.end())
Modified: trunk/Source/WebCore/css/StyleSheetContents.h (205659 => 205660)
--- trunk/Source/WebCore/css/StyleSheetContents.h 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/StyleSheetContents.h 2016-09-08 21:09:04 UTC (rev 205660)
@@ -44,7 +44,7 @@
class StyleSheetContents final : public RefCounted<StyleSheetContents> {
public:
- static Ref<StyleSheetContents> create(const CSSParserContext& context = CSSParserContext(CSSStrictMode))
+ static Ref<StyleSheetContents> create(const CSSParserContext& context = CSSParserContext(HTMLStandardMode))
{
return adoptRef(*new StyleSheetContents(0, String(), context));
}
@@ -60,9 +60,10 @@
WEBCORE_EXPORT ~StyleSheetContents();
const CSSParserContext& parserContext() const { return m_parserContext; }
+
+ const AtomicString& defaultNamespace() { return m_defaultNamespace; }
+ const AtomicString& namespaceURIFromPrefix(const AtomicString& prefix);
- const AtomicString& determineNamespace(const AtomicString& prefix);
-
void parseAuthorStyleSheet(const CachedCSSStyleSheet*, const SecurityOrigin*);
WEBCORE_EXPORT bool parseString(const String&);
bool parseStringAtPosition(const String&, const TextPosition&, bool createdByParser);
@@ -160,6 +161,7 @@
Vector<RefPtr<StyleRuleBase>> m_childRules;
typedef HashMap<AtomicString, AtomicString> PrefixNamespaceURIMap;
PrefixNamespaceURIMap m_namespaces;
+ AtomicString m_defaultNamespace;
bool m_loadCompleted : 1;
bool m_isUserStyleSheet : 1;
Modified: trunk/Source/WebCore/css/WebKitCSSMatrix.cpp (205659 => 205660)
--- trunk/Source/WebCore/css/WebKitCSSMatrix.cpp 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/WebKitCSSMatrix.cpp 2016-09-08 21:09:04 UTC (rev 205660)
@@ -57,7 +57,7 @@
return;
auto styleDeclaration = MutableStyleProperties::create();
- if (CSSParser::parseValue(styleDeclaration, CSSPropertyTransform, string, true, CSSStrictMode, nullptr) != CSSParser::ParseResult::Error) {
+ if (CSSParser::parseValue(styleDeclaration, CSSPropertyTransform, string, true, HTMLStandardMode, nullptr) != CSSParser::ParseResult::Error) {
// Convert to TransformOperations. This can fail if a property
// requires style (i.e., param uses 'ems' or 'exs')
RefPtr<CSSValue> value = styleDeclaration->getPropertyCSSValue(CSSPropertyTransform);
Modified: trunk/Source/WebCore/css/makeSelectorPseudoClassAndCompatibilityElementMap.py (205659 => 205660)
--- trunk/Source/WebCore/css/makeSelectorPseudoClassAndCompatibilityElementMap.py 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/makeSelectorPseudoClassAndCompatibilityElementMap.py 2016-09-08 21:09:04 UTC (rev 205660)
@@ -62,7 +62,7 @@
output_file.write("""
%{
/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-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
@@ -198,6 +198,19 @@
return { CSSSelector::PseudoClassUnknown, CSSSelector::PseudoElementUnknown };
}
+PseudoClassOrCompatibilityPseudoElement parsePseudoClassAndCompatibilityElementString(const StringView& pseudoTypeString)
+{
+ const SelectorPseudoClassOrCompatibilityPseudoElementEntry* entry;
+ if (pseudoTypeString.is8Bit())
+ entry = parsePseudoClassAndCompatibilityElementString(pseudoTypeString.characters8(), pseudoTypeString.length());
+ else
+ entry = parsePseudoClassAndCompatibilityElementString(pseudoTypeString.characters16(), pseudoTypeString.length());
+
+ if (entry)
+ return entry->pseudoTypes;
+ return { CSSSelector::PseudoClassUnknown, CSSSelector::PseudoElementUnknown };
+}
+
} // namespace WebCore
#if defined(__clang__)
Modified: trunk/Source/WebCore/css/parser/CSSParser.cpp (205659 => 205660)
--- trunk/Source/WebCore/css/parser/CSSParser.cpp 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/parser/CSSParser.cpp 2016-09-08 21:09:04 UTC (rev 205660)
@@ -232,7 +232,7 @@
const CSSParserContext& strictCSSParserContext()
{
- static NeverDestroyed<CSSParserContext> strictContext(CSSStrictMode);
+ static NeverDestroyed<CSSParserContext> strictContext(HTMLStandardMode);
return strictContext;
}
@@ -254,7 +254,7 @@
CSSParserContext::CSSParserContext(Document& document, const URL& baseURL, const String& charset)
: baseURL(baseURL.isNull() ? document.baseURL() : baseURL)
, charset(charset)
- , mode(document.inQuirksMode() ? CSSQuirksMode : CSSStrictMode)
+ , mode(document.inQuirksMode() ? HTMLQuirksMode : HTMLStandardMode)
, isHTMLDocument(document.isHTMLDocument())
#if ENABLE(CSS_GRID_LAYOUT)
, cssGridLayoutEnabled(document.isCSSGridLayoutEnabled())
@@ -1392,7 +1392,7 @@
if (fastParseColor(color, string, strict))
return true;
- CSSParser parser(CSSStrictMode);
+ CSSParser parser(HTMLStandardMode);
// In case the fast-path parser didn't understand the color, try the full parser.
if (!parser.parseColor(string))
@@ -1719,7 +1719,7 @@
inline bool CSSParser::shouldAcceptUnitLessValues(CSSParserValue& value, Units unitFlags, CSSParserMode cssParserMode)
{
// Qirks mode and svg presentation attributes accept unit less values.
- return (unitFlags & (FLength | FAngle | FTime)) && (!value.fValue || cssParserMode == CSSQuirksMode || cssParserMode == SVGAttributeMode);
+ return (unitFlags & (FLength | FAngle | FTime)) && (!value.fValue || cssParserMode == HTMLQuirksMode || cssParserMode == SVGAttributeMode);
}
bool CSSParser::validateUnit(ValueWithCalculation& valueWithCalculation, Units unitFlags, CSSParserMode cssParserMode)
@@ -2356,7 +2356,7 @@
if (id == CSSValueAuto)
validPrimitive = true;
else
- validPrimitive = (!id && validateUnit(valueWithCalculation, FInteger, CSSQuirksMode));
+ validPrimitive = (!id && validateUnit(valueWithCalculation, FInteger, HTMLQuirksMode));
break;
case CSSPropertyOrphans: // <integer> | inherit | auto (We've added support for auto for backwards compatibility)
@@ -2364,7 +2364,7 @@
if (id == CSSValueAuto)
validPrimitive = true;
else
- validPrimitive = (!id && validateUnit(valueWithCalculation, FPositiveInteger, CSSQuirksMode));
+ validPrimitive = (!id && validateUnit(valueWithCalculation, FPositiveInteger, HTMLQuirksMode));
break;
case CSSPropertyLineHeight:
@@ -2415,7 +2415,7 @@
if (id == CSSValueNormal || id == CSSValueReset || id == CSSValueDocument)
validPrimitive = true;
else
- validPrimitive = (!id && validateUnit(valueWithCalculation, FNumber | FPercent | FNonNeg, CSSStrictMode));
+ validPrimitive = (!id && validateUnit(valueWithCalculation, FNumber | FPercent | FNonNeg, HTMLStandardMode));
break;
case CSSPropertyWebkitTextZoom:
@@ -2567,10 +2567,10 @@
validPrimitive = validateUnit(valueWithCalculation, FNumber);
break;
case CSSPropertyWebkitBoxFlexGroup:
- validPrimitive = validateUnit(valueWithCalculation, FInteger | FNonNeg, CSSStrictMode);
+ validPrimitive = validateUnit(valueWithCalculation, FInteger | FNonNeg, HTMLStandardMode);
break;
case CSSPropertyWebkitBoxOrdinalGroup:
- validPrimitive = validateUnit(valueWithCalculation, FInteger | FNonNeg, CSSStrictMode) && valueWithCalculation.value().fValue;
+ validPrimitive = validateUnit(valueWithCalculation, FInteger | FNonNeg, HTMLStandardMode) && valueWithCalculation.value().fValue;
break;
case CSSPropertyFilter:
#if ENABLE(FILTERS_LEVEL_2)
@@ -2616,7 +2616,7 @@
validPrimitive = validateUnit(valueWithCalculation, FNumber | FNonNeg);
break;
case CSSPropertyOrder:
- if (validateUnit(valueWithCalculation, FInteger, CSSStrictMode)) {
+ if (validateUnit(valueWithCalculation, FInteger, HTMLStandardMode)) {
// We restrict the smallest value to int min + 2 because we use int min and int min + 1 as special values in a hash set.
double result = std::max<double>(std::numeric_limits<int>::min() + 2, parsedDouble(valueWithCalculation));
parsedValue = cssValuePool.createValue(result, CSSPrimitiveValue::CSS_NUMBER);
@@ -2898,7 +2898,7 @@
case CSSPropertyWebkitLineClamp:
// When specifying number of lines, don't allow 0 as a valid value
// When specifying either type of unit, require non-negative integers
- validPrimitive = (!id && (valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_PERCENTAGE || valueWithCalculation.value().fValue) && validateUnit(valueWithCalculation, FInteger | FPercent | FNonNeg, CSSQuirksMode));
+ validPrimitive = (!id && (valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_PERCENTAGE || valueWithCalculation.value().fValue) && validateUnit(valueWithCalculation, FInteger | FPercent | FNonNeg, HTMLQuirksMode));
break;
#if ENABLE(IOS_TEXT_AUTOSIZING)
case CSSPropertyWebkitTextSizeAdjust:
@@ -2909,7 +2909,7 @@
validPrimitive = true;
else {
// FIXME: Handle multilength case where we allow relative units.
- validPrimitive = (!id && validateUnit(valueWithCalculation, FPercent | FNonNeg, CSSStrictMode));
+ validPrimitive = (!id && validateUnit(valueWithCalculation, FPercent | FNonNeg, HTMLStandardMode));
}
break;
#endif
@@ -2925,12 +2925,12 @@
case CSSPropertyWebkitHyphenateLimitBefore:
case CSSPropertyWebkitHyphenateLimitAfter:
- if (id == CSSValueAuto || validateUnit(valueWithCalculation, FInteger | FNonNeg, CSSStrictMode))
+ if (id == CSSValueAuto || validateUnit(valueWithCalculation, FInteger | FNonNeg, HTMLStandardMode))
validPrimitive = true;
break;
case CSSPropertyWebkitHyphenateLimitLines:
- if (id == CSSValueNoLimit || validateUnit(valueWithCalculation, FInteger | FNonNeg, CSSStrictMode))
+ if (id == CSSValueNoLimit || validateUnit(valueWithCalculation, FInteger | FNonNeg, HTMLStandardMode))
validPrimitive = true;
break;
@@ -3874,7 +3874,7 @@
ValueWithCalculation valueWithCalculation(*m_valueList->current());
CSSValueID id = valueWithCalculation.value().id;
// Always parse this property in strict mode, since it would be ambiguous otherwise when used in the 'columns' shorthand property.
- if (id != CSSValueAuto && !(validateUnit(valueWithCalculation, FLength | FNonNeg, CSSStrictMode) && parsedDouble(valueWithCalculation)))
+ if (id != CSSValueAuto && !(validateUnit(valueWithCalculation, FLength | FNonNeg, HTMLStandardMode) && parsedDouble(valueWithCalculation)))
return nullptr;
auto parsedValue = parseValidPrimitive(id, valueWithCalculation);
@@ -3887,7 +3887,7 @@
ValueWithCalculation valueWithCalculation(*m_valueList->current());
CSSValueID id = valueWithCalculation.value().id;
- if (id != CSSValueAuto && !validateUnit(valueWithCalculation, FPositiveInteger, CSSQuirksMode))
+ if (id != CSSValueAuto && !validateUnit(valueWithCalculation, FPositiveInteger, HTMLQuirksMode))
return nullptr;
auto parsedValue = parseValidPrimitive(id, valueWithCalculation);
@@ -7237,7 +7237,7 @@
return true;
}
ValueWithCalculation valueWithCalculation(value);
- if (validateUnit(valueWithCalculation, FInteger | FNonNeg, CSSQuirksMode)) {
+ if (validateUnit(valueWithCalculation, FInteger | FNonNeg, HTMLQuirksMode)) {
int weight = static_cast<int>(parsedDouble(valueWithCalculation));
if (!(weight % 100) && weight >= 100 && weight <= 900) {
addProperty(CSSPropertyFontWeight, CSSValuePool::singleton().createIdentifierValue(createFontWeightValueKeyword(weight)), important);
@@ -7812,9 +7812,9 @@
ValueWithCalculation firstArgumentWithCalculation(*args->current());
Units unitType = FUnknown;
// Get the first value and its type
- if (validateUnit(firstArgumentWithCalculation, FInteger, CSSStrictMode))
+ if (validateUnit(firstArgumentWithCalculation, FInteger, HTMLStandardMode))
unitType = FInteger;
- else if (validateUnit(firstArgumentWithCalculation, FPercent, CSSStrictMode))
+ else if (validateUnit(firstArgumentWithCalculation, FPercent, HTMLStandardMode))
unitType = FPercent;
else
return false;
@@ -7825,7 +7825,7 @@
if (operatorArgument.unit != CSSParserValue::Operator && operatorArgument.iValue != ',')
return false;
ValueWithCalculation argumentWithCalculation(*args->next());
- if (!validateUnit(argumentWithCalculation, unitType, CSSStrictMode))
+ if (!validateUnit(argumentWithCalculation, unitType, HTMLStandardMode))
return false;
colorArray[i] = colorIntFromValue(argumentWithCalculation);
}
@@ -7834,7 +7834,7 @@
if (operatorArgument.unit != CSSParserValue::Operator && operatorArgument.iValue != ',')
return false;
ValueWithCalculation argumentWithCalculation(*args->next());
- if (!validateUnit(argumentWithCalculation, FNumber, CSSStrictMode))
+ if (!validateUnit(argumentWithCalculation, FNumber, HTMLStandardMode))
return false;
double doubleValue = parsedDouble(argumentWithCalculation);
// Convert the floating pointer number of alpha to an integer in the range [0, 256),
@@ -7854,7 +7854,7 @@
CSSParserValueList* args = value.function->args.get();
ValueWithCalculation firstArgumentWithCalculation(*args->current());
// Get the first value
- if (!validateUnit(firstArgumentWithCalculation, FNumber, CSSStrictMode))
+ if (!validateUnit(firstArgumentWithCalculation, FNumber, HTMLStandardMode))
return false;
// normalize the Hue value and change it to be between 0 and 1.0
colorArray[0] = (((static_cast<int>(parsedDouble(firstArgumentWithCalculation)) % 360) + 360) % 360) / 360.0;
@@ -7863,7 +7863,7 @@
if (operatorArgument.unit != CSSParserValue::Operator && operatorArgument.iValue != ',')
return false;
ValueWithCalculation argumentWithCalculation(*args->next());
- if (!validateUnit(argumentWithCalculation, FPercent, CSSStrictMode))
+ if (!validateUnit(argumentWithCalculation, FPercent, HTMLStandardMode))
return false;
colorArray[i] = std::max<double>(0, std::min<double>(100, parsedDouble(argumentWithCalculation))) / 100.0; // needs to be value between 0 and 1.0
}
@@ -7872,7 +7872,7 @@
if (operatorArgument.unit != CSSParserValue::Operator && operatorArgument.iValue != ',')
return false;
ValueWithCalculation argumentWithCalculation(*args->next());
- if (!validateUnit(argumentWithCalculation, FNumber, CSSStrictMode))
+ if (!validateUnit(argumentWithCalculation, FNumber, HTMLStandardMode))
return false;
colorArray[3] = std::max<double>(0, std::min<double>(1, parsedDouble(argumentWithCalculation)));
}
@@ -8079,13 +8079,13 @@
return nullptr;
// The value is good. Commit it.
context.commitValue();
- } else if (validateUnit(valueWithCalculation, FLength, CSSStrictMode)) {
+ } else if (validateUnit(valueWithCalculation, FLength, HTMLStandardMode)) {
// We required a length and didn't get one. Invalid.
if (!context.allowLength())
return nullptr;
// Blur radius must be non-negative.
- if (context.allowBlur && !validateUnit(valueWithCalculation, FLength | FNonNeg, CSSStrictMode))
+ if (context.allowBlur && !validateUnit(valueWithCalculation, FLength | FNonNeg, HTMLStandardMode))
return nullptr;
// A length is allowed here. Construct the value and add it.
@@ -8533,7 +8533,7 @@
while ((value = m_valueList->current())) {
ValueWithCalculation valueWithCalculation(*value);
// FIXME calc() http://webkit.org/b/16662 : calc is parsed but values are not created yet.
- if (context.allowNumber() && !isCalculation(valueWithCalculation) && validateUnit(valueWithCalculation, FInteger | FNonNeg | FPercent, CSSStrictMode)) {
+ if (context.allowNumber() && !isCalculation(valueWithCalculation) && validateUnit(valueWithCalculation, FInteger | FNonNeg | FPercent, HTMLStandardMode)) {
context.commitNumber(valueWithCalculation);
} else if (context.allowFill() && value->id == CSSValueFill)
context.commitFill();
@@ -8647,7 +8647,7 @@
CSSParserValue* value;
while ((value = m_valueList->current())) {
ValueWithCalculation valueWithCalculation(*value);
- if (context.allowNumber() && (validateUnit(valueWithCalculation, validUnits, CSSStrictMode) || value->id == CSSValueAuto)) {
+ if (context.allowNumber() && (validateUnit(valueWithCalculation, validUnits, HTMLStandardMode) || value->id == CSSValueAuto)) {
context.commitNumber(valueWithCalculation);
} else if (!inShorthand()) {
// If we're not parsing a shorthand then we are invalid.
@@ -9077,7 +9077,7 @@
bool expectComma = false;
// Look for angle.
- if (validateUnit(argumentWithCalculation, FAngle, CSSStrictMode)) {
+ if (validateUnit(argumentWithCalculation, FAngle, HTMLStandardMode)) {
result->setAngle(createPrimitiveNumericValue(argumentWithCalculation));
args->next();
@@ -9263,7 +9263,7 @@
bool expectComma = false;
// Look for angle.
- if (validateUnit(firstArgumentWithCalculation, FAngle, CSSStrictMode)) {
+ if (validateUnit(firstArgumentWithCalculation, FAngle, HTMLStandardMode)) {
result->setAngle(createPrimitiveNumericValue(firstArgumentWithCalculation));
args->next();
@@ -10078,21 +10078,21 @@
if (info.type() == WebKitCSSTransformValue::Rotate3DTransformOperation && argNumber == 3) {
// 4th param of rotate3d() is an angle rather than a bare number, validate it as such
- if (!validateUnit(argumentWithCalculation, FAngle, CSSStrictMode))
+ if (!validateUnit(argumentWithCalculation, FAngle, HTMLStandardMode))
return nullptr;
} else if (info.type() == WebKitCSSTransformValue::Translate3DTransformOperation && argNumber == 2) {
// 3rd param of translate3d() cannot be a percentage
- if (!validateUnit(argumentWithCalculation, FLength, CSSStrictMode))
+ if (!validateUnit(argumentWithCalculation, FLength, HTMLStandardMode))
return nullptr;
} else if (info.type() == WebKitCSSTransformValue::TranslateZTransformOperation && !argNumber) {
// 1st param of translateZ() cannot be a percentage
- if (!validateUnit(argumentWithCalculation, FLength, CSSStrictMode))
+ if (!validateUnit(argumentWithCalculation, FLength, HTMLStandardMode))
return nullptr;
} else if (info.type() == WebKitCSSTransformValue::PerspectiveTransformOperation && !argNumber) {
// 1st param of perspective() must be a non-negative number (deprecated) or length.
- if (!validateUnit(argumentWithCalculation, FNumber | FLength | FNonNeg, CSSStrictMode))
+ if (!validateUnit(argumentWithCalculation, FNumber | FLength | FNonNeg, HTMLStandardMode))
return nullptr;
- } else if (!validateUnit(argumentWithCalculation, unit, CSSStrictMode))
+ } else if (!validateUnit(argumentWithCalculation, unit, HTMLStandardMode))
return nullptr;
// Add the value to the current transform operation.
@@ -10167,7 +10167,7 @@
if (args.size()) {
ValueWithCalculation argumentWithCalculation(*args.current());
- if (!validateUnit(argumentWithCalculation, FNumber | FPercent | FNonNeg, CSSStrictMode))
+ if (!validateUnit(argumentWithCalculation, FNumber | FPercent | FNonNeg, HTMLStandardMode))
return nullptr;
auto primitiveValue = createPrimitiveNumericValue(argumentWithCalculation);
@@ -10191,7 +10191,7 @@
if (args.size()) {
ValueWithCalculation argumentWithCalculation(*args.current());
- if (!validateUnit(argumentWithCalculation, FNumber | FPercent, CSSStrictMode))
+ if (!validateUnit(argumentWithCalculation, FNumber | FPercent, HTMLStandardMode))
return nullptr;
filterValue->append(createPrimitiveNumericValue(argumentWithCalculation));
@@ -10205,7 +10205,7 @@
if (args.size()) {
ValueWithCalculation argumentWithCalculation(*args.current());
- if (!validateUnit(argumentWithCalculation, FAngle, CSSStrictMode))
+ if (!validateUnit(argumentWithCalculation, FAngle, HTMLStandardMode))
return nullptr;
filterValue->append(createPrimitiveNumericValue(argumentWithCalculation));
@@ -10219,7 +10219,7 @@
if (args.size()) {
ValueWithCalculation argumentWithCalculation(*args.current());
- if (!validateUnit(argumentWithCalculation, FLength | FNonNeg, CSSStrictMode))
+ if (!validateUnit(argumentWithCalculation, FLength | FNonNeg, HTMLStandardMode))
return nullptr;
filterValue->append(createPrimitiveNumericValue(argumentWithCalculation));
@@ -13125,7 +13125,7 @@
if (!m_styleSheet)
return QualifiedName(prefix, localName, m_defaultNamespace);
- return QualifiedName(prefix, localName, m_styleSheet->determineNamespace(prefix));
+ return QualifiedName(prefix, localName, m_styleSheet->namespaceURIFromPrefix(prefix));
}
void CSSParser::rewriteSpecifiersWithNamespaceIfNeeded(CSSParserSelector& specifiers)
Modified: trunk/Source/WebCore/css/parser/CSSParser.h (205659 => 205660)
--- trunk/Source/WebCore/css/parser/CSSParser.h 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/parser/CSSParser.h 2016-09-08 21:09:04 UTC (rev 205660)
@@ -571,8 +571,8 @@
void setStyleSheet(StyleSheetContents* styleSheet) { m_styleSheet = styleSheet; }
- inline bool inStrictMode() const { return m_context.mode == CSSStrictMode || m_context.mode == SVGAttributeMode; }
- inline bool inQuirksMode() const { return m_context.mode == CSSQuirksMode; }
+ inline bool inStrictMode() const { return m_context.mode == UASheetMode || m_context.mode == HTMLStandardMode || m_context.mode == SVGAttributeMode; }
+ inline bool inQuirksMode() const { return m_context.mode == HTMLQuirksMode; }
URL completeURL(const String& url) const;
Modified: trunk/Source/WebCore/css/parser/CSSParserMode.h (205659 => 205660)
--- trunk/Source/WebCore/css/parser/CSSParserMode.h 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/parser/CSSParserMode.h 2016-09-08 21:09:04 UTC (rev 205660)
@@ -37,21 +37,50 @@
class Document;
+// Must not grow beyond 3 bits, due to packing in StyleProperties.
enum CSSParserMode {
- CSSQuirksMode,
- CSSStrictMode,
- // SVG should always be in strict mode. For SVG attributes, the rules differ to strict sometimes.
- SVGAttributeMode
+ HTMLStandardMode,
+ HTMLQuirksMode,
+ // HTML attributes are parsed in quirks mode but also allows internal properties and values.
+ HTMLAttributeMode,
+ // SVG attributes are parsed in quirks mode but rules differ slightly.
+ SVGAttributeMode,
+ // @viewport rules are parsed in standards mode but CSSOM modifications (via StylePropertySet)
+ // must call parseViewportProperties so needs a special mode.
+ CSSViewportRuleMode,
+ // User agent stylesheets are parsed in standards mode but also allows internal properties and values.
+ UASheetMode
};
+inline bool isQuirksModeBehavior(CSSParserMode mode)
+{
+ return mode == HTMLQuirksMode || mode == HTMLAttributeMode;
+}
+
+inline bool isUASheetBehavior(CSSParserMode mode)
+{
+ return mode == UASheetMode;
+}
+
+inline bool isUnitLessLengthParsingEnabledForMode(CSSParserMode mode)
+{
+ return mode == HTMLAttributeMode || mode == SVGAttributeMode;
+}
+
+inline bool isCSSViewportParsingEnabledForMode(CSSParserMode mode)
+{
+ return mode == CSSViewportRuleMode;
+}
+
+// FIXME-NEWPARSER: Next two functions should be removed eventually.
inline CSSParserMode strictToCSSParserMode(bool inStrictMode)
{
- return inStrictMode ? CSSStrictMode : CSSQuirksMode;
+ return inStrictMode ? HTMLStandardMode : HTMLQuirksMode;
}
inline bool isStrictParserMode(CSSParserMode cssParserMode)
{
- return cssParserMode == CSSStrictMode || cssParserMode == SVGAttributeMode;
+ return cssParserMode == UASheetMode || cssParserMode == HTMLStandardMode || cssParserMode == SVGAttributeMode;
}
struct CSSParserContext {
@@ -62,7 +91,7 @@
URL baseURL;
String charset;
- CSSParserMode mode { CSSStrictMode };
+ CSSParserMode mode { HTMLStandardMode };
bool isHTMLDocument { false };
#if ENABLE(CSS_GRID_LAYOUT)
bool cssGridLayoutEnabled { false };
Modified: trunk/Source/WebCore/css/parser/CSSParserValues.cpp (205659 => 205660)
--- trunk/Source/WebCore/css/parser/CSSParserValues.cpp 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/parser/CSSParserValues.cpp 2016-09-08 21:09:04 UTC (rev 205660)
@@ -22,6 +22,7 @@
#include "CSSParserValues.h"
#include "CSSCustomPropertyValue.h"
+#include "CSSParserIdioms.h"
#include "CSSPrimitiveValue.h"
#include "CSSFunctionValue.h"
#include "CSSSelector.h"
@@ -219,6 +220,27 @@
return selector.release();
}
+CSSParserSelector* CSSParserSelector::parsePseudoElementSelectorFromStringView(StringView& pseudoTypeString)
+{
+ convertToASCIILowercaseInPlace(pseudoTypeString);
+ AtomicString name = pseudoTypeString.toAtomicString();
+
+ CSSSelector::PseudoElementType pseudoType = CSSSelector::parsePseudoElementType(name);
+ if (pseudoType == CSSSelector::PseudoElementUnknown)
+ return nullptr;
+
+ auto selector = std::make_unique<CSSParserSelector>();
+ selector->m_selector->setMatch(CSSSelector::PseudoElement);
+ selector->m_selector->setPseudoElementType(pseudoType);
+ if (pseudoType == CSSSelector::PseudoElementWebKitCustomLegacyPrefixed) {
+ ASSERT_WITH_MESSAGE(name == "-webkit-input-placeholder", "-webkit-input-placeholder is the only LegacyPrefix pseudo type.");
+ if (name == "-webkit-input-placeholder")
+ name = AtomicString("placeholder", AtomicString::ConstructFromLiteral);
+ }
+ selector->m_selector->setValue(name);
+ return selector.release();
+}
+
#if ENABLE(VIDEO_TRACK)
CSSParserSelector* CSSParserSelector::parsePseudoElementCueFunctionSelector(const CSSParserString& functionIdentifier, Vector<std::unique_ptr<CSSParserSelector>>* parsedSelectorVector)
{
@@ -308,6 +330,29 @@
return nullptr;
}
+CSSParserSelector* CSSParserSelector::parsePseudoClassSelectorFromStringView(StringView& pseudoTypeString)
+{
+ if (pseudoTypeString.length() && pseudoTypeString[pseudoTypeString.length() - 1] == '(')
+ return nullptr;
+
+ PseudoClassOrCompatibilityPseudoElement pseudoType = parsePseudoClassAndCompatibilityElementString(pseudoTypeString);
+ if (pseudoType.pseudoClass != CSSSelector::PseudoClassUnknown) {
+ auto selector = std::make_unique<CSSParserSelector>();
+ selector->m_selector->setMatch(CSSSelector::PseudoClass);
+ selector->m_selector->setPseudoClassType(pseudoType.pseudoClass);
+ return selector.release();
+ }
+ if (pseudoType.compatibilityPseudoElement != CSSSelector::PseudoElementUnknown) {
+ auto selector = std::make_unique<CSSParserSelector>();
+ selector->m_selector->setMatch(CSSSelector::PseudoElement);
+ selector->m_selector->setPseudoElementType(pseudoType.compatibilityPseudoElement);
+ AtomicString name = pseudoTypeString.toAtomicString();
+ selector->m_selector->setValue(name);
+ return selector.release();
+ }
+ return nullptr;
+}
+
CSSParserSelector::CSSParserSelector()
: m_selector(std::make_unique<CSSSelector>())
{
@@ -349,7 +394,12 @@
argumentList->append(languageArgument);
m_selector->setLangArgumentList(WTFMove(argumentList));
}
-
+
+void CSSParserSelector::setSelectorList(std::unique_ptr<CSSSelectorList> selectorList)
+{
+ m_selector->setSelectorList(WTFMove(selectorList));
+}
+
void CSSParserSelector::setPseudoClassValue(const CSSParserString& pseudoClassString)
{
ASSERT(m_selector->match() == CSSSelector::PseudoClass);
@@ -425,6 +475,15 @@
case CSSParserSelectorCombinator::IndirectAdjacent:
selectorRelation = CSSSelector::IndirectAdjacent;
break;
+ case CSSParserSelectorCombinator::ShadowDeep:
+ selectorRelation = CSSSelector::ShadowDeep;
+ break;
+ case CSSParserSelectorCombinator::ShadowPseudo:
+ selectorRelation = CSSSelector::ShadowPseudo;
+ break;
+ case CSSParserSelectorCombinator::ShadowSlot:
+ selectorRelation = CSSSelector::ShadowSlot;
+ break;
}
end->setRelation(selectorRelation);
@@ -447,5 +506,17 @@
m_selector->setRelation(CSSSelector::SubSelector);
}
+std::unique_ptr<CSSParserSelector> CSSParserSelector::releaseTagHistory()
+{
+ setRelation(CSSSelector::SubSelector);
+ return WTFMove(m_tagHistory);
}
+// FIXME-NEWPARSER: Add support for :host-context
+bool CSSParserSelector::isHostPseudoSelector() const
+{
+ return pseudoClassType() == CSSSelector::PseudoClassHost;
+}
+
+}
+
Modified: trunk/Source/WebCore/css/parser/CSSParserValues.h (205659 => 205660)
--- trunk/Source/WebCore/css/parser/CSSParserValues.h 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/parser/CSSParserValues.h 2016-09-08 21:09:04 UTC (rev 205660)
@@ -193,7 +193,10 @@
DescendantDoubleChild,
#endif
DirectAdjacent,
- IndirectAdjacent
+ IndirectAdjacent,
+ ShadowPseudo, // Special case of shadow DOM pseudo elements / shadow pseudo element
+ ShadowDeep, // /deep/ combinator
+ ShadowSlot // slotted to <slot> e
};
class CSSParserSelector {
@@ -206,6 +209,9 @@
static CSSParserSelector* parsePseudoClassHostFunctionSelector(const CSSParserString& functionIdentifier, CSSParserSelector*);
static CSSParserSelector* parsePseudoClassAndCompatibilityElementSelector(CSSParserString& pseudoTypeString);
+ static CSSParserSelector* parsePseudoClassSelectorFromStringView(StringView&);
+ static CSSParserSelector* parsePseudoElementSelectorFromStringView(StringView&);
+
CSSParserSelector();
explicit CSSParserSelector(const QualifiedName&);
~CSSParserSelector();
@@ -220,8 +226,13 @@
void setRelation(CSSSelector::Relation value) { m_selector->setRelation(value); }
void setForPage() { m_selector->setForPage(); }
+ CSSSelector::Match match() const { return m_selector->match(); }
+ CSSSelector::PseudoElementType pseudoElementType() const { return m_selector->pseudoElementType(); }
+ const CSSSelectorList* selectorList() const { return m_selector->selectorList(); }
+
void adoptSelectorVector(Vector<std::unique_ptr<CSSParserSelector>>& selectorVector);
void setLangArgumentList(const Vector<CSSParserString>& stringVector);
+ void setSelectorList(std::unique_ptr<CSSSelectorList>);
void setPseudoClassValue(const CSSParserString& pseudoClassString);
CSSSelector::PseudoClassType pseudoClassType() const { return m_selector->pseudoClassType(); }
@@ -239,6 +250,11 @@
bool hasShadowDescendant() const;
bool matchesPseudoElement() const;
+ bool isHostPseudoSelector() const;
+
+ // FIXME-NEWPARSER: Missing "shadow"
+ bool needsImplicitShadowCombinatorForMatching() const { return pseudoElementType() == CSSSelector::PseudoElementWebKitCustom || pseudoElementType() == CSSSelector::PseudoElementUserAgentCustom || pseudoElementType() == CSSSelector::PseudoElementWebKitCustomLegacyPrefixed || pseudoElementType() == CSSSelector::PseudoElementCue || pseudoElementType() == CSSSelector::PseudoElementSlotted; }
+
CSSParserSelector* tagHistory() const { return m_tagHistory.get(); }
void setTagHistory(std::unique_ptr<CSSParserSelector> selector) { m_tagHistory = WTFMove(selector); }
void clearTagHistory() { m_tagHistory.reset(); }
@@ -246,6 +262,7 @@
void appendTagHistory(CSSSelector::Relation, std::unique_ptr<CSSParserSelector>);
void appendTagHistory(CSSParserSelectorCombinator, std::unique_ptr<CSSParserSelector>);
void prependTagSelector(const QualifiedName&, bool tagIsForNamespaceRule = false);
+ std::unique_ptr<CSSParserSelector> releaseTagHistory();
private:
#if ENABLE(CSS_SELECTORS_LEVEL4)
Modified: trunk/Source/WebCore/css/parser/CSSPropertyParser.h (205659 => 205660)
--- trunk/Source/WebCore/css/parser/CSSPropertyParser.h 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParser.h 2016-09-08 21:09:04 UTC (rev 205660)
@@ -55,7 +55,7 @@
bool consumeCSSWideKeyword(CSSPropertyID unresolvedProperty, bool important);
const CSSValue* parseSingleValue(CSSPropertyID, CSSPropertyID = CSSPropertyInvalid);
- bool inQuirksMode() const { return m_context.mode == CSSQuirksMode; }
+ bool inQuirksMode() const { return m_context.mode == HTMLQuirksMode; }
bool parseViewportDescriptor(CSSPropertyID propId, bool important);
bool parseFontFaceDescriptor(CSSPropertyID);
Added: trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp (0 => 205660)
--- trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp (rev 0)
+++ trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp 2016-09-08 21:09:04 UTC (rev 205660)
@@ -0,0 +1,771 @@
+// 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 "CSSSelectorParser.h"
+
+#include "CSSParserMode.h"
+#include "CSSSelectorList.h"
+#include "StyleSheetContents.h"
+#include <memory>
+
+namespace WebCore {
+
+CSSSelectorList CSSSelectorParser::parseSelector(CSSParserTokenRange range, const CSSParserContext& context, StyleSheetContents* styleSheet)
+{
+ CSSSelectorParser parser(context, styleSheet);
+ range.consumeWhitespace();
+ CSSSelectorList result = parser.consumeComplexSelectorList(range);
+ if (!range.atEnd())
+ return CSSSelectorList();
+ return result;
+}
+
+CSSSelectorParser::CSSSelectorParser(const CSSParserContext& context, StyleSheetContents* styleSheet)
+ : m_context(context)
+ , m_styleSheet(styleSheet)
+{
+}
+
+CSSSelectorList CSSSelectorParser::consumeComplexSelectorList(CSSParserTokenRange& range)
+{
+ Vector<std::unique_ptr<CSSParserSelector>> selectorList;
+ std::unique_ptr<CSSParserSelector> selector = consumeComplexSelector(range);
+ if (!selector)
+ return CSSSelectorList();
+ selectorList.append(WTFMove(selector));
+ while (!range.atEnd() && range.peek().type() == CommaToken) {
+ range.consumeIncludingWhitespace();
+ selector = consumeComplexSelector(range);
+ if (!selector)
+ return CSSSelectorList();
+ selectorList.append(WTFMove(selector));
+ }
+
+ CSSSelectorList list;
+ if (m_failedParsing)
+ return list;
+ list.adoptSelectorVector(selectorList);
+ return list;
+}
+
+CSSSelectorList CSSSelectorParser::consumeCompoundSelectorList(CSSParserTokenRange& range)
+{
+ Vector<std::unique_ptr<CSSParserSelector>> selectorList;
+ std::unique_ptr<CSSParserSelector> selector = consumeCompoundSelector(range);
+ range.consumeWhitespace();
+ if (!selector)
+ return CSSSelectorList();
+ selectorList.append(WTFMove(selector));
+ while (!range.atEnd() && range.peek().type() == CommaToken) {
+ range.consumeIncludingWhitespace();
+ selector = consumeCompoundSelector(range);
+ range.consumeWhitespace();
+ if (!selector)
+ return CSSSelectorList();
+ selectorList.append(WTFMove(selector));
+ }
+
+ CSSSelectorList list;
+ if (m_failedParsing)
+ return list;
+ list.adoptSelectorVector(selectorList);
+ return list;
+}
+
+namespace {
+
+enum CompoundSelectorFlags {
+ HasPseudoElementForRightmostCompound = 1 << 0,
+ HasContentPseudoElement = 1 << 1
+};
+
+unsigned extractCompoundFlags(const CSSParserSelector& simpleSelector, CSSParserMode parserMode)
+{
+ if (simpleSelector.match() != CSSSelector::PseudoElement)
+ return 0;
+ // FIXME-NEWPARSER: These don't exist for us, so may need to revisit.
+ // if (simpleSelector.pseudoElementType() == CSSSelector::PseudoContent)
+ // return HasContentPseudoElement;
+ // if (simpleSelector.pseudoElementType() == CSSSelector::PseudoShadow)
+ // return 0;
+
+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=161747
+ // The UASheetMode check is a work-around to allow this selector in mediaControls(New).css:
+ // input[type="range" i]::-webkit-media-slider-container > div {
+ if (parserMode == UASheetMode && simpleSelector.pseudoElementType() == CSSSelector::PseudoElementWebKitCustom)
+ return 0;
+ return HasPseudoElementForRightmostCompound;
+}
+
+} // namespace
+
+std::unique_ptr<CSSParserSelector> CSSSelectorParser::consumeComplexSelector(CSSParserTokenRange& range)
+{
+ std::unique_ptr<CSSParserSelector> selector = consumeCompoundSelector(range);
+ if (!selector)
+ return nullptr;
+
+
+ unsigned previousCompoundFlags = 0;
+
+ for (CSSParserSelector* simple = selector.get(); simple && !previousCompoundFlags; simple = simple->tagHistory())
+ previousCompoundFlags |= extractCompoundFlags(*simple, m_context.mode);
+
+ while (CSSSelector::Relation combinator = consumeCombinator(range)) {
+ std::unique_ptr<CSSParserSelector> nextSelector = consumeCompoundSelector(range);
+ if (!nextSelector)
+ return combinator == CSSSelector::Descendant ? WTFMove(selector) : nullptr;
+ if (previousCompoundFlags & HasPseudoElementForRightmostCompound)
+ return nullptr;
+ CSSParserSelector* end = nextSelector.get();
+ unsigned compoundFlags = extractCompoundFlags(*end, m_context.mode);
+ while (end->tagHistory()) {
+ end = end->tagHistory();
+ compoundFlags |= extractCompoundFlags(*end, m_context.mode);
+ }
+ end->setRelation(combinator);
+ // FIXME-NEWPARSER: Shadow stuff that we don't have.
+ // if (previousCompoundFlags & HasContentPseudoElement)
+ // end->setRelationIsAffectedByPseudoContent();
+ previousCompoundFlags = compoundFlags;
+ end->setTagHistory(WTFMove(selector));
+
+ selector = WTFMove(nextSelector);
+ }
+
+ return selector;
+}
+
+namespace {
+
+bool isScrollbarPseudoClass(CSSSelector::PseudoClassType pseudo)
+{
+ switch (pseudo) {
+ case CSSSelector::PseudoClassEnabled:
+ case CSSSelector::PseudoClassDisabled:
+ case CSSSelector::PseudoClassHover:
+ case CSSSelector::PseudoClassActive:
+ case CSSSelector::PseudoClassHorizontal:
+ case CSSSelector::PseudoClassVertical:
+ case CSSSelector::PseudoClassDecrement:
+ case CSSSelector::PseudoClassIncrement:
+ case CSSSelector::PseudoClassStart:
+ case CSSSelector::PseudoClassEnd:
+ case CSSSelector::PseudoClassDoubleButton:
+ case CSSSelector::PseudoClassSingleButton:
+ case CSSSelector::PseudoClassNoButton:
+ case CSSSelector::PseudoClassCornerPresent:
+ case CSSSelector::PseudoClassWindowInactive:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool isUserActionPseudoClass(CSSSelector::PseudoClassType pseudo)
+{
+ switch (pseudo) {
+ case CSSSelector::PseudoClassHover:
+ case CSSSelector::PseudoClassFocus:
+ case CSSSelector::PseudoClassActive:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool isPseudoClassValidAfterPseudoElement(CSSSelector::PseudoClassType pseudoClass, CSSSelector::PseudoElementType compoundPseudoElement)
+{
+ switch (compoundPseudoElement) {
+ case CSSSelector::PseudoElementResizer:
+ case CSSSelector::PseudoElementScrollbar:
+ case CSSSelector::PseudoElementScrollbarCorner:
+ case CSSSelector::PseudoElementScrollbarButton:
+ case CSSSelector::PseudoElementScrollbarThumb:
+ case CSSSelector::PseudoElementScrollbarTrack:
+ case CSSSelector::PseudoElementScrollbarTrackPiece:
+ return isScrollbarPseudoClass(pseudoClass);
+ case CSSSelector::PseudoElementSelection:
+ return pseudoClass == CSSSelector::PseudoClassWindowInactive;
+ case CSSSelector::PseudoElementWebKitCustom:
+ case CSSSelector::PseudoElementWebKitCustomLegacyPrefixed:
+ return isUserActionPseudoClass(pseudoClass);
+ default:
+ return false;
+ }
+}
+
+bool isSimpleSelectorValidAfterPseudoElement(const CSSParserSelector& simpleSelector, CSSSelector::PseudoElementType compoundPseudoElement)
+{
+ if (compoundPseudoElement == CSSSelector::PseudoElementUnknown)
+ return true;
+ // FIXME-NEWPARSER: This doesn't exist for us.
+ // if (compoundPseudoElement == CSSSelector::PseudoElementContent)
+ // return simpleSelector.match() != CSSSelector::PseudoElement;
+ if (simpleSelector.match() != CSSSelector::PseudoClass)
+ return false;
+ CSSSelector::PseudoClassType pseudo = simpleSelector.pseudoClassType();
+ if (pseudo == CSSSelector::PseudoClassNot) {
+ ASSERT(simpleSelector.selectorList());
+ ASSERT(simpleSelector.selectorList()->first());
+ ASSERT(!simpleSelector.selectorList()->first()->tagHistory());
+ pseudo = simpleSelector.selectorList()->first()->pseudoClassType();
+ }
+ return isPseudoClassValidAfterPseudoElement(pseudo, compoundPseudoElement);
+}
+
+} // namespace
+
+std::unique_ptr<CSSParserSelector> CSSSelectorParser::consumeCompoundSelector(CSSParserTokenRange& range)
+{
+ std::unique_ptr<CSSParserSelector> compoundSelector;
+
+ AtomicString namespacePrefix;
+ AtomicString elementName;
+ CSSSelector::PseudoElementType compoundPseudoElement = CSSSelector::PseudoElementUnknown;
+ if (!consumeName(range, elementName, namespacePrefix)) {
+ compoundSelector = consumeSimpleSelector(range);
+ if (!compoundSelector)
+ return nullptr;
+ if (compoundSelector->match() == CSSSelector::PseudoElement)
+ compoundPseudoElement = compoundSelector->pseudoElementType();
+ }
+ if (m_context.isHTMLDocument)
+ elementName = elementName.convertToASCIILowercase();
+
+ while (std::unique_ptr<CSSParserSelector> simpleSelector = consumeSimpleSelector(range)) {
+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=161747
+ // The UASheetMode check is a work-around to allow this selector in mediaControls(New).css:
+ // video::-webkit-media-text-track-region-container.scrolling
+ if (m_context.mode != UASheetMode && !isSimpleSelectorValidAfterPseudoElement(*simpleSelector.get(), compoundPseudoElement)) {
+ m_failedParsing = true;
+ return nullptr;
+ }
+ if (simpleSelector->match() == CSSSelector::PseudoElement)
+ compoundPseudoElement = simpleSelector->pseudoElementType();
+
+ if (compoundSelector)
+ compoundSelector = addSimpleSelectorToCompound(WTFMove(compoundSelector), WTFMove(simpleSelector));
+ else
+ compoundSelector = WTFMove(simpleSelector);
+ }
+
+ if (!compoundSelector) {
+ AtomicString namespaceURI = determineNamespace(namespacePrefix);
+ if (namespaceURI.isNull()) {
+ m_failedParsing = true;
+ return nullptr;
+ }
+ if (namespaceURI == defaultNamespace())
+ namespacePrefix = nullAtom;
+
+ CSSParserSelector* rawSelector = new CSSParserSelector(QualifiedName(namespacePrefix, elementName, namespaceURI));
+ std::unique_ptr<CSSParserSelector> selector = std::unique_ptr<CSSParserSelector>(rawSelector);
+ return selector;
+ }
+ prependTypeSelectorIfNeeded(namespacePrefix, elementName, compoundSelector.get());
+ return splitCompoundAtImplicitShadowCrossingCombinator(WTFMove(compoundSelector));
+}
+
+std::unique_ptr<CSSParserSelector> CSSSelectorParser::consumeSimpleSelector(CSSParserTokenRange& range)
+{
+ const CSSParserToken& token = range.peek();
+ std::unique_ptr<CSSParserSelector> selector;
+ if (token.type() == HashToken)
+ selector = consumeId(range);
+ else if (token.type() == DelimiterToken && token.delimiter() == '.')
+ selector = consumeClass(range);
+ else if (token.type() == LeftBracketToken)
+ selector = consumeAttribute(range);
+ else if (token.type() == ColonToken)
+ selector = consumePseudo(range);
+ else
+ return nullptr;
+ if (!selector)
+ m_failedParsing = true;
+ return selector;
+}
+
+bool CSSSelectorParser::consumeName(CSSParserTokenRange& range, AtomicString& name, AtomicString& namespacePrefix)
+{
+ name = nullAtom;
+ namespacePrefix = nullAtom;
+
+ const CSSParserToken& firstToken = range.peek();
+ if (firstToken.type() == IdentToken) {
+ name = firstToken.value().toAtomicString();
+ range.consume();
+ } else if (firstToken.type() == DelimiterToken && firstToken.delimiter() == '*') {
+ name = starAtom;
+ range.consume();
+ } else if (firstToken.type() == DelimiterToken && firstToken.delimiter() == '|') {
+ // This is an empty namespace, which'll get assigned this value below
+ name = emptyAtom;
+ } else
+ return false;
+
+ if (range.peek().type() != DelimiterToken || range.peek().delimiter() != '|')
+ return true;
+ range.consume();
+
+ namespacePrefix = name;
+ const CSSParserToken& nameToken = range.consume();
+ if (nameToken.type() == IdentToken) {
+ name = nameToken.value().toAtomicString();
+ } else if (nameToken.type() == DelimiterToken && nameToken.delimiter() == '*')
+ name = starAtom;
+ else {
+ name = nullAtom;
+ namespacePrefix = nullAtom;
+ return false;
+ }
+
+ return true;
+}
+
+std::unique_ptr<CSSParserSelector> CSSSelectorParser::consumeId(CSSParserTokenRange& range)
+{
+ ASSERT(range.peek().type() == HashToken);
+ if (range.peek().getHashTokenType() != HashTokenId)
+ return nullptr;
+ std::unique_ptr<CSSParserSelector> selector = std::unique_ptr<CSSParserSelector>(new CSSParserSelector());
+ selector->setMatch(CSSSelector::Id);
+ AtomicString value = range.consume().value().toAtomicString();
+ selector->setValue(value);
+ return selector;
+}
+
+std::unique_ptr<CSSParserSelector> CSSSelectorParser::consumeClass(CSSParserTokenRange& range)
+{
+ ASSERT(range.peek().type() == DelimiterToken);
+ ASSERT(range.peek().delimiter() == '.');
+ range.consume();
+ if (range.peek().type() != IdentToken)
+ return nullptr;
+ std::unique_ptr<CSSParserSelector> selector = std::unique_ptr<CSSParserSelector>(new CSSParserSelector());
+ selector->setMatch(CSSSelector::Class);
+ AtomicString value = range.consume().value().toAtomicString();
+ selector->setValue(value);
+ return selector;
+}
+
+std::unique_ptr<CSSParserSelector> CSSSelectorParser::consumeAttribute(CSSParserTokenRange& range)
+{
+ ASSERT(range.peek().type() == LeftBracketToken);
+ CSSParserTokenRange block = range.consumeBlock();
+ block.consumeWhitespace();
+
+ AtomicString namespacePrefix;
+ AtomicString attributeName;
+ if (!consumeName(block, attributeName, namespacePrefix))
+ return nullptr;
+ block.consumeWhitespace();
+
+ if (m_context.isHTMLDocument)
+ attributeName = attributeName.convertToASCIILowercase();
+
+ AtomicString namespaceURI = determineNamespace(namespacePrefix);
+ if (namespaceURI.isNull())
+ return nullptr;
+
+ QualifiedName qualifiedName = namespacePrefix.isNull()
+ ? QualifiedName(nullAtom, attributeName, nullAtom)
+ : QualifiedName(namespacePrefix, attributeName, namespaceURI);
+
+ std::unique_ptr<CSSParserSelector> selector = std::unique_ptr<CSSParserSelector>(new CSSParserSelector());
+
+ if (block.atEnd()) {
+ selector->setAttribute(qualifiedName, CSSSelector::CaseSensitive);
+ selector->setMatch(CSSSelector::Set);
+ return selector;
+ }
+
+ selector->setMatch(consumeAttributeMatch(block));
+
+ const CSSParserToken& attributeValue = block.consumeIncludingWhitespace();
+ if (attributeValue.type() != IdentToken && attributeValue.type() != StringToken)
+ return nullptr;
+ selector->setValue(attributeValue.value().toAtomicString());
+ selector->setAttribute(qualifiedName, consumeAttributeFlags(block));
+
+ if (!block.atEnd())
+ return nullptr;
+ return selector;
+}
+
+std::unique_ptr<CSSParserSelector> CSSSelectorParser::consumePseudo(CSSParserTokenRange& range)
+{
+ ASSERT(range.peek().type() == ColonToken);
+ range.consume();
+
+ int colons = 1;
+ if (range.peek().type() == ColonToken) {
+ range.consume();
+ colons++;
+ }
+
+ const CSSParserToken& token = range.peek();
+ if (token.type() != IdentToken && token.type() != FunctionToken)
+ return nullptr;
+
+ std::unique_ptr<CSSParserSelector> selector;
+ StringView value = token.value();
+ if (selector->match() == CSSSelector::PseudoClass)
+ selector = std::unique_ptr<CSSParserSelector>(CSSParserSelector::parsePseudoClassSelectorFromStringView(value));
+ else
+ selector = std::unique_ptr<CSSParserSelector>(CSSParserSelector::parsePseudoElementSelectorFromStringView(value));
+
+ if (!selector || (selector->match() == CSSSelector::PseudoElement && m_disallowPseudoElements))
+ return nullptr;
+
+ if (token.type() == IdentToken) {
+ range.consume();
+ if (selector->pseudoElementType() == CSSSelector::PseudoElementUnknown)
+ return nullptr;
+ return selector;
+ }
+
+ CSSParserTokenRange block = range.consumeBlock();
+ block.consumeWhitespace();
+ if (token.type() != FunctionToken)
+ return nullptr;
+
+ switch (selector->pseudoClassType()) {
+ case CSSSelector::PseudoClassNot: {
+ std::unique_ptr<CSSParserSelector> innerSelector = consumeCompoundSelector(block);
+ block.consumeWhitespace();
+ if (!innerSelector || !block.atEnd())
+ return nullptr;
+ Vector<std::unique_ptr<CSSParserSelector>> selectorVector;
+ selectorVector.append(WTFMove(innerSelector));
+ selector->adoptSelectorVector(selectorVector);
+ return selector;
+ }
+ case CSSSelector::PseudoClassNthChild:
+ case CSSSelector::PseudoClassNthLastChild:
+ case CSSSelector::PseudoClassNthOfType:
+ case CSSSelector::PseudoClassNthLastOfType: {
+ std::pair<int, int> ab;
+ if (!consumeANPlusB(block, ab))
+ return nullptr;
+ block.consumeWhitespace();
+ if (!block.atEnd())
+ return nullptr;
+ selector->setArgument(AtomicString::number(ab.first * ab.second));
+ return selector;
+ }
+ case CSSSelector::PseudoClassLang: {
+ // FIXME: CSS Selectors Level 4 allows :lang(*-foo)
+ const CSSParserToken& ident = block.consumeIncludingWhitespace();
+ if (ident.type() != IdentToken || !block.atEnd())
+ return nullptr;
+ selector->setArgument(ident.value().toAtomicString());
+ return selector;
+ }
+ // FIXME-NEWPARSER: Support :host-context
+ case CSSSelector::PseudoClassAny:
+ case CSSSelector::PseudoClassHost: {
+ DisallowPseudoElementsScope scope(this);
+ std::unique_ptr<CSSSelectorList> selectorList = std::unique_ptr<CSSSelectorList>(new CSSSelectorList());
+ *selectorList = consumeCompoundSelectorList(block);
+ if (!selectorList->isValid() || !block.atEnd())
+ return nullptr;
+ selector->setSelectorList(WTFMove(selectorList));
+ return selector;
+ }
+ default:
+ break;
+ }
+
+ switch (selector->pseudoElementType()) {
+ case CSSSelector::PseudoElementCue: {
+ DisallowPseudoElementsScope scope(this);
+ std::unique_ptr<CSSSelectorList> selectorList = std::unique_ptr<CSSSelectorList>(new CSSSelectorList());
+ *selectorList = consumeCompoundSelectorList(block);
+ if (!selectorList->isValid() || !block.atEnd())
+ return nullptr;
+ selector->setSelectorList(WTFMove(selectorList));
+ return selector;
+ }
+ case CSSSelector::PseudoElementSlotted: {
+ DisallowPseudoElementsScope scope(this);
+
+ std::unique_ptr<CSSParserSelector> innerSelector = consumeCompoundSelector(block);
+ block.consumeWhitespace();
+ if (!innerSelector || !block.atEnd())
+ return nullptr;
+ Vector<std::unique_ptr<CSSParserSelector>> selectorVector;
+ selectorVector.append(WTFMove(innerSelector));
+ selector->adoptSelectorVector(selectorVector);
+ return selector;
+ }
+ default:
+ break;
+ }
+
+ return nullptr;
+}
+
+CSSSelector::Relation CSSSelectorParser::consumeCombinator(CSSParserTokenRange& range)
+{
+ CSSSelector::Relation fallbackResult = CSSSelector::SubSelector;
+ while (range.peek().type() == WhitespaceToken) {
+ range.consume();
+ fallbackResult = CSSSelector::Descendant;
+ }
+
+ if (range.peek().type() != DelimiterToken)
+ return fallbackResult;
+
+ UChar delimiter = range.peek().delimiter();
+
+ if (delimiter == '+' || delimiter == '~' || delimiter == '>') {
+ range.consumeIncludingWhitespace();
+ if (delimiter == '+')
+ return CSSSelector::DirectAdjacent;
+ if (delimiter == '~')
+ return CSSSelector::IndirectAdjacent;
+ return CSSSelector::Child;
+ }
+
+ // Match /deep/
+ if (delimiter != '/')
+ return fallbackResult;
+ range.consume();
+ const CSSParserToken& ident = range.consume();
+ if (ident.type() != IdentToken || !equalIgnoringASCIICase(ident.value(), "deep"))
+ m_failedParsing = true;
+ const CSSParserToken& slash = range.consumeIncludingWhitespace();
+ if (slash.type() != DelimiterToken || slash.delimiter() != '/')
+ m_failedParsing = true;
+ return CSSSelector::ShadowDeep;
+}
+
+CSSSelector::Match CSSSelectorParser::consumeAttributeMatch(CSSParserTokenRange& range)
+{
+ const CSSParserToken& token = range.consumeIncludingWhitespace();
+ switch (token.type()) {
+ case IncludeMatchToken:
+ return CSSSelector::List;
+ case DashMatchToken:
+ return CSSSelector::Hyphen;
+ case PrefixMatchToken:
+ return CSSSelector::Begin;
+ case SuffixMatchToken:
+ return CSSSelector::End;
+ case SubstringMatchToken:
+ return CSSSelector::Contain;
+ case DelimiterToken:
+ if (token.delimiter() == '=')
+ return CSSSelector::Exact;
+ FALLTHROUGH;
+ default:
+ m_failedParsing = true;
+ return CSSSelector::Exact;
+ }
+}
+
+CSSSelector::AttributeMatchType CSSSelectorParser::consumeAttributeFlags(CSSParserTokenRange& range)
+{
+ if (range.peek().type() != IdentToken)
+ return CSSSelector::CaseSensitive;
+ const CSSParserToken& flag = range.consumeIncludingWhitespace();
+ if (equalIgnoringASCIICase(flag.value(), "i"))
+ return CSSSelector::CaseInsensitive;
+ m_failedParsing = true;
+ return CSSSelector::CaseSensitive;
+}
+
+bool CSSSelectorParser::consumeANPlusB(CSSParserTokenRange& range, std::pair<int, int>& result)
+{
+ const CSSParserToken& token = range.consume();
+ if (token.type() == NumberToken && token.numericValueType() == IntegerValueType) {
+ result = std::make_pair(0, static_cast<int>(token.numericValue()));
+ return true;
+ }
+ if (token.type() == IdentToken) {
+ if (equalIgnoringASCIICase(token.value(), "odd")) {
+ result = std::make_pair(2, 1);
+ return true;
+ }
+ if (equalIgnoringASCIICase(token.value(), "even")) {
+ result = std::make_pair(2, 0);
+ return true;
+ }
+ }
+
+ // The 'n' will end up as part of an ident or dimension. For a valid <an+b>,
+ // this will store a string of the form 'n', 'n-', or 'n-123'.
+ String nString;
+
+ if (token.type() == DelimiterToken && token.delimiter() == '+' && range.peek().type() == IdentToken) {
+ result.first = 1;
+ nString = range.consume().value().toString();
+ } else if (token.type() == DimensionToken && token.numericValueType() == IntegerValueType) {
+ result.first = token.numericValue();
+ nString = token.value().toString();
+ } else if (token.type() == IdentToken) {
+ if (token.value()[0] == '-') {
+ result.first = -1;
+ nString = token.value().toString().substring(1);
+ } else {
+ result.first = 1;
+ nString = token.value().toString();
+ }
+ }
+
+ range.consumeWhitespace();
+
+ if (nString.isEmpty() || !isASCIIAlphaCaselessEqual(nString[0], 'n'))
+ return false;
+ if (nString.length() > 1 && nString[1] != '-')
+ return false;
+
+ if (nString.length() > 2) {
+ bool valid;
+ result.second = nString.substring(1).toIntStrict(&valid);
+ return valid;
+ }
+
+ NumericSign sign = nString.length() == 1 ? NoSign : MinusSign;
+ if (sign == NoSign && range.peek().type() == DelimiterToken) {
+ char delimiterSign = range.consumeIncludingWhitespace().delimiter();
+ if (delimiterSign == '+')
+ sign = PlusSign;
+ else if (delimiterSign == '-')
+ sign = MinusSign;
+ else
+ return false;
+ }
+
+ if (sign == NoSign && range.peek().type() != NumberToken) {
+ result.second = 0;
+ return true;
+ }
+
+ const CSSParserToken& b = range.consume();
+ if (b.type() != NumberToken || b.numericValueType() != IntegerValueType)
+ return false;
+ if ((b.numericSign() == NoSign) == (sign == NoSign))
+ return false;
+ result.second = b.numericValue();
+ if (sign == MinusSign)
+ result.second = -result.second;
+ return true;
+}
+
+const AtomicString& CSSSelectorParser::defaultNamespace() const
+{
+ if (!m_styleSheet)
+ return starAtom;
+ return m_styleSheet->defaultNamespace();
+}
+
+const AtomicString& CSSSelectorParser::determineNamespace(const AtomicString& prefix)
+{
+ if (prefix.isNull())
+ return defaultNamespace();
+ if (prefix.isEmpty())
+ return emptyAtom; // No namespace. If an element/attribute has a namespace, we won't match it.
+ if (prefix == starAtom)
+ return starAtom; // We'll match any namespace.
+ if (!m_styleSheet)
+ return nullAtom; // Cannot resolve prefix to namespace without a stylesheet, syntax error.
+ return m_styleSheet->namespaceURIFromPrefix(prefix);
+}
+
+void CSSSelectorParser::prependTypeSelectorIfNeeded(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector* compoundSelector)
+{
+ if (elementName.isNull() && defaultNamespace() == starAtom && !compoundSelector->needsImplicitShadowCombinatorForMatching())
+ return;
+
+ AtomicString determinedElementName = elementName.isNull() ? starAtom : elementName;
+ AtomicString namespaceURI = determineNamespace(namespacePrefix);
+ if (namespaceURI.isNull()) {
+ m_failedParsing = true;
+ return;
+ }
+ AtomicString determinedPrefix = namespacePrefix;
+ if (namespaceURI == defaultNamespace())
+ determinedPrefix = nullAtom;
+ QualifiedName tag = QualifiedName(determinedPrefix, determinedElementName, namespaceURI);
+
+ // *:host/*:host-context never matches, so we can't discard the *,
+ // otherwise we can't tell the difference between *:host and just :host.
+ //
+ // Also, selectors where we use a ShadowPseudo combinator between the
+ // element and the pseudo element for matching (custom pseudo elements,
+ // ::cue, ::shadow), we need a universal selector to set the combinator
+ // (relation) on in the cases where there are no simple selectors preceding
+ // the pseudo element.
+ bool explicitForHost = compoundSelector->isHostPseudoSelector() && !elementName.isNull();
+ if (tag != anyQName() || explicitForHost || compoundSelector->needsImplicitShadowCombinatorForMatching())
+ compoundSelector->prependTagSelector(tag, determinedPrefix == nullAtom && determinedElementName == starAtom && !explicitForHost);
+}
+
+std::unique_ptr<CSSParserSelector> CSSSelectorParser::addSimpleSelectorToCompound(std::unique_ptr<CSSParserSelector> compoundSelector, std::unique_ptr<CSSParserSelector> simpleSelector)
+{
+ compoundSelector->appendTagHistory(CSSSelector::SubSelector, WTFMove(simpleSelector));
+ return compoundSelector;
+}
+
+std::unique_ptr<CSSParserSelector> CSSSelectorParser::splitCompoundAtImplicitShadowCrossingCombinator(std::unique_ptr<CSSParserSelector> compoundSelector)
+{
+ // The tagHistory is a linked list that stores combinator separated compound selectors
+ // from right-to-left. Yet, within a single compound selector, stores the simple selectors
+ // from left-to-right.
+ //
+ // ".a.b > div#id" is stored in a tagHistory as [div, #id, .a, .b], each element in the
+ // list stored with an associated relation (combinator or SubSelector).
+ //
+ // ::cue, ::shadow, and custom pseudo elements have an implicit ShadowPseudo combinator
+ // to their left, which really makes for a new compound selector, yet it's consumed by
+ // the selector parser as a single compound selector.
+ //
+ // Example: input#x::-webkit-clear-button -> [ ::-webkit-clear-button, input, #x ]
+ //
+ // Likewise, ::slotted() pseudo element has an implicit ShadowSlot combinator to its left
+ // for finding matching slot element in other TreeScope.
+ //
+ // Example: slot[name=foo]::slotted(div) -> [ ::slotted(div), slot, [name=foo] ]
+ CSSParserSelector* splitAfter = compoundSelector.get();
+
+ while (splitAfter->tagHistory() && !splitAfter->tagHistory()->needsImplicitShadowCombinatorForMatching())
+ splitAfter = splitAfter->tagHistory();
+
+ if (!splitAfter || !splitAfter->tagHistory())
+ return compoundSelector;
+
+ std::unique_ptr<CSSParserSelector> secondCompound = splitAfter->releaseTagHistory();
+ secondCompound->appendTagHistory(secondCompound->pseudoElementType() == CSSSelector::PseudoElementSlotted ? CSSSelector::ShadowSlot : CSSSelector::ShadowPseudo, WTFMove(compoundSelector));
+ return secondCompound;
+}
+
+} // namespace blink
Added: trunk/Source/WebCore/css/parser/CSSSelectorParser.h (0 => 205660)
--- trunk/Source/WebCore/css/parser/CSSSelectorParser.h (rev 0)
+++ trunk/Source/WebCore/css/parser/CSSSelectorParser.h 2016-09-08 21:09:04 UTC (rev 205660)
@@ -0,0 +1,108 @@
+// 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.
+
+#pragma once
+
+#include "CSSParserTokenRange.h"
+#include "CSSParserValues.h" // FIXME-NEWPARSER Change when CSSParserSelector moves into its own file.
+#include <memory>
+
+namespace WebCore {
+
+struct CSSParserContext;
+class CSSSelectorList;
+class StyleSheetContents;
+
+// FIXME: We should consider building CSSSelectors directly instead of using
+// the intermediate CSSParserSelector.
+class CSSSelectorParser {
+public:
+ static CSSSelectorList parseSelector(CSSParserTokenRange, const CSSParserContext&, StyleSheetContents*);
+
+ static bool consumeANPlusB(CSSParserTokenRange&, std::pair<int, int>&);
+
+private:
+ CSSSelectorParser(const CSSParserContext&, StyleSheetContents*);
+
+ // These will all consume trailing comments if successful
+
+ CSSSelectorList consumeComplexSelectorList(CSSParserTokenRange&);
+ CSSSelectorList consumeCompoundSelectorList(CSSParserTokenRange&);
+
+ std::unique_ptr<CSSParserSelector> consumeComplexSelector(CSSParserTokenRange&);
+ std::unique_ptr<CSSParserSelector> consumeCompoundSelector(CSSParserTokenRange&);
+ // This doesn't include element names, since they're handled specially
+ std::unique_ptr<CSSParserSelector> consumeSimpleSelector(CSSParserTokenRange&);
+
+ bool consumeName(CSSParserTokenRange&, AtomicString& name, AtomicString& namespacePrefix);
+
+ // These will return nullptr when the selector is invalid
+ std::unique_ptr<CSSParserSelector> consumeId(CSSParserTokenRange&);
+ std::unique_ptr<CSSParserSelector> consumeClass(CSSParserTokenRange&);
+ std::unique_ptr<CSSParserSelector> consumePseudo(CSSParserTokenRange&);
+ std::unique_ptr<CSSParserSelector> consumeAttribute(CSSParserTokenRange&);
+
+ CSSSelector::Relation consumeCombinator(CSSParserTokenRange&);
+ CSSSelector::Match consumeAttributeMatch(CSSParserTokenRange&);
+ CSSSelector::AttributeMatchType consumeAttributeFlags(CSSParserTokenRange&);
+
+ const AtomicString& defaultNamespace() const;
+ const AtomicString& determineNamespace(const AtomicString& prefix);
+ void prependTypeSelectorIfNeeded(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector*);
+ static std::unique_ptr<CSSParserSelector> addSimpleSelectorToCompound(std::unique_ptr<CSSParserSelector> compoundSelector, std::unique_ptr<CSSParserSelector> simpleSelector);
+ static std::unique_ptr<CSSParserSelector> splitCompoundAtImplicitShadowCrossingCombinator(std::unique_ptr<CSSParserSelector> compoundSelector);
+
+ const CSSParserContext& m_context;
+ RefPtr<StyleSheetContents> m_styleSheet; // FIXME: Should be const
+
+ bool m_failedParsing = false;
+ bool m_disallowPseudoElements = false;
+
+ class DisallowPseudoElementsScope {
+ WTF_MAKE_NONCOPYABLE(DisallowPseudoElementsScope);
+ public:
+ DisallowPseudoElementsScope(CSSSelectorParser* parser)
+ : m_parser(parser), m_wasDisallowed(m_parser->m_disallowPseudoElements)
+ {
+ m_parser->m_disallowPseudoElements = true;
+ }
+
+ ~DisallowPseudoElementsScope()
+ {
+ m_parser->m_disallowPseudoElements = m_wasDisallowed;
+ }
+
+ private:
+ CSSSelectorParser* m_parser;
+ bool m_wasDisallowed;
+ };
+};
+
+} // namespace WebCore
+
Modified: trunk/Source/WebCore/cssjit/SelectorCompiler.cpp (205659 => 205660)
--- trunk/Source/WebCore/cssjit/SelectorCompiler.cpp 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/cssjit/SelectorCompiler.cpp 2016-09-08 21:09:04 UTC (rev 205660)
@@ -411,6 +411,9 @@
return FragmentRelation::IndirectAdjacent;
case CSSSelector::SubSelector:
case CSSSelector::ShadowDescendant:
+ case CSSSelector::ShadowPseudo:
+ case CSSSelector::ShadowDeep:
+ case CSSSelector::ShadowSlot:
ASSERT_NOT_REACHED();
}
ASSERT_NOT_REACHED();
Modified: trunk/Source/WebCore/dom/StyledElement.cpp (205659 => 205660)
--- trunk/Source/WebCore/dom/StyledElement.cpp 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/dom/StyledElement.cpp 2016-09-08 21:09:04 UTC (rev 205660)
@@ -331,7 +331,7 @@
style = cacheIterator->value->value;
presentationAttributeCacheCleaner().didHitPresentationAttributeCache();
} else {
- style = MutableStyleProperties::create(isSVGElement() ? SVGAttributeMode : CSSQuirksMode);
+ style = MutableStyleProperties::create(isSVGElement() ? SVGAttributeMode : HTMLQuirksMode);
for (const Attribute& attribute : attributesIterator())
collectStyleForPresentationAttribute(attribute.name(), attribute.value(), static_cast<MutableStyleProperties&>(*style));
}
Modified: trunk/Source/WebCore/svg/SVGFontFaceElement.cpp (205659 => 205660)
--- trunk/Source/WebCore/svg/SVGFontFaceElement.cpp 2016-09-08 20:54:24 UTC (rev 205659)
+++ trunk/Source/WebCore/svg/SVGFontFaceElement.cpp 2016-09-08 21:09:04 UTC (rev 205660)
@@ -49,7 +49,7 @@
inline SVGFontFaceElement::SVGFontFaceElement(const QualifiedName& tagName, Document& document)
: SVGElement(tagName, document)
- , m_fontFaceRule(StyleRuleFontFace::create(MutableStyleProperties::create(CSSStrictMode)))
+ , m_fontFaceRule(StyleRuleFontFace::create(MutableStyleProperties::create(HTMLStandardMode)))
, m_fontElement(nullptr)
{
ASSERT(hasTagName(font_faceTag));