| Index: third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
|
| diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
|
| index c21a17aebd834fa25cb8d8ba7f89d1473ed2f51e..e5ea4aa69be8a6d1e0b80ee0e032b8f69f444edb 100644
|
| --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
|
| +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
|
| @@ -1884,34 +1884,98 @@ bool CSSPropertyParser::ConsumeColumns(bool important) {
|
| bool CSSPropertyParser::ConsumeShorthandGreedily(
|
| const StylePropertyShorthand& shorthand,
|
| bool important) {
|
| + return ConsumeShorthandViaLonghand(shorthand, important,
|
| + LonghandsOrder::kNoOrder);
|
| +}
|
| +
|
| +bool CSSPropertyParser::ConsumeShorthandViaLonghand(
|
| + const StylePropertyShorthand& shorthand,
|
| + bool important,
|
| + LonghandsOrder order) {
|
| // Existing shorthands have at most 6 longhands.
|
| DCHECK_LE(shorthand.length(), 6u);
|
| +
|
| + const bool ordered_parsing = order != LonghandsOrder::kNoOrder;
|
| +
|
| const CSSValue* longhands[6] = {nullptr, nullptr, nullptr,
|
| nullptr, nullptr, nullptr};
|
| +
|
| const CSSPropertyID* shorthand_properties = shorthand.properties();
|
| - do {
|
| +
|
| + if (range_.AtEnd()) {
|
| + return false;
|
| + }
|
| +
|
| + // Only set "next" to the next ordered longhand. It will remain 0 for
|
| + // unordered case.
|
| + size_t next = 0;
|
| + // For ordered longhands only. It becomes false when the parser fails to parse
|
| + // a longhand. In this case, we want to stop subsequent parsing immediately.
|
| + bool continue_parsing = true;
|
| +
|
| + while (!range_.AtEnd()) {
|
| + size_t i = next;
|
| bool found_longhand = false;
|
| - for (size_t i = 0; !found_longhand && i < shorthand.length(); ++i) {
|
| - if (longhands[i])
|
| +
|
| + while (i < shorthand.length() && continue_parsing) {
|
| + if (longhands[i]) {
|
| + DCHECK(!ordered_parsing);
|
| + ++i;
|
| continue;
|
| + }
|
| longhands[i] = ParseSingleValue(shorthand_properties[i], shorthand.id());
|
| - if (longhands[i])
|
| + if (longhands[i]) {
|
| found_longhand = true;
|
| + if (ordered_parsing) {
|
| + ++next;
|
| + }
|
| + break;
|
| + }
|
| + if (ordered_parsing) {
|
| + if (i == 0) {
|
| + return false;
|
| + }
|
| + continue_parsing = false;
|
| + break;
|
| + }
|
| + ++i;
|
| }
|
| - if (!found_longhand)
|
| +
|
| + if (!found_longhand && !ordered_parsing) {
|
| return false;
|
| - } while (!range_.AtEnd());
|
| + }
|
| + if (!continue_parsing || next == shorthand.length()) {
|
| + DCHECK_GT(next, 0u);
|
| + break;
|
| + }
|
| + }
|
| +
|
| + if (ordered_parsing) {
|
| + DCHECK(longhands[0]);
|
| + }
|
| +
|
| + std::map<size_t, size_t> default_property_index = {{1u, 0}};
|
| + if (order == LonghandsOrder::kOrderBy4Values) {
|
| + default_property_index[2u] = 0;
|
| + default_property_index[3u] = 1u;
|
| + }
|
|
|
| for (size_t i = 0; i < shorthand.length(); ++i) {
|
| - if (longhands[i]) {
|
| - AddParsedProperty(shorthand_properties[i], shorthand.id(), *longhands[i],
|
| - important);
|
| - } else {
|
| - AddParsedProperty(shorthand_properties[i], shorthand.id(),
|
| - *CSSInitialValue::Create(), important);
|
| + if (!longhands[i]) {
|
| + if (ordered_parsing) {
|
| + std::map<size_t, size_t>::iterator iter =
|
| + default_property_index.find(i);
|
| + DCHECK(iter != default_property_index.end());
|
| + longhands[i] = longhands[iter->second];
|
| + } else {
|
| + longhands[i] = CSSInitialValue::Create();
|
| + }
|
| }
|
| + AddParsedProperty(shorthand_properties[i], shorthand.id(), *longhands[i],
|
| + important);
|
| }
|
| - return true;
|
| +
|
| + return range_.AtEnd();
|
| }
|
|
|
| bool CSSPropertyParser::ConsumeFlex(bool important) {
|
| @@ -2027,51 +2091,14 @@ bool CSSPropertyParser::ConsumeBorder(bool important) {
|
|
|
| bool CSSPropertyParser::Consume2Values(const StylePropertyShorthand& shorthand,
|
| bool important) {
|
| - DCHECK_EQ(shorthand.length(), 2u);
|
| - const CSSPropertyID* longhands = shorthand.properties();
|
| - const CSSValue* start = ParseSingleValue(longhands[0], shorthand.id());
|
| - if (!start)
|
| - return false;
|
| -
|
| - const CSSValue* end = ParseSingleValue(longhands[1], shorthand.id());
|
| - if (!end)
|
| - end = start;
|
| - AddParsedProperty(longhands[0], shorthand.id(), *start, important);
|
| - AddParsedProperty(longhands[1], shorthand.id(), *end, important);
|
| -
|
| - return range_.AtEnd();
|
| + return ConsumeShorthandViaLonghand(shorthand, important,
|
| + LonghandsOrder::kOrderBy2Values);
|
| }
|
|
|
| bool CSSPropertyParser::Consume4Values(const StylePropertyShorthand& shorthand,
|
| bool important) {
|
| - DCHECK_EQ(shorthand.length(), 4u);
|
| - const CSSPropertyID* longhands = shorthand.properties();
|
| - const CSSValue* top = ParseSingleValue(longhands[0], shorthand.id());
|
| - if (!top)
|
| - return false;
|
| -
|
| - const CSSValue* right = ParseSingleValue(longhands[1], shorthand.id());
|
| - const CSSValue* bottom = nullptr;
|
| - const CSSValue* left = nullptr;
|
| - if (right) {
|
| - bottom = ParseSingleValue(longhands[2], shorthand.id());
|
| - if (bottom)
|
| - left = ParseSingleValue(longhands[3], shorthand.id());
|
| - }
|
| -
|
| - if (!right)
|
| - right = top;
|
| - if (!bottom)
|
| - bottom = top;
|
| - if (!left)
|
| - left = right;
|
| -
|
| - AddParsedProperty(longhands[0], shorthand.id(), *top, important);
|
| - AddParsedProperty(longhands[1], shorthand.id(), *right, important);
|
| - AddParsedProperty(longhands[2], shorthand.id(), *bottom, important);
|
| - AddParsedProperty(longhands[3], shorthand.id(), *left, important);
|
| -
|
| - return range_.AtEnd();
|
| + return ConsumeShorthandViaLonghand(shorthand, important,
|
| + LonghandsOrder::kOrderBy4Values);
|
| }
|
|
|
| // TODO(crbug.com/668012): refactor out property specific logic from this method
|
|
|