Diff
Modified: trunk/LayoutTests/ChangeLog (178674 => 178675)
--- trunk/LayoutTests/ChangeLog 2015-01-19 22:15:16 UTC (rev 178674)
+++ trunk/LayoutTests/ChangeLog 2015-01-19 23:09:36 UTC (rev 178675)
@@ -1,3 +1,13 @@
+2015-01-19 Dhi Aurrahman <diorah...@rockybars.com>
+
+ Canonicalization of :lang() should preserve the :lang()'s arguments representations
+ https://bugs.webkit.org/show_bug.cgi?id=139928
+
+ Reviewed by Benjamin Poulain.
+
+ * fast/css/css-lang-selector-with-string-arguments-text-expected.txt:
+ * fast/css/css-lang-selector-with-string-arguments-text.html:
+
2015-01-16 Roger Fong <roger_f...@apple.com>
WebGL2: Support webgl2 context creation.
Modified: trunk/LayoutTests/fast/css/css-lang-selector-with-string-arguments-text-expected.txt (178674 => 178675)
--- trunk/LayoutTests/fast/css/css-lang-selector-with-string-arguments-text-expected.txt 2015-01-19 22:15:16 UTC (rev 178674)
+++ trunk/LayoutTests/fast/css/css-lang-selector-with-string-arguments-text-expected.txt 2015-01-19 23:09:36 UTC (rev 178675)
@@ -3,12 +3,19 @@
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-PASS parseThenSerializeRule(':lang("a") { }') is ':lang(a) { }'
-PASS parseThenSerializeRule(':lang("bb", cc) { }') is ':lang(bb, cc) { }'
-PASS parseThenSerializeRule(':lang("ddd", eee) { }') is ':lang(ddd, eee) { }'
-PASS parseThenSerializeRule(':lang("*-1997") { }') is ':lang(*-1997) { }'
-PASS parseThenSerializeRule(':lang("*-1997", "*-1998") { }') is ':lang(*-1997, *-1998) { }'
-PASS parseThenSerializeRule(':lang("") { }') is ':lang() { }'
+PASS parseThenSerializeRule(':lang("a") { }') is ':lang("a") { }'
+PASS parseThenSerializeRule(':lang("bb", cc) { }') is ':lang("bb", cc) { }'
+PASS parseThenSerializeRule(':lang("ddd", eee) { }') is ':lang("ddd", eee) { }'
+PASS parseThenSerializeRule(':lang("ddd", eee, ffff) { }') is ':lang("ddd", eee, ffff) { }'
+PASS parseThenSerializeRule(':lang("ddd", eee, "ffff") { }') is ':lang("ddd", eee, "ffff") { }'
+PASS parseThenSerializeRule(':lang("*-1997") { }') is ':lang("*-1997") { }'
+PASS parseThenSerializeRule(':lang("*-1997", "*-1998") { }') is ':lang("*-1997", "*-1998") { }'
+PASS parseThenSerializeRule(':lang("*-1997", "*-1998", "*-1999") { }') is ':lang("*-1997", "*-1998", "*-1999") { }'
+PASS parseThenSerializeRule(':lang("") { }') is ':lang("") { }'
+
+PASS parseThenSerializeRule(':lang(foo, "bar", baz) { }') is ':lang(foo, "bar", baz) { }'
+PASS parseThenSerializeRule(':lang(foo, "bar" , baz) { }') is ':lang(foo, "bar", baz) { }'
+PASS parseThenSerializeRule(':lang( foo , "bar" , baz ) { }') is ':lang(foo, "bar", baz) { }'
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/fast/css/css-lang-selector-with-string-arguments-text.html (178674 => 178675)
--- trunk/LayoutTests/fast/css/css-lang-selector-with-string-arguments-text.html 2015-01-19 22:15:16 UTC (rev 178674)
+++ trunk/LayoutTests/fast/css/css-lang-selector-with-string-arguments-text.html 2015-01-19 23:09:36 UTC (rev 178675)
@@ -25,17 +25,24 @@
function testSelectorRoundTrip(selector)
{
- var expected = selector.split('"').join('');
- shouldBe("parseThenSerializeRule('" + selector + " { }')", "'" + expected + " { }'");
+ shouldBe("parseThenSerializeRule('" + selector + " { }')", "'" + selector + " { }'");
}
testSelectorRoundTrip(':lang("a")');
testSelectorRoundTrip(':lang("bb", cc)');
testSelectorRoundTrip(':lang("ddd", eee)');
+testSelectorRoundTrip(':lang("ddd", eee, ffff)');
+testSelectorRoundTrip(':lang("ddd", eee, "ffff")');
testSelectorRoundTrip(':lang("*-1997")');
testSelectorRoundTrip(':lang("*-1997", "*-1998")');
+testSelectorRoundTrip(':lang("*-1997", "*-1998", "*-1999")');
testSelectorRoundTrip(':lang("")');
+debug('');
+
+shouldBe("parseThenSerializeRule(':lang(foo, \"bar\", baz) { }')", "':lang(foo, \"bar\", baz) { }'");
+shouldBe("parseThenSerializeRule(':lang(foo, \"bar\" , baz) { }')", "':lang(foo, \"bar\", baz) { }'");
+shouldBe("parseThenSerializeRule(':lang( foo , \"bar\" , baz ) { }')", "':lang(foo, \"bar\", baz) { }'");
</script>
<script src=""
</body>
Modified: trunk/Source/WebCore/ChangeLog (178674 => 178675)
--- trunk/Source/WebCore/ChangeLog 2015-01-19 22:15:16 UTC (rev 178674)
+++ trunk/Source/WebCore/ChangeLog 2015-01-19 23:09:36 UTC (rev 178675)
@@ -1,3 +1,43 @@
+2015-01-19 Dhi Aurrahman <diorah...@rockybars.com>
+
+ Canonicalization of :lang() should preserve the :lang()'s arguments representations
+ https://bugs.webkit.org/show_bug.cgi?id=139928
+
+ Reviewed by Benjamin Poulain.
+
+ Preserve the representation of IDENT and STRING when serializing the
+ :lang(). For example, :lang(foo,"bar", baz) should be serialize as
+ :lang(foo, "bar", baz) instead of :lang(foo, bar, baz).
+
+ Rename CSSParserSelector::setArgumentList, CSSSelector::setArgumentList
+ and CSSSelector::argumentList to CSSParserSelector::setLangArgumentList,
+ CSSSelector::setLangArgumentList and CSSSelector::langArgumentList
+ respectively, since those methods are being exclusively used in respect
+ with :lang().
+
+ Update the test of serializing :lang() with IDENT and STRING arguments.
+
+ * css/CSSGrammar.y.in:
+ * css/CSSParserValues.cpp:
+ (WebCore::CSSParserSelector::setLangArgumentList):
+ (WebCore::CSSParserSelector::setArgumentList): Deleted.
+ * css/CSSParserValues.h:
+ (WebCore::CSSParserString::tokenType):
+ (WebCore::CSSParserString::setTokenType):
+ * css/CSSSelector.cpp:
+ (WebCore::appendLangArgumentList):
+ (WebCore::CSSSelector::selectorText):
+ (WebCore::CSSSelector::setLangArgumentList):
+ (WebCore::appendArgumentList): Deleted.
+ (WebCore::CSSSelector::setArgumentList): Deleted.
+ * css/CSSSelector.h:
+ (WebCore::CSSSelector::langArgumentList):
+ (WebCore::CSSSelector::argumentList): Deleted.
+ * css/SelectorChecker.cpp:
+ (WebCore::SelectorChecker::checkOne):
+ * css/SelectorCheckerTestFunctions.h:
+ (WebCore::matchesLangPseudoClass):
+
2015-01-16 Roger Fong <roger_f...@apple.com>
WebGL2: Support webgl2 context creation.
Modified: trunk/Source/WebCore/css/CSSGrammar.y.in (178674 => 178675)
--- trunk/Source/WebCore/css/CSSGrammar.y.in 2015-01-19 22:15:16 UTC (rev 178674)
+++ trunk/Source/WebCore/css/CSSGrammar.y.in 2015-01-19 23:09:36 UTC (rev 178675)
@@ -1105,7 +1105,7 @@
;
#if ENABLE_CSS_SELECTORS_LEVEL4
-lang_range: LANGRANGE | IDENT | STRING
+lang_range: LANGRANGE | IDENT | STRING { $$.setTokenType(TokenType::AtomicStringToken); } ;
comma_separated_lang_ranges:
lang_range %prec UNIMPORTANT_TOK {
@@ -1398,7 +1398,7 @@
if ($4) {
auto selector = std::make_unique<CSSParserSelector>();
selector->setMatch(CSSSelector::PseudoClass);
- selector->setArgumentList(*std::unique_ptr<Vector<CSSParserString>>($4));
+ selector->setLangArgumentList(*std::unique_ptr<Vector<CSSParserString>>($4));
selector->setPseudoClassValue($2);
if (selector->pseudoClassType() == CSSSelector::PseudoClassLang)
$$ = selector.release();
Modified: trunk/Source/WebCore/css/CSSParserValues.cpp (178674 => 178675)
--- trunk/Source/WebCore/css/CSSParserValues.cpp 2015-01-19 22:15:16 UTC (rev 178674)
+++ trunk/Source/WebCore/css/CSSParserValues.cpp 2015-01-19 23:09:36 UTC (rev 178675)
@@ -262,14 +262,18 @@
}
#if ENABLE(CSS_SELECTORS_LEVEL4)
-void CSSParserSelector::setArgumentList(Vector<CSSParserString>& stringVector)
+void CSSParserSelector::setLangArgumentList(const Vector<CSSParserString>& stringVector)
{
ASSERT_WITH_MESSAGE(!stringVector.isEmpty(), "No CSS Selector takes an empty argument list.");
- auto argumentList = std::make_unique<Vector<AtomicString>>();
+ auto argumentList = std::make_unique<Vector<LanguageArgument>>();
argumentList->reserveInitialCapacity(stringVector.size());
- for (const AtomicString& argument : stringVector)
- argumentList->append(argument);
- m_selector->setArgumentList(WTF::move(argumentList));
+ for (const CSSParserString& string : stringVector) {
+ LanguageArgument languageArgument;
+ languageArgument.languageRange = string;
+ languageArgument.tokenType = string.tokenType();
+ argumentList->append(languageArgument);
+ }
+ m_selector->setLangArgumentList(WTF::move(argumentList));
}
#endif
Modified: trunk/Source/WebCore/css/CSSParserValues.h (178674 => 178675)
--- trunk/Source/WebCore/css/CSSParserValues.h 2015-01-19 22:15:16 UTC (rev 178674)
+++ trunk/Source/WebCore/css/CSSParserValues.h 2015-01-19 23:09:36 UTC (rev 178675)
@@ -38,6 +38,9 @@
m_data.characters8 = characters;
m_length = length;
m_is8Bit = true;
+#if ENABLE(CSS_SELECTORS_LEVEL4)
+ m_tokenType = TokenType::IdentifierToken;
+#endif
}
void init(UChar* characters, unsigned length)
@@ -45,6 +48,9 @@
m_data.characters16 = characters;
m_length = length;
m_is8Bit = false;
+#if ENABLE(CSS_SELECTORS_LEVEL4)
+ m_tokenType = TokenType::IdentifierToken;
+#endif
}
void init(const String& string)
@@ -57,6 +63,9 @@
m_data.characters16 = const_cast<UChar*>(string.characters16());
m_is8Bit = false;
}
+#if ENABLE(CSS_SELECTORS_LEVEL4)
+ m_tokenType = TokenType::IdentifierToken;
+#endif
}
void clear()
@@ -64,6 +73,9 @@
m_data.characters8 = 0;
m_length = 0;
m_is8Bit = true;
+#if ENABLE(CSS_SELECTORS_LEVEL4)
+ m_tokenType = TokenType::IdentifierToken;
+#endif
}
bool is8Bit() const { return m_is8Bit; }
@@ -75,6 +87,11 @@
unsigned length() const { return m_length; }
void setLength(unsigned length) { m_length = length; }
+#if ENABLE(CSS_SELECTORS_LEVEL4)
+ TokenType tokenType() const { return m_tokenType; }
+ void setTokenType(TokenType tokenType) { m_tokenType = tokenType; }
+#endif
+
void lower();
UChar operator[](unsigned i) const
@@ -101,6 +118,9 @@
} m_data;
unsigned m_length;
bool m_is8Bit;
+#if ENABLE(CSS_SELECTORS_LEVEL4)
+ TokenType m_tokenType;
+#endif
};
struct CSSParserFunction;
@@ -210,7 +230,7 @@
void adoptSelectorVector(Vector<std::unique_ptr<CSSParserSelector>>& selectorVector);
#if ENABLE(CSS_SELECTORS_LEVEL4)
- void setArgumentList(Vector<CSSParserString>& stringVector);
+ void setLangArgumentList(const Vector<CSSParserString>& stringVector);
#endif
void setPseudoClassValue(const CSSParserString& pseudoClassString);
Modified: trunk/Source/WebCore/css/CSSSelector.cpp (178674 => 178675)
--- trunk/Source/WebCore/css/CSSSelector.cpp 2015-01-19 22:15:16 UTC (rev 178674)
+++ trunk/Source/WebCore/css/CSSSelector.cpp 2015-01-19 23:09:36 UTC (rev 178675)
@@ -346,11 +346,17 @@
}
#if ENABLE(CSS_SELECTORS_LEVEL4)
-static void appendArgumentList(StringBuilder& str, const Vector<AtomicString>& argumentList)
+static void appendLangArgumentList(StringBuilder& str, const Vector<LanguageArgument>& argumentList)
{
unsigned argumentListSize = argumentList.size();
for (unsigned i = 0; i < argumentListSize; ++i) {
- str.append(argumentList[i]);
+ const LanguageArgument& argument = argumentList[i];
+ bool isAtomicStringToken = argument.tokenType == TokenType::AtomicStringToken;
+ if (isAtomicStringToken)
+ str.append('"');
+ str.append(argument.languageRange);
+ if (isAtomicStringToken)
+ str.append('"');
if (i != argumentListSize - 1)
str.appendLiteral(", ");
}
@@ -491,8 +497,8 @@
case CSSSelector::PseudoClassLang:
str.appendLiteral(":lang(");
#if ENABLE(CSS_SELECTORS_LEVEL4)
- ASSERT_WITH_MESSAGE(cs->argumentList() && !cs->argumentList()->isEmpty(), "An empty :lang() is invalid and should never be generated by the parser.");
- appendArgumentList(str, *cs->argumentList());
+ ASSERT_WITH_MESSAGE(cs->langArgumentList() && !cs->langArgumentList()->isEmpty(), "An empty :lang() is invalid and should never be generated by the parser.");
+ appendLangArgumentList(str, *cs->langArgumentList());
str.append(')');
#else
appendPseudoClassFunctionTail(str, cs);
@@ -710,10 +716,10 @@
}
#if ENABLE(CSS_SELECTORS_LEVEL4)
-void CSSSelector::setArgumentList(std::unique_ptr<Vector<AtomicString>> argumentList)
+void CSSSelector::setLangArgumentList(std::unique_ptr<Vector<LanguageArgument>> argumentList)
{
createRareData();
- m_data.m_rareData->m_argumentList = WTF::move(argumentList);
+ m_data.m_rareData->m_langArgumentList = WTF::move(argumentList);
}
#endif
Modified: trunk/Source/WebCore/css/CSSSelector.h (178674 => 178675)
--- trunk/Source/WebCore/css/CSSSelector.h 2015-01-19 22:15:16 UTC (rev 178674)
+++ trunk/Source/WebCore/css/CSSSelector.h 2015-01-19 23:09:36 UTC (rev 178675)
@@ -29,6 +29,17 @@
namespace WebCore {
class CSSSelectorList;
+#if ENABLE(CSS_SELECTORS_LEVEL4)
+ enum class TokenType {
+ IdentifierToken = 0,
+ AtomicStringToken
+ };
+
+ struct LanguageArgument {
+ AtomicString languageRange;
+ TokenType tokenType;
+ };
+#endif
enum class SelectorSpecificityIncrement {
ClassA = 0x10000,
ClassB = 0x100,
@@ -222,7 +233,7 @@
const AtomicString& attributeCanonicalLocalName() const;
const AtomicString& argument() const { return m_hasRareData ? m_data.m_rareData->m_argument : nullAtom; }
#if ENABLE(CSS_SELECTORS_LEVEL4)
- const Vector<AtomicString>* argumentList() const { return m_hasRareData ? m_data.m_rareData->m_argumentList.get() : nullptr; }
+ const Vector<LanguageArgument>* langArgumentList() const { return m_hasRareData ? m_data.m_rareData->m_langArgumentList.get() : nullptr; }
#endif
const CSSSelectorList* selectorList() const { return m_hasRareData ? m_data.m_rareData->m_selectorList.get() : nullptr; }
@@ -230,7 +241,7 @@
void setAttribute(const QualifiedName&, bool isCaseInsensitive);
void setArgument(const AtomicString&);
#if ENABLE(CSS_SELECTORS_LEVEL4)
- void setArgumentList(std::unique_ptr<Vector<AtomicString>>);
+ void setLangArgumentList(std::unique_ptr<Vector<LanguageArgument>>);
#endif
void setSelectorList(std::unique_ptr<CSSSelectorList>);
@@ -337,7 +348,7 @@
AtomicString m_attributeCanonicalLocalName;
AtomicString m_argument; // Used for :contains and :nth-*
#if ENABLE(CSS_SELECTORS_LEVEL4)
- std::unique_ptr<Vector<AtomicString>> m_argumentList;
+ std::unique_ptr<Vector<LanguageArgument>> m_langArgumentList;
#endif
std::unique_ptr<CSSSelectorList> m_selectorList; // Used for :-webkit-any and :not
Modified: trunk/Source/WebCore/css/SelectorChecker.cpp (178674 => 178675)
--- trunk/Source/WebCore/css/SelectorChecker.cpp 2015-01-19 22:15:16 UTC (rev 178674)
+++ trunk/Source/WebCore/css/SelectorChecker.cpp 2015-01-19 23:09:36 UTC (rev 178675)
@@ -935,8 +935,8 @@
case CSSSelector::PseudoClassLang:
{
#if ENABLE(CSS_SELECTORS_LEVEL4)
- ASSERT(selector->argumentList() && !selector->argumentList()->isEmpty());
- return matchesLangPseudoClass(element, *selector->argumentList());
+ ASSERT(selector->langArgumentList() && !selector->langArgumentList()->isEmpty());
+ return matchesLangPseudoClass(element, *selector->langArgumentList());
#else
const AtomicString& argument = selector->argument();
if (argument.isNull())
Modified: trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h (178674 => 178675)
--- trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h 2015-01-19 22:15:16 UTC (rev 178674)
+++ trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h 2015-01-19 23:09:36 UTC (rev 178675)
@@ -146,7 +146,7 @@
return false;
}
-inline bool matchesLangPseudoClass(const Element* element, const Vector<AtomicString>& ranges)
+inline bool matchesLangPseudoClass(const Element* element, const Vector<LanguageArgument>& argumentList)
{
ASSERT(element);
@@ -161,14 +161,15 @@
if (language.isEmpty())
return false;
- // Implement basic and extended filterings of given language tags
+ // Implement basic and extended filterings of given language tags
// as specified in www.ietf.org/rfc/rfc4647.txt.
Vector<String> rangeSubtags;
Vector<String> languageSubtags;
language.string().split('-', true, languageSubtags);
- for (const AtomicString& range : ranges) {
+ for (const LanguageArgument& argument : argumentList) {
+ const AtomicString& range = argument.languageRange;
if (range.isEmpty())
continue;