<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[209314] trunk</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/209314">209314</a></dd>
<dt>Author</dt> <dd>hyatt@apple.com</dd>
<dt>Date</dt> <dd>2016-12-04 16:35:34 -0800 (Sun, 04 Dec 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>[CSS Parser] Eliminate in-place lowercasing in the parser.
https://bugs.webkit.org/show_bug.cgi?id=165368
Reviewed by Darin Adler.
Source/WebCore:
Replace the in-place lowercasing that the parser does with new
mechanisms. In-place lowercasing ruins serialization and doesn't
work on CSS parsed from static strings. It also has the side effect
of mutating strings passed in from JavaScript like for querySelectorAll.
For class/id selectors, we now check if the string is lowercase or not.
If it contains uppercase ASCII characters, then we allocate the RareData
for the selector. RareData now has two fields instead of one for the value,
a matching value (all lowercase in quirks mode), and a serializing value (the
original string). Because this is done at the CSSSelector level, the old
parser has been patched as well for these cases.
In addition, in-place lowercasing was done for pseudo-elements, for
media query features, and for attr(). In all of these cases we do
lowercase converting by first checking if it's needed. Serialization will
not retain the original string in these cases, so we may want to revisit
these cases in the future and apply a solution similar to what we did for
selectors.
* css/CSSGrammar.y.in:
* css/CSSSelector.cpp:
(WebCore::CSSSelector::createRareData):
(WebCore::CSSSelector::selectorText):
(WebCore::CSSSelector::RareData::RareData):
(WebCore::CSSSelector::RareData::~RareData):
* css/CSSSelector.h:
(WebCore::CSSSelector::RareData::create):
(WebCore::CSSSelector::setValue):
(WebCore::CSSSelector::value):
(WebCore::CSSSelector::serializingValue):
* css/MediaQueryExp.cpp:
(WebCore::MediaQueryExpression::MediaQueryExpression):
* css/parser/CSSParserToken.cpp:
(WebCore::convertToASCIILowercaseInPlace): Deleted.
(WebCore::CSSParserToken::convertToASCIILowercaseInPlace): Deleted.
* css/parser/CSSParserToken.h:
* css/parser/CSSParserValues.h:
(WebCore::CSSParserSelector::setValue):
* css/parser/CSSPropertyParser.cpp:
(WebCore::consumeAttr):
* css/parser/CSSSelectorParser.cpp:
(WebCore::CSSSelectorParser::consumeId):
(WebCore::CSSSelectorParser::consumeClass):
(WebCore::CSSSelectorParser::consumePseudo):
* css/parser/MediaQueryParser.cpp:
(WebCore::MediaQueryParser::readFeature):
LayoutTests:
* fast/media/mq-pointer-expected.txt:</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsfastmediamqpointerexpectedtxt">trunk/LayoutTests/fast/media/mq-pointer-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorecssCSSGrammaryin">trunk/Source/WebCore/css/CSSGrammar.y.in</a></li>
<li><a href="#trunkSourceWebCorecssCSSSelectorcpp">trunk/Source/WebCore/css/CSSSelector.cpp</a></li>
<li><a href="#trunkSourceWebCorecssCSSSelectorh">trunk/Source/WebCore/css/CSSSelector.h</a></li>
<li><a href="#trunkSourceWebCorecssMediaQueryExpcpp">trunk/Source/WebCore/css/MediaQueryExp.cpp</a></li>
<li><a href="#trunkSourceWebCorecssparserCSSParserTokencpp">trunk/Source/WebCore/css/parser/CSSParserToken.cpp</a></li>
<li><a href="#trunkSourceWebCorecssparserCSSParserTokenh">trunk/Source/WebCore/css/parser/CSSParserToken.h</a></li>
<li><a href="#trunkSourceWebCorecssparserCSSParserValuesh">trunk/Source/WebCore/css/parser/CSSParserValues.h</a></li>
<li><a href="#trunkSourceWebCorecssparserCSSPropertyParsercpp">trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp</a></li>
<li><a href="#trunkSourceWebCorecssparserCSSSelectorParsercpp">trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp</a></li>
<li><a href="#trunkSourceWebCorecssparserMediaQueryParsercpp">trunk/Source/WebCore/css/parser/MediaQueryParser.cpp</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (209313 => 209314)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-12-04 22:47:02 UTC (rev 209313)
+++ trunk/LayoutTests/ChangeLog        2016-12-05 00:35:34 UTC (rev 209314)
</span><span class="lines">@@ -1,3 +1,12 @@
</span><ins>+2016-12-04 Dave Hyatt <hyatt@apple.com>
+
+ [CSS Parser] Eliminate in-place lowercasing in the parser.
+ https://bugs.webkit.org/show_bug.cgi?id=165368
+
+ Reviewed by Darin Adler.
+
+ * fast/media/mq-pointer-expected.txt:
+
</ins><span class="cx"> 2016-12-04 Matt Baker <mattbaker@apple.com>
</span><span class="cx">
</span><span class="cx"> Web Inspector: Assertion Failures breakpoint should respect global Breakpoints enabled setting
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediamqpointerexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/media/mq-pointer-expected.txt (209313 => 209314)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/media/mq-pointer-expected.txt        2016-12-04 22:47:02 UTC (rev 209313)
+++ trunk/LayoutTests/fast/media/mq-pointer-expected.txt        2016-12-05 00:35:34 UTC (rev 209314)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> Test the (pointer) and (hover) media features. See Bug 87403 for details.
</span><span class="cx">
</span><span class="cx"> Query "(pointer)": true
</span><del>-Query "(pointer)": true
</del><ins>+Query "(Pointer)": true
</ins><span class="cx"> Query "(pointer:none)": false
</span><span class="cx"> Query "(pointer:coarse)": false
</span><span class="cx"> Query "(pointer:coARse)": false
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (209313 => 209314)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-12-04 22:47:02 UTC (rev 209313)
+++ trunk/Source/WebCore/ChangeLog        2016-12-05 00:35:34 UTC (rev 209314)
</span><span class="lines">@@ -1,3 +1,57 @@
</span><ins>+2016-12-04 Dave Hyatt <hyatt@apple.com>
+
+ [CSS Parser] Eliminate in-place lowercasing in the parser.
+ https://bugs.webkit.org/show_bug.cgi?id=165368
+
+ Reviewed by Darin Adler.
+
+ Replace the in-place lowercasing that the parser does with new
+ mechanisms. In-place lowercasing ruins serialization and doesn't
+ work on CSS parsed from static strings. It also has the side effect
+ of mutating strings passed in from JavaScript like for querySelectorAll.
+
+ For class/id selectors, we now check if the string is lowercase or not.
+ If it contains uppercase ASCII characters, then we allocate the RareData
+ for the selector. RareData now has two fields instead of one for the value,
+ a matching value (all lowercase in quirks mode), and a serializing value (the
+ original string). Because this is done at the CSSSelector level, the old
+ parser has been patched as well for these cases.
+
+ In addition, in-place lowercasing was done for pseudo-elements, for
+ media query features, and for attr(). In all of these cases we do
+ lowercase converting by first checking if it's needed. Serialization will
+ not retain the original string in these cases, so we may want to revisit
+ these cases in the future and apply a solution similar to what we did for
+ selectors.
+
+ * css/CSSGrammar.y.in:
+ * css/CSSSelector.cpp:
+ (WebCore::CSSSelector::createRareData):
+ (WebCore::CSSSelector::selectorText):
+ (WebCore::CSSSelector::RareData::RareData):
+ (WebCore::CSSSelector::RareData::~RareData):
+ * css/CSSSelector.h:
+ (WebCore::CSSSelector::RareData::create):
+ (WebCore::CSSSelector::setValue):
+ (WebCore::CSSSelector::value):
+ (WebCore::CSSSelector::serializingValue):
+ * css/MediaQueryExp.cpp:
+ (WebCore::MediaQueryExpression::MediaQueryExpression):
+ * css/parser/CSSParserToken.cpp:
+ (WebCore::convertToASCIILowercaseInPlace): Deleted.
+ (WebCore::CSSParserToken::convertToASCIILowercaseInPlace): Deleted.
+ * css/parser/CSSParserToken.h:
+ * css/parser/CSSParserValues.h:
+ (WebCore::CSSParserSelector::setValue):
+ * css/parser/CSSPropertyParser.cpp:
+ (WebCore::consumeAttr):
+ * css/parser/CSSSelectorParser.cpp:
+ (WebCore::CSSSelectorParser::consumeId):
+ (WebCore::CSSSelectorParser::consumeClass):
+ (WebCore::CSSSelectorParser::consumePseudo):
+ * css/parser/MediaQueryParser.cpp:
+ (WebCore::MediaQueryParser::readFeature):
+
</ins><span class="cx"> 2016-12-04 Gyuyoung Kim <gyuyoung.kim@webkit.org>
</span><span class="cx">
</span><span class="cx"> Fix a build break on EFL since r209303.
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSGrammaryin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSGrammar.y.in (209313 => 209314)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSGrammar.y.in        2016-12-04 22:47:02 UTC (rev 209313)
+++ trunk/Source/WebCore/css/CSSGrammar.y.in        2016-12-05 00:35:34 UTC (rev 209314)
</span><span class="lines">@@ -1214,9 +1214,7 @@
</span><span class="cx"> IDSEL {
</span><span class="cx"> $$ = new CSSParserSelector;
</span><span class="cx"> $$->setMatch(CSSSelector::Id);
</span><del>- if (parser->m_context.mode == HTMLQuirksMode)
- $1.convertToASCIILowercaseInPlace();
- $$->setValue($1);
</del><ins>+ $$->setValue($1, parser->m_context.mode == HTMLQuirksMode);
</ins><span class="cx"> }
</span><span class="cx"> | HEX {
</span><span class="cx"> if ($1[0] >= '0' && $1[0] <= '9')
</span><span class="lines">@@ -1224,9 +1222,7 @@
</span><span class="cx"> else {
</span><span class="cx"> $$ = new CSSParserSelector;
</span><span class="cx"> $$->setMatch(CSSSelector::Id);
</span><del>- if (parser->m_context.mode == HTMLQuirksMode)
- $1.convertToASCIILowercaseInPlace();
- $$->setValue($1);
</del><ins>+ $$->setValue($1, parser->m_context.mode == HTMLQuirksMode);
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx"> | class
</span><span class="lines">@@ -1238,9 +1234,7 @@
</span><span class="cx"> '.' IDENT {
</span><span class="cx"> $$ = new CSSParserSelector;
</span><span class="cx"> $$->setMatch(CSSSelector::Class);
</span><del>- if (parser->m_context.mode == HTMLQuirksMode)
- $2.convertToASCIILowercaseInPlace();
- $$->setValue($2);
</del><ins>+ $$->setValue($2, parser->m_context.mode == HTMLQuirksMode);
</ins><span class="cx"> }
</span><span class="cx"> ;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSSelectorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSSelector.cpp (209313 => 209314)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSSelector.cpp        2016-12-04 22:47:02 UTC (rev 209313)
+++ trunk/Source/WebCore/css/CSSSelector.cpp        2016-12-05 00:35:34 UTC (rev 209314)
</span><span class="lines">@@ -84,7 +84,8 @@
</span><span class="cx"> if (m_hasRareData)
</span><span class="cx"> return;
</span><span class="cx"> // Move the value to the rare data stucture.
</span><del>- m_data.m_rareData = &RareData::create(adoptRef(m_data.m_value)).leakRef();
</del><ins>+ AtomicString value { adoptRef(m_data.m_value) };
+ m_data.m_rareData = &RareData::create(WTFMove(value)).leakRef();
</ins><span class="cx"> m_hasRareData = true;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -406,10 +407,10 @@
</span><span class="cx"> while (true) {
</span><span class="cx"> if (cs->match() == CSSSelector::Id) {
</span><span class="cx"> str.append('#');
</span><del>- serializeIdentifier(cs->value(), str);
</del><ins>+ serializeIdentifier(cs->serializingValue(), str);
</ins><span class="cx"> } else if (cs->match() == CSSSelector::Class) {
</span><span class="cx"> str.append('.');
</span><del>- serializeIdentifier(cs->value(), str);
</del><ins>+ serializeIdentifier(cs->serializingValue(), str);
</ins><span class="cx"> } else if (cs->match() == CSSSelector::PseudoClass) {
</span><span class="cx"> switch (cs->pseudoClassType()) {
</span><span class="cx"> #if ENABLE(FULLSCREEN_API)
</span><span class="lines">@@ -659,7 +660,7 @@
</span><span class="cx"> break;
</span><span class="cx"> default:
</span><span class="cx"> str.appendLiteral("::");
</span><del>- str.append(cs->value());
</del><ins>+ str.append(cs->serializingValue());
</ins><span class="cx"> }
</span><span class="cx"> } else if (cs->isAttributeSelector()) {
</span><span class="cx"> str.append('[');
</span><span class="lines">@@ -696,7 +697,7 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> if (cs->match() != CSSSelector::Set) {
</span><del>- serializeString(cs->value(), str);
</del><ins>+ serializeString(cs->serializingValue(), str);
</ins><span class="cx"> if (cs->attributeValueMatchingIsCaseInsensitive())
</span><span class="cx"> str.appendLiteral(" i]");
</span><span class="cx"> else
</span><span class="lines">@@ -820,8 +821,9 @@
</span><span class="cx"> return m_data.m_rareData->m_b;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-CSSSelector::RareData::RareData(PassRefPtr<AtomicStringImpl> value)
- : m_value(value.leakRef())
</del><ins>+CSSSelector::RareData::RareData(AtomicString&& value)
+ : m_matchingValue(value)
+ , m_serializingValue(value)
</ins><span class="cx"> , m_a(0)
</span><span class="cx"> , m_b(0)
</span><span class="cx"> , m_attribute(anyQName())
</span><span class="lines">@@ -831,8 +833,6 @@
</span><span class="cx">
</span><span class="cx"> CSSSelector::RareData::~RareData()
</span><span class="cx"> {
</span><del>- if (m_value)
- m_value->deref();
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> // a helper function for parsing nth-arguments
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSSelectorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSSelector.h (209313 => 209314)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSSelector.h        2016-12-04 22:47:02 UTC (rev 209313)
+++ trunk/Source/WebCore/css/CSSSelector.h        2016-12-05 00:35:34 UTC (rev 209314)
</span><span class="lines">@@ -233,6 +233,7 @@
</span><span class="cx"> const AtomicString& tagLowercaseLocalName() const;
</span><span class="cx">
</span><span class="cx"> const AtomicString& value() const;
</span><ins>+ const AtomicString& serializingValue() const;
</ins><span class="cx"> const QualifiedName& attribute() const;
</span><span class="cx"> const AtomicString& attributeCanonicalLocalName() const;
</span><span class="cx"> const AtomicString& argument() const { return m_hasRareData ? m_data.m_rareData->m_argument : nullAtom; }
</span><span class="lines">@@ -240,7 +241,7 @@
</span><span class="cx"> const Vector<AtomicString>* langArgumentList() const { return m_hasRareData ? m_data.m_rareData->m_langArgumentList.get() : nullptr; }
</span><span class="cx"> const CSSSelectorList* selectorList() const { return m_hasRareData ? m_data.m_rareData->m_selectorList.get() : nullptr; }
</span><span class="cx">
</span><del>- void setValue(const AtomicString&);
</del><ins>+ void setValue(const AtomicString&, bool matchLowerCase = false);
</ins><span class="cx">
</span><span class="cx"> // FIXME-NEWPARSER: These two methods can go away once the old parser is gone.
</span><span class="cx"> void setAttribute(const QualifiedName&, bool);
</span><span class="lines">@@ -348,13 +349,18 @@
</span><span class="cx"> CSSSelector& operator=(const CSSSelector&);
</span><span class="cx">
</span><span class="cx"> struct RareData : public RefCounted<RareData> {
</span><del>- static Ref<RareData> create(PassRefPtr<AtomicStringImpl> value) { return adoptRef(*new RareData(value)); }
</del><ins>+ static Ref<RareData> create(AtomicString&& value) { return adoptRef(*new RareData(WTFMove(value))); }
</ins><span class="cx"> ~RareData();
</span><span class="cx">
</span><span class="cx"> bool parseNth();
</span><span class="cx"> bool matchNth(int count);
</span><span class="cx">
</span><del>- AtomicStringImpl* m_value; // Plain pointer to keep things uniform with the union.
</del><ins>+ // For quirks mode, class and id are case-insensitive. In the case where uppercase
+ // letters are used in quirks mode, |m_matchingValue| holds the lowercase class/id
+ // and |m_serializingValue| holds the original string.
+ AtomicString m_matchingValue;
+ AtomicString m_serializingValue;
+
</ins><span class="cx"> int m_a; // Used for :nth-*
</span><span class="cx"> int m_b; // Used for :nth-*
</span><span class="cx"> QualifiedName m_attribute; // used for attribute selector
</span><span class="lines">@@ -364,7 +370,7 @@
</span><span class="cx"> std::unique_ptr<CSSSelectorList> m_selectorList; // Used for :matches() and :not().
</span><span class="cx">
</span><span class="cx"> private:
</span><del>- RareData(PassRefPtr<AtomicStringImpl> value);
</del><ins>+ RareData(AtomicString&& value);
</ins><span class="cx"> };
</span><span class="cx"> void createRareData();
</span><span class="cx">
</span><span class="lines">@@ -459,21 +465,24 @@
</span><span class="cx"> || match() == CSSSelector::End;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-inline void CSSSelector::setValue(const AtomicString& value)
</del><ins>+inline void CSSSelector::setValue(const AtomicString& value, bool matchLowerCase)
</ins><span class="cx"> {
</span><span class="cx"> ASSERT(match() != Tag);
</span><ins>+ AtomicString matchingValue = matchLowerCase ? value.convertToASCIILowercase() : value;
+ if (!m_hasRareData && matchingValue != value)
+ createRareData();
+
</ins><span class="cx"> // Need to do ref counting manually for the union.
</span><del>- if (m_hasRareData) {
- if (m_data.m_rareData->m_value)
- m_data.m_rareData->m_value->deref();
- m_data.m_rareData->m_value = value.impl();
- m_data.m_rareData->m_value->ref();
</del><ins>+ if (!m_hasRareData) {
+ if (m_data.m_value)
+ m_data.m_value->deref();
+ m_data.m_value = value.impl();
+ m_data.m_value->ref();
</ins><span class="cx"> return;
</span><span class="cx"> }
</span><del>- if (m_data.m_value)
- m_data.m_value->deref();
- m_data.m_value = value.impl();
- m_data.m_value->ref();
</del><ins>+
+ m_data.m_rareData->m_matchingValue = WTFMove(matchingValue);
+ m_data.m_rareData->m_serializingValue = value;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> inline CSSSelector::CSSSelector()
</span><span class="lines">@@ -567,11 +576,23 @@
</span><span class="cx"> inline const AtomicString& CSSSelector::value() const
</span><span class="cx"> {
</span><span class="cx"> ASSERT(match() != Tag);
</span><ins>+ if (m_hasRareData)
+ return m_data.m_rareData->m_matchingValue;
+
</ins><span class="cx"> // AtomicString is really just an AtomicStringImpl* so the cast below is safe.
</span><del>- // FIXME: Perhaps call sites could be changed to accept AtomicStringImpl?
- return *reinterpret_cast<const AtomicString*>(m_hasRareData ? &m_data.m_rareData->m_value : &m_data.m_value);
</del><ins>+ return *reinterpret_cast<const AtomicString*>(&m_data.m_value);
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+inline const AtomicString& CSSSelector::serializingValue() const
+{
+ ASSERT(match() != Tag);
+ if (m_hasRareData)
+ return m_data.m_rareData->m_serializingValue;
+
+ // AtomicString is really just an AtomicStringImpl* so the cast below is safe.
+ return *reinterpret_cast<const AtomicString*>(&m_data.m_value);
+}
+
</ins><span class="cx"> inline void CSSSelector::setAttributeValueMatchingIsCaseInsensitive(bool isCaseInsensitive)
</span><span class="cx"> {
</span><span class="cx"> ASSERT(isAttributeSelector() && match() != CSSSelector::Set);
</span></span></pre></div>
<a id="trunkSourceWebCorecssMediaQueryExpcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/MediaQueryExp.cpp (209313 => 209314)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/MediaQueryExp.cpp        2016-12-04 22:47:02 UTC (rev 209313)
+++ trunk/Source/WebCore/css/MediaQueryExp.cpp        2016-12-05 00:35:34 UTC (rev 209314)
</span><span class="lines">@@ -289,7 +289,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> MediaQueryExpression::MediaQueryExpression(const String& feature, const Vector<CSSParserToken, 4>& tokenList)
</span><del>- : m_mediaFeature(feature)
</del><ins>+ : m_mediaFeature(feature.convertToASCIILowercase())
</ins><span class="cx"> , m_isValid(false)
</span><span class="cx"> {
</span><span class="cx"> // Create value for media query expression that must have 1 or more values.
</span></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSParserTokencpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/parser/CSSParserToken.cpp (209313 => 209314)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/CSSParserToken.cpp        2016-12-04 22:47:02 UTC (rev 209313)
+++ trunk/Source/WebCore/css/parser/CSSParserToken.cpp        2016-12-05 00:35:34 UTC (rev 209314)
</span><span class="lines">@@ -476,23 +476,4 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>-template<typename CharacterType> ALWAYS_INLINE static void convertToASCIILowercaseInPlace(CharacterType* characters, unsigned length)
-{
- for (unsigned i = 0; i < length; ++i)
- characters[i] = toASCIILower(characters[i]);
-}
-
-// FIXME-NEWPARSER: Would like to get rid of this operation. Blink uses HTMLParser static lowercase
-// string hashing, but we don't have that code in our HTMLParser.
-void CSSParserToken::convertToASCIILowercaseInPlace()
-{
- if (!hasStringBacking())
- return;
-
- if (m_valueIs8Bit)
- WebCore::convertToASCIILowercaseInPlace(static_cast<LChar*>(m_valueDataCharRaw), m_valueLength);
- else
- WebCore::convertToASCIILowercaseInPlace(static_cast<UChar*>(m_valueDataCharRaw), m_valueLength);
-}
-
</del><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSParserTokenh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/parser/CSSParserToken.h (209313 => 209314)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/CSSParserToken.h        2016-12-04 22:47:02 UTC (rev 209313)
+++ trunk/Source/WebCore/css/parser/CSSParserToken.h        2016-12-05 00:35:34 UTC (rev 209314)
</span><span class="lines">@@ -121,8 +121,6 @@
</span><span class="cx"> return StringView(static_cast<const UChar*>(m_valueDataCharRaw), m_valueLength);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- void convertToASCIILowercaseInPlace();
-
</del><span class="cx"> UChar delimiter() const;
</span><span class="cx"> NumericSign numericSign() const;
</span><span class="cx"> NumericValueType numericValueType() const;
</span></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSParserValuesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/parser/CSSParserValues.h (209313 => 209314)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/CSSParserValues.h        2016-12-04 22:47:02 UTC (rev 209313)
+++ trunk/Source/WebCore/css/parser/CSSParserValues.h        2016-12-05 00:35:34 UTC (rev 209314)
</span><span class="lines">@@ -218,7 +218,7 @@
</span><span class="cx">
</span><span class="cx"> std::unique_ptr<CSSSelector> releaseSelector() { return WTFMove(m_selector); }
</span><span class="cx">
</span><del>- void setValue(const AtomicString& value) { m_selector->setValue(value); }
</del><ins>+ void setValue(const AtomicString& value, bool matchLowerCase = false) { m_selector->setValue(value, matchLowerCase); }
</ins><span class="cx">
</span><span class="cx"> // FIXME-NEWPARSER: These two methods can go away once old parser is gone.
</span><span class="cx"> void setAttribute(const QualifiedName& value, bool isCaseInsensitive) { m_selector->setAttribute(value, isCaseInsensitive); }
</span></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSPropertyParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp (209313 => 209314)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp        2016-12-04 22:47:02 UTC (rev 209313)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp        2016-12-05 00:35:34 UTC (rev 209314)
</span><span class="lines">@@ -2122,10 +2122,10 @@
</span><span class="cx"> return nullptr;
</span><span class="cx">
</span><span class="cx"> CSSParserToken token = args.consumeIncludingWhitespace();
</span><ins>+ auto attrName = token.value().toAtomicString();
</ins><span class="cx"> if (context.isHTMLDocument)
</span><del>- token.convertToASCIILowercaseInPlace();
</del><ins>+ attrName = attrName.convertToASCIILowercase();
</ins><span class="cx">
</span><del>- String attrName = token.value().toString();
</del><span class="cx"> if (!args.atEnd())
</span><span class="cx"> return nullptr;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSSelectorParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp (209313 => 209314)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp        2016-12-04 22:47:02 UTC (rev 209313)
+++ trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp        2016-12-05 00:35:34 UTC (rev 209314)
</span><span class="lines">@@ -389,10 +389,7 @@
</span><span class="cx"> // FIXME-NEWPARSER: Avoid having to do this, but the old parser does and we need
</span><span class="cx"> // to be compatible for now.
</span><span class="cx"> CSSParserToken token = range.consume();
</span><del>- if (m_context.mode == HTMLQuirksMode)
- token.convertToASCIILowercaseInPlace();
- selector->setValue(token.value().toAtomicString());
-
</del><ins>+ selector->setValue(token.value().toAtomicString(), m_context.mode == HTMLQuirksMode);
</ins><span class="cx"> return selector;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -409,9 +406,7 @@
</span><span class="cx"> // FIXME-NEWPARSER: Avoid having to do this, but the old parser does and we need
</span><span class="cx"> // to be compatible for now.
</span><span class="cx"> CSSParserToken token = range.consume();
</span><del>- if (m_context.mode == HTMLQuirksMode)
- token.convertToASCIILowercaseInPlace();
- selector->setValue(token.value().toAtomicString());
</del><ins>+ selector->setValue(token.value().toAtomicString(), m_context.mode == HTMLQuirksMode);
</ins><span class="cx">
</span><span class="cx"> return selector;
</span><span class="cx"> }
</span><span class="lines">@@ -512,19 +507,17 @@
</span><span class="cx">
</span><span class="cx"> std::unique_ptr<CSSParserSelector> selector;
</span><span class="cx">
</span><del>- // FIXME-NEWPARSER: Would like to eliminate this.
- const_cast<CSSParserToken&>(token).convertToASCIILowercaseInPlace();
</del><ins>+ auto lowercasedValue = token.value().toString().convertToASCIILowercase();
+ auto value = StringView { lowercasedValue };
</ins><span class="cx">
</span><del>- StringView value = token.value();
-
</del><span class="cx"> // FIXME-NEWPARSER: We can't change the pseudoclass/element maps that the old parser
</span><span class="cx"> // uses without breaking it; this hack allows function selectors to work. When the new
</span><span class="cx"> // parser turns on, we can patch the map and remove this code.
</span><span class="cx"> String newValue;
</span><span class="cx"> if (token.type() == FunctionToken && colons == 1) {
</span><del>- String tokenString = value.toString();
- if (!tokenString.startsWithIgnoringASCIICase("host")) {
- newValue = value.toString() + "(";
</del><ins>+ auto tokenString = value.toString();
+ if (!value.startsWithIgnoringASCIICase(StringView { "host" })) {
+ newValue = makeString(value, '(');
</ins><span class="cx"> value = newValue;
</span><span class="cx"> }
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorecssparserMediaQueryParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/parser/MediaQueryParser.cpp (209313 => 209314)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/MediaQueryParser.cpp        2016-12-04 22:47:02 UTC (rev 209313)
+++ trunk/Source/WebCore/css/parser/MediaQueryParser.cpp        2016-12-05 00:35:34 UTC (rev 209314)
</span><span class="lines">@@ -166,8 +166,6 @@
</span><span class="cx"> void MediaQueryParser::readFeature(CSSParserTokenType type, const CSSParserToken& token)
</span><span class="cx"> {
</span><span class="cx"> if (type == IdentToken) {
</span><del>- // FIXME-NEWPARSER: Find a way to avoid this.
- const_cast<CSSParserToken&>(token).convertToASCIILowercaseInPlace();
</del><span class="cx"> m_mediaQueryData.setMediaFeature(token.value().toString());
</span><span class="cx"> m_state = ReadFeatureColon;
</span><span class="cx"> } else
</span></span></pre>
</div>
</div>
</body>
</html>