Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(282)

Side by Side Diff: Source/core/css/parser/MediaQueryParser.cpp

Issue 171383002: A thread-safe Media Query Parser (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "config.h"
6 #include "core/css/parser/MediaQueryParser.h"
7
8 #include "core/css/CSSParserValues.h"
9 #include "core/css/MediaList.h"
10 #include "core/css/MediaQuery.h"
11 #include "core/css/MediaQueryExp.h"
12 #include "core/css/parser/NewCSSTokenizer.h"
13
14 namespace WebCore {
15
16 PassRefPtr<MediaQuerySet> MediaQueryParser::parse(String queryString)
17 {
18 MediaQueryParser parser(queryString);
19 return parser.parseImpl();
20 }
21
22 MediaQueryParser::MediaQueryParser(String queryString)
23 : m_state(ReadRestrictor)
24 {
25 NewCSSTokenizer::tokenize(queryString, m_tokens);
26 }
27
28 PassRefPtr<MediaQuerySet> MediaQueryParser::parseImpl()
29 {
30 RefPtr<MediaQuerySet> querySet = MediaQuerySet::create();
31 MediaQuery::Restrictor restrictor = MediaQuery::None;
32 String mediaType("all");
33 OwnPtr<ExpressionVector> expressions = adoptPtr(new ExpressionVector());
34 String mediaFeature;
35 CSSParserValueList valueList;
36 CSSTokenType type;
37
38 for (Vector<CSSToken>::iterator it = m_tokens.begin(); it != m_tokens.end(); ++it) {
39 type = it->type();
40 // FIXME - turn this into a lookup table
41 if (type == WhitespaceToken) {
42 continue;
43 }
44 /*
45 if (type == WhitespaceToken || type == DelimToken) {
46 continue;
47 }
48 */
49 if (m_state <= ReadMediaType) {
50 if (type == LeftParenToken) {
51 m_state = ReadFeature;
52 } else if (type == IdentToken) {
53 if (m_state == ReadRestrictor && it->value() == "not") {
54 restrictor = MediaQuery::Not;
55 m_state = ReadMediaType;
56 } else if (m_state == ReadRestrictor && it->value() == "only") {
57 restrictor = MediaQuery::Only;
58 m_state = ReadMediaType;
59 } else {
60 mediaType = it->value();
61 m_state = ReadAnd;
62 }
63 } else {
64 m_state = SkipTillComma;
65 }
66 } else if (m_state == ReadAnd) {
67 if (type == IdentToken && it->value() == "and") {
68 m_state = ReadFeatureStart;
69 } else if (type == CommaToken) {
70 // Append the current MediaQuery and initialize a new one
71 mediaType.ensure16Bit();
72 querySet->addMediaQuery(adoptPtr(new MediaQuery(restrictor, medi aType, expressions.release())));
73 expressions = adoptPtr(new ExpressionVector());
74 m_state = ReadRestrictor;
75 mediaType = "all";
76 mediaFeature = "";
77 restrictor = MediaQuery::None;
78 valueList.clear();
79 } else {
80 m_state = SkipTillComma;
81 }
82 } else if (m_state == ReadFeatureStart) {
83 if (type == LeftParenToken) {
84 m_state = ReadFeature;
85 } else {
86 m_state = SkipTillComma;
87 }
88 } else if (m_state == ReadFeature) {
89 if (type == IdentToken) {
90 mediaFeature = it->value();
91 m_state = ReadFeatureColon;
92 } else {
93 m_state = SkipTillComma;
94 }
95 } else if (m_state == ReadFeatureColon) {
96 if (type == ColonToken) {
97 m_state = ReadFeatureValue;
98 } else if (type == RightParenToken) {
99 --it;
100 m_state = ReadFeatureEnd;
101 } else {
102 m_state = SkipTillParen;
103 }
104 } else if (m_state == ReadFeatureValue) {
105 // Read the value and unit
106 CSSParserValue value;
107 if (type == NumberToken || type == PercentageToken || type == Dimens ionToken) {
108 value.setFromNumber(it->numericValue(), it->unitType());
109 value.isInt = (it->numericValueType() == IntegerValueType);
110 } else {
111 CSSParserFunction function;
112 function.name.init(it->value());
113 value.setFromFunction(&function);
114 }
115 valueList.addValue(value);
116 m_state = ReadFeatureEnd;
117 } else if (m_state == ReadFeatureEnd) {
118 if (type == RightParenToken) {
119 OwnPtr<MediaQueryExp> expression = MediaQueryExp::create(mediaFe ature, &valueList);
120 if (expression) {
121 expressions->append(expression.release());
122 m_state = ReadAnd;
123 } else {
124 m_state = SkipTillComma;
125 }
126
127 valueList.clear();
128 } else if (type == DelimToken && it->delimiter() == '/') {
129 CSSParserValue value;
130 value.unit = CSSParserValue::Operator;
131 value.iValue = '/';
132 valueList.addValue(value);
133 m_state = ReadFeatureValue;
134 } else {
135 m_state = SkipTillParen;
136 }
137 } else if (m_state == SkipTillComma) {
138 if (type == CommaToken || type == EOFToken) {
139 m_state = ReadRestrictor;
140 mediaType = "all";
141 mediaFeature = "";
142 valueList.clear();
143 expressions = adoptPtr(new ExpressionVector());
144 mediaType.ensure16Bit();
145 querySet->addMediaQuery(adoptPtr(new MediaQuery(MediaQuery::Not, mediaType, nullptr)));
146 restrictor = MediaQuery::None;
147 }
148 // FIXME - Should dump previousely gathered results???
149 } else if (m_state == SkipTillParen) {
150 if (type == RightParenToken) {
151 m_state = ReadAnd;
152 mediaType = "all";
153 restrictor = MediaQuery::Not;
154 mediaFeature = "";
155 expressions = adoptPtr(new ExpressionVector());
156 }
157 // FIXME - Should dump previousely gathered results???
158 }
159 }
160 // Write down the last MQ, if there was one
161 if (restrictor != MediaQuery::None || mediaType != "all" || expressions->siz e() > 0) {
162 mediaType.ensure16Bit();
163 querySet->addMediaQuery(adoptPtr(new MediaQuery(restrictor, mediaType, e xpressions.release())));
164 }
165 return querySet;
166 }
167
168 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698