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

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

Issue 224733011: A sizes attribute parser (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Added invalid length layout test Created 6 years, 8 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 "SizesAttributeParser.h"
7
8 #include "MediaTypeNames.h"
9 #include "core/css/MediaQueryEvaluator.h"
10 #include "core/css/parser/MediaQueryTokenizer.h"
11
12 namespace WebCore {
13
14 unsigned SizesAttributeParser::findEffectiveSize(const String& attribute, PassRe fPtr<MediaValues> mediaValues)
15 {
16 Vector<MediaQueryToken> tokens;
17 SizesAttributeParser parser(mediaValues);
18
19 MediaQueryTokenizer::tokenize(attribute, tokens);
20 if (!parser.parse(tokens))
21 return parser.effectiveSizeDefaultValue();
22 return parser.effectiveSize();
23 }
24
25 bool SizesAttributeParser::calculateLengthInPixels(TokenIterator startToken, Tok enIterator endToken, unsigned& result)
26 {
27 MediaQueryTokenType type = startToken->type();
28 if (type == NumberToken || type == PercentageToken || type == DimensionToken ) {
eseidel 2014/04/14 23:10:13 Would this be clearer returning early instead of a
29 int length;
eseidel 2014/04/14 23:10:13 Can this be negative?
30 RefPtr<CSSPrimitiveValue> primitiveValue = CSSPrimitiveValue::create(sta rtToken->numericValue(), startToken->unitType());
eseidel 2014/04/14 23:10:13 Presumably this only ever runs on the main thread?
31 if (!primitiveValue->isLength())
32 return false;
33 if (m_mediaValues->computeLength(*primitiveValue, length)) {
34 if (length > 0) {
35 result = (unsigned)length;
36 return true;
37 }
38 }
39 }
40 // FIXME - Handle calc() functions here!
41 return false;
42 }
43
44 static void reverseSkipIrrelevantTokens(TokenIterator& token, TokenIterator star tToken)
45 {
46 TokenIterator endToken = token;
47 while (token != startToken && (token->type() == WhitespaceToken || token->ty pe() == CommentToken || token->type() == EOFToken))
48 --token;
49 if (token != endToken)
50 ++token;
51 }
52
53 static void reverseSkipUntilComponentStart(TokenIterator& token, TokenIterator s tartToken)
54 {
55 if (token == startToken)
56 return;
57 --token;
58 if (token->blockType() != MediaQueryToken::BlockEnd)
59 return;
60 unsigned blockLevel = 0;
61 while (token != startToken) {
62 if (token->blockType() == MediaQueryToken::BlockEnd) {
63 ++blockLevel;
64 } else if (token->blockType() == MediaQueryToken::BlockStart) {
65 --blockLevel;
66 if (!blockLevel)
67 break;
68 }
69
70 --token;
71 }
72 }
73
74 bool SizesAttributeParser::mediaConditionMatches(PassRefPtr<MediaQuerySet> media Condition)
75 {
76 // FIXME: How do I handle non-screen media types here?
77 MediaQueryEvaluator mediaQueryEvaluator(MediaTypeNames::screen, *m_mediaValu es);
78 return mediaQueryEvaluator.eval(mediaCondition.get());
79 }
80
81 bool SizesAttributeParser::parseMediaConditionAndLength(TokenIterator startToken , TokenIterator endToken)
82 {
83 TokenIterator lengthTokenStart;
84 TokenIterator lengthTokenEnd;
85
86 reverseSkipIrrelevantTokens(endToken, startToken);
87 lengthTokenEnd = endToken;
88 reverseSkipUntilComponentStart(endToken, startToken);
89 lengthTokenStart = endToken;
90 unsigned length;
91 if (!calculateLengthInPixels(lengthTokenStart, lengthTokenEnd, length))
92 return false;
93 RefPtr<MediaQuerySet> mediaCondition = MediaQueryParser::parseMediaCondition (startToken, endToken);
94 if (mediaCondition && mediaConditionMatches(mediaCondition)) {
95 m_length = length;
96 return true;
97 }
98 return false;
99 }
100
101 bool SizesAttributeParser::parse(Vector<MediaQueryToken>& tokens)
102 {
103 TokenIterator startToken = tokens.begin();
104 TokenIterator endToken;
105 // Split on a comma token, and send the result tokens to be parsed as (media -condition, length) pairs
106 for (TokenIterator token = tokens.begin(); token != tokens.end(); ++token) {
107 if (token->type() == CommaToken) {
108 endToken = token;
109 if (parseMediaConditionAndLength(startToken, endToken))
110 return true;
111 startToken = token;
112 ++startToken;
113 }
114 }
115 endToken = tokens.end();
116 return parseMediaConditionAndLength(startToken, --endToken);
117 }
118
119 unsigned SizesAttributeParser::effectiveSize()
120 {
121 if (m_length)
122 return m_length;
123 return effectiveSizeDefaultValue();
124 }
125
126 unsigned SizesAttributeParser::effectiveSizeDefaultValue()
127 {
128 // Returning the equivalent of "100%"
129 return m_mediaValues->viewportWidth();
130 }
131
132 } // namespace
133
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698