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

Unified Diff: third_party/WebKit/Source/core/css/CSSSyntaxDescriptor.cpp

Issue 2330893002: CSS Properties and Values API: Support more syntax strings (Closed)
Patch Set: move some syntax parsing logic into helpers Created 4 years, 3 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 | « third_party/WebKit/Source/core/css/CSSSyntaxDescriptor.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/core/css/CSSSyntaxDescriptor.cpp
diff --git a/third_party/WebKit/Source/core/css/CSSSyntaxDescriptor.cpp b/third_party/WebKit/Source/core/css/CSSSyntaxDescriptor.cpp
index 3ee259ffbd873bef9329faaacd0d18db14a0decb..a35e46a2f0d4fd1edad08375956c10527d53ae8a 100644
--- a/third_party/WebKit/Source/core/css/CSSSyntaxDescriptor.cpp
+++ b/third_party/WebKit/Source/core/css/CSSSyntaxDescriptor.cpp
@@ -8,19 +8,127 @@
#include "core/css/CSSURIValue.h"
#include "core/css/CSSValueList.h"
#include "core/css/CSSVariableReferenceValue.h"
+#include "core/css/parser/CSSParserIdioms.h"
#include "core/css/parser/CSSPropertyParserHelpers.h"
#include "core/css/parser/CSSTokenizer.h"
#include "core/css/parser/CSSVariableParser.h"
+#include "core/html/parser/HTMLParserIdioms.h"
namespace blink {
+void consumeWhitespace(const String& string, size_t& offset)
+{
+ while (isHTMLSpace(string[offset]))
+ offset++;
+}
+
+bool consumeCharacterAndWhitespace(const String& string, char character, size_t& offset)
+{
+ if (string[offset] != character)
+ return false;
+ offset++;
+ consumeWhitespace(string, offset);
+ return true;
+}
+
+CSSSyntaxType parseSyntaxType(String type)
+{
+ // TODO(timloh): Are these supposed to be case sensitive?
+ if (type == "length")
+ return CSSSyntaxType::Length;
+ if (type == "number")
+ return CSSSyntaxType::Number;
+ if (type == "percentage")
+ return CSSSyntaxType::Percentage;
+ if (type == "length-percentage")
+ return CSSSyntaxType::LengthPercentage;
+ if (type == "color")
+ return CSSSyntaxType::Color;
+ if (type == "image")
+ return CSSSyntaxType::Image;
+ if (type == "url")
+ return CSSSyntaxType::Url;
+ if (type == "integer")
+ return CSSSyntaxType::Integer;
+ if (type == "angle")
+ return CSSSyntaxType::Angle;
+ if (type == "time")
+ return CSSSyntaxType::Time;
+ if (type == "resolution")
+ return CSSSyntaxType::Resolution;
+ if (type == "transform-function")
+ return CSSSyntaxType::TransformFunction;
+ if (type == "custom-ident")
+ return CSSSyntaxType::CustomIdent;
+ // Not an Ident, just used to indicate failure
+ return CSSSyntaxType::Ident;
+}
+
+bool consumeSyntaxType(const String& input, size_t& offset, CSSSyntaxType& type)
+{
+ DCHECK_EQ(input[offset], '<');
+ offset++;
+ size_t typeStart = offset;
+ while (offset < input.length() && input[offset] != '>')
+ offset++;
+ if (offset == input.length())
+ return false;
+ type = parseSyntaxType(input.substring(typeStart, offset - typeStart));
+ if (type == CSSSyntaxType::Ident)
+ return false;
+ offset++;
+ return true;
+}
+
+bool consumeSyntaxIdent(const String& input, size_t& offset, String& ident)
+{
+ // TODO(timloh): Are CSS-wide keywords allowed here?
+ size_t identStart = offset;
+ while (isNameCodePoint(input[offset]))
+ offset++;
+ if (offset == identStart)
+ return false;
+ ident = input.substring(identStart, offset - identStart);
+ return true;
+}
+
CSSSyntaxDescriptor::CSSSyntaxDescriptor(String input)
{
- // TODO(timloh): Implement proper parsing
- if (input.contains('*'))
- m_syntaxComponents.append(CSSSyntaxComponent(CSSSyntaxType::TokenStream));
- else
- m_syntaxComponents.append(CSSSyntaxComponent(CSSSyntaxType::Length));
+ size_t offset = 0;
+ consumeWhitespace(input, offset);
+
+ if (consumeCharacterAndWhitespace(input, '*', offset)) {
+ if (offset != input.length())
+ return;
+ m_syntaxComponents.append(CSSSyntaxComponent(CSSSyntaxType::TokenStream, emptyString(), false));
+ return;
+ }
+
+ do {
+ CSSSyntaxType type;
+ String ident;
+ bool success;
+
+ if (input[offset] == '<') {
+ success = consumeSyntaxType(input, offset, type);
+ } else {
+ type = CSSSyntaxType::Ident;
+ success = consumeSyntaxIdent(input, offset, ident);
+ }
+
+ if (!success) {
+ m_syntaxComponents.clear();
+ return;
+ }
+
+ bool repeatable = consumeCharacterAndWhitespace(input, '+', offset);
+ consumeWhitespace(input, offset);
+ m_syntaxComponents.append(CSSSyntaxComponent(type, ident, repeatable));
+
+ } while (consumeCharacterAndWhitespace(input, '|', offset));
+
+ if (offset != input.length())
+ m_syntaxComponents.clear();
}
const CSSValue* consumeSingleType(const CSSSyntaxComponent& syntax, CSSParserTokenRange& range)
@@ -29,8 +137,40 @@ const CSSValue* consumeSingleType(const CSSSyntaxComponent& syntax, CSSParserTok
// TODO(timloh): Calc values need to be normalized
switch (syntax.m_type) {
+ case CSSSyntaxType::Ident:
+ if (range.peek().type() == IdentToken
+ && range.peek().value() == syntax.m_string) {
+ range.consumeIncludingWhitespace();
+ return CSSCustomIdentValue::create(AtomicString(syntax.m_string));
+ }
+ return nullptr;
case CSSSyntaxType::Length:
return consumeLength(range, HTMLStandardMode, ValueRange::ValueRangeAll);
+ case CSSSyntaxType::Number:
+ return consumeNumber(range, ValueRange::ValueRangeAll);
+ case CSSSyntaxType::Percentage:
+ return consumePercent(range, ValueRange::ValueRangeAll);
+ case CSSSyntaxType::LengthPercentage:
+ return consumeLengthOrPercent(range, HTMLStandardMode, ValueRange::ValueRangeAll);
+ case CSSSyntaxType::Color:
+ return consumeColor(range, HTMLStandardMode);
+ case CSSSyntaxType::Image:
+ // TODO(timloh): This probably needs a proper parser context for relative URL resolution.
+ return consumeImage(range, strictCSSParserContext());
+ case CSSSyntaxType::Url:
+ return consumeUrl(range);
+ case CSSSyntaxType::Integer:
+ return consumeInteger(range);
+ case CSSSyntaxType::Angle:
+ return consumeAngle(range);
+ case CSSSyntaxType::Time:
+ return consumeTime(range, ValueRange::ValueRangeAll);
+ case CSSSyntaxType::Resolution:
+ return nullptr; // TODO(timloh): Implement this.
+ case CSSSyntaxType::TransformFunction:
+ return nullptr; // TODO(timloh): Implement this.
+ case CSSSyntaxType::CustomIdent:
+ return consumeCustomIdent(range);
default:
NOTREACHED();
return nullptr;
@@ -40,6 +180,16 @@ const CSSValue* consumeSingleType(const CSSSyntaxComponent& syntax, CSSParserTok
const CSSValue* consumeSyntaxComponent(const CSSSyntaxComponent& syntax, CSSParserTokenRange range)
{
// CSS-wide keywords are already handled by the CSSPropertyParser
+ if (syntax.m_repeatable) {
+ CSSValueList* list = CSSValueList::createSpaceSeparated();
+ while (!range.atEnd()) {
+ const CSSValue* value = consumeSingleType(syntax, range);
+ if (!value)
+ return nullptr;
+ list->append(*value);
+ }
+ return list;
+ }
const CSSValue* result = consumeSingleType(syntax, range);
if (!range.atEnd())
return nullptr;
« no previous file with comments | « third_party/WebKit/Source/core/css/CSSSyntaxDescriptor.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698