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

Unified 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: Fixed rebase 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/css/parser/SizesAttributeParser.h ('k') | Source/core/css/parser/SizesAttributeParserTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/css/parser/SizesAttributeParser.cpp
diff --git a/Source/core/css/parser/SizesAttributeParser.cpp b/Source/core/css/parser/SizesAttributeParser.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dca1ace194f1a8c0483646db3c29e4f76235657c
--- /dev/null
+++ b/Source/core/css/parser/SizesAttributeParser.cpp
@@ -0,0 +1,134 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "SizesAttributeParser.h"
+
+#include "MediaTypeNames.h"
+#include "core/css/MediaQueryEvaluator.h"
+#include "core/css/parser/MediaQueryTokenizer.h"
+
+namespace WebCore {
+
+unsigned SizesAttributeParser::findEffectiveSize(const String& attribute, PassRefPtr<MediaValues> mediaValues)
+{
+ Vector<MediaQueryToken> tokens;
+ SizesAttributeParser parser(mediaValues);
+
+ MediaQueryTokenizer::tokenize(attribute, tokens);
+ if (!parser.parse(tokens))
+ return parser.effectiveSizeDefaultValue();
+ return parser.effectiveSize();
+}
+
+bool SizesAttributeParser::calculateLengthInPixels(TokenIterator startToken, TokenIterator endToken, unsigned& result)
+{
+ MediaQueryTokenType type = startToken->type();
+ if (type == DimensionToken) {
+ int length;
+ if (!CSSPrimitiveValue::isLength(startToken->unitType()))
+ return false;
+ if (m_mediaValues->computeLength(startToken->numericValue(), startToken->unitType(), length)) {
+ if (length > 0) {
+ result = (unsigned)length;
+ return true;
+ }
+ }
+ }
+ if (type == FunctionToken) {
+ // FIXME - Handle calc() functions here!
+ }
+ return false;
+}
+
+static void reverseSkipIrrelevantTokens(TokenIterator& token, TokenIterator startToken)
+{
+ TokenIterator endToken = token;
+ while (token != startToken && (token->type() == WhitespaceToken || token->type() == CommentToken || token->type() == EOFToken))
+ --token;
+ if (token != endToken)
+ ++token;
+}
+
+static void reverseSkipUntilComponentStart(TokenIterator& token, TokenIterator startToken)
+{
+ if (token == startToken)
+ return;
+ --token;
+ if (token->blockType() != MediaQueryToken::BlockEnd)
+ return;
+ unsigned blockLevel = 0;
+ while (token != startToken) {
+ if (token->blockType() == MediaQueryToken::BlockEnd) {
+ ++blockLevel;
+ } else if (token->blockType() == MediaQueryToken::BlockStart) {
+ --blockLevel;
+ if (!blockLevel)
+ break;
+ }
+
+ --token;
+ }
+}
+
+bool SizesAttributeParser::mediaConditionMatches(PassRefPtr<MediaQuerySet> mediaCondition)
+{
+ // FIXME: How do I handle non-screen media types here?
+ MediaQueryEvaluator mediaQueryEvaluator(MediaTypeNames::screen, *m_mediaValues);
+ return mediaQueryEvaluator.eval(mediaCondition.get());
+}
+
+bool SizesAttributeParser::parseMediaConditionAndLength(TokenIterator startToken, TokenIterator endToken)
+{
+ TokenIterator lengthTokenStart;
+ TokenIterator lengthTokenEnd;
+
+ reverseSkipIrrelevantTokens(endToken, startToken);
+ lengthTokenEnd = endToken;
+ reverseSkipUntilComponentStart(endToken, startToken);
+ lengthTokenStart = endToken;
+ unsigned length;
+ if (!calculateLengthInPixels(lengthTokenStart, lengthTokenEnd, length))
+ return false;
+ RefPtr<MediaQuerySet> mediaCondition = MediaQueryParser::parseMediaCondition(startToken, endToken);
+ if (mediaCondition && mediaConditionMatches(mediaCondition)) {
+ m_length = length;
+ return true;
+ }
+ return false;
+}
+
+bool SizesAttributeParser::parse(Vector<MediaQueryToken>& tokens)
+{
+ TokenIterator startToken = tokens.begin();
+ TokenIterator endToken;
+ // Split on a comma token, and send the result tokens to be parsed as (media-condition, length) pairs
+ for (TokenIterator token = tokens.begin(); token != tokens.end(); ++token) {
+ if (token->type() == CommaToken) {
+ endToken = token;
+ if (parseMediaConditionAndLength(startToken, endToken))
+ return true;
+ startToken = token;
+ ++startToken;
+ }
+ }
+ endToken = tokens.end();
+ return parseMediaConditionAndLength(startToken, --endToken);
+}
+
+unsigned SizesAttributeParser::effectiveSize()
+{
+ if (m_length)
+ return m_length;
+ return effectiveSizeDefaultValue();
+}
+
+unsigned SizesAttributeParser::effectiveSizeDefaultValue()
+{
+ // Returning the equivalent of "100%"
+ return m_mediaValues->viewportWidth();
+}
+
+} // namespace
+
« no previous file with comments | « Source/core/css/parser/SizesAttributeParser.h ('k') | Source/core/css/parser/SizesAttributeParserTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698