Commit 51c2bff2 authored by Jia's avatar Jia Committed by Commit Bot

Implement API for shorthand properties animation and transition.

This cl is a resubmission of an earlier cl (crrev.com/c/549675), which
was reverted to fix a crash on one specific version of Google Pixel.
The difference between this cl and the previous cl is in the
implementation of CSSPropertyAnimationUtils::ConsumeAnimationShorthand:
- The old version is a templated function that uses function callback
  and variable number of args.
- The new version uses a function pointer, which is simpler than a
  callback.

The original crash was not reproducible using the old patch. 
But it is probably better to use function pointers instead of 
a callback function with variable number of bugs. 

Have run this new patch on a pixel phone and there was not crash. 

Bug: 668012
Change-Id: I183df5f3a168fffbed253a8b47b177fa72cd06b4
Reviewed-on: https://chromium-review.googlesource.com/569505
Commit-Queue: Jia Meng <jiameng@chromium.org>
Reviewed-by: default avatarAlan Cutter <alancutter@chromium.org>
Cr-Commit-Position: refs/heads/master@{#487372}
parent b7d775df
...@@ -592,6 +592,7 @@ css_properties("make_core_generated_css_property_apis") { ...@@ -592,6 +592,7 @@ css_properties("make_core_generated_css_property_apis") {
"$blink_core_output_dir/css/properties/CSSPropertyAPIZoom.h", "$blink_core_output_dir/css/properties/CSSPropertyAPIZoom.h",
"$blink_core_output_dir/css/properties/CSSPropertyDescriptor.cpp", "$blink_core_output_dir/css/properties/CSSPropertyDescriptor.cpp",
"$blink_core_output_dir/css/properties/CSSPropertyDescriptor.h", "$blink_core_output_dir/css/properties/CSSPropertyDescriptor.h",
"$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIAnimation.h",
"$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIBorderImage.h", "$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIBorderImage.h",
"$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIBorderRadius.h", "$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIBorderRadius.h",
"$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIBorderSpacing.h", "$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIBorderSpacing.h",
...@@ -608,6 +609,7 @@ css_properties("make_core_generated_css_property_apis") { ...@@ -608,6 +609,7 @@ css_properties("make_core_generated_css_property_apis") {
"$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIScrollSnapMarginBlock.h", "$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIScrollSnapMarginBlock.h",
"$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIScrollSnapMarginInline.h", "$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIScrollSnapMarginInline.h",
"$blink_core_output_dir/css/properties/CSSShorthandPropertyAPITextDecoration.h", "$blink_core_output_dir/css/properties/CSSShorthandPropertyAPITextDecoration.h",
"$blink_core_output_dir/css/properties/CSSShorthandPropertyAPITransition.h",
"$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIWebkitBorderAfter.h", "$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIWebkitBorderAfter.h",
"$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIWebkitBorderBefore.h", "$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIWebkitBorderBefore.h",
"$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIWebkitBorderEnd.h", "$blink_core_output_dir/css/properties/CSSShorthandPropertyAPIWebkitBorderEnd.h",
......
...@@ -506,6 +506,10 @@ blink_core_sources("css") { ...@@ -506,6 +506,10 @@ blink_core_sources("css") {
"properties/CSSPropertyAnimationIterationCountUtils.h", "properties/CSSPropertyAnimationIterationCountUtils.h",
"properties/CSSPropertyAnimationNameUtils.cpp", "properties/CSSPropertyAnimationNameUtils.cpp",
"properties/CSSPropertyAnimationNameUtils.h", "properties/CSSPropertyAnimationNameUtils.h",
"properties/CSSPropertyAnimationTimingFunctionUtils.cpp",
"properties/CSSPropertyAnimationTimingFunctionUtils.h",
"properties/CSSPropertyAnimationUtils.cpp",
"properties/CSSPropertyAnimationUtils.h",
"properties/CSSPropertyBorderImageUtils.cpp", "properties/CSSPropertyBorderImageUtils.cpp",
"properties/CSSPropertyBorderImageUtils.h", "properties/CSSPropertyBorderImageUtils.h",
"properties/CSSPropertyBoxShadowUtils.cpp", "properties/CSSPropertyBoxShadowUtils.cpp",
...@@ -535,6 +539,7 @@ blink_core_sources("css") { ...@@ -535,6 +539,7 @@ blink_core_sources("css") {
"properties/CSSPropertyTransitionPropertyUtils.h", "properties/CSSPropertyTransitionPropertyUtils.h",
"properties/CSSPropertyWebkitBorderWidthUtils.cpp", "properties/CSSPropertyWebkitBorderWidthUtils.cpp",
"properties/CSSPropertyWebkitBorderWidthUtils.h", "properties/CSSPropertyWebkitBorderWidthUtils.h",
"properties/CSSShorthandPropertyAPIAnimation.cpp",
"properties/CSSShorthandPropertyAPIBorderImage.cpp", "properties/CSSShorthandPropertyAPIBorderImage.cpp",
"properties/CSSShorthandPropertyAPIBorderRadius.cpp", "properties/CSSShorthandPropertyAPIBorderRadius.cpp",
"properties/CSSShorthandPropertyAPIBorderSpacing.cpp", "properties/CSSShorthandPropertyAPIBorderSpacing.cpp",
...@@ -551,6 +556,7 @@ blink_core_sources("css") { ...@@ -551,6 +556,7 @@ blink_core_sources("css") {
"properties/CSSShorthandPropertyAPIScrollSnapMarginBlock.cpp", "properties/CSSShorthandPropertyAPIScrollSnapMarginBlock.cpp",
"properties/CSSShorthandPropertyAPIScrollSnapMarginInline.cpp", "properties/CSSShorthandPropertyAPIScrollSnapMarginInline.cpp",
"properties/CSSShorthandPropertyAPITextDecoration.cpp", "properties/CSSShorthandPropertyAPITextDecoration.cpp",
"properties/CSSShorthandPropertyAPITransition.cpp",
"properties/CSSShorthandPropertyAPIWebkitBorderAfter.cpp", "properties/CSSShorthandPropertyAPIWebkitBorderAfter.cpp",
"properties/CSSShorthandPropertyAPIWebkitBorderBefore.cpp", "properties/CSSShorthandPropertyAPIWebkitBorderBefore.cpp",
"properties/CSSShorthandPropertyAPIWebkitBorderEnd.cpp", "properties/CSSShorthandPropertyAPIWebkitBorderEnd.cpp",
......
...@@ -3663,6 +3663,8 @@ ...@@ -3663,6 +3663,8 @@
{ {
name: "animation", name: "animation",
longhands: ["animation-name", "animation-duration", "animation-timing-function", "animation-delay", "animation-iteration-count", "animation-direction", "animation-fill-mode", "animation-play-state"], longhands: ["animation-name", "animation-duration", "animation-timing-function", "animation-delay", "animation-iteration-count", "animation-direction", "animation-fill-mode", "animation-play-state"],
api_class: true,
api_methods: ["parseShorthand"],
}, },
{ {
name: "background", name: "background",
...@@ -3885,6 +3887,8 @@ ...@@ -3885,6 +3887,8 @@
{ {
name: "transition", name: "transition",
longhands: ["transition-property", "transition-duration", "transition-timing-function", "transition-delay"], longhands: ["transition-property", "transition-duration", "transition-timing-function", "transition-delay"],
api_class: true,
api_methods: ["parseShorthand"],
}, },
{ {
name: "-webkit-border-after", name: "-webkit-border-after",
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include "core/css/CSSReflectValue.h" #include "core/css/CSSReflectValue.h"
#include "core/css/CSSShadowValue.h" #include "core/css/CSSShadowValue.h"
#include "core/css/CSSStringValue.h" #include "core/css/CSSStringValue.h"
#include "core/css/CSSTimingFunctionValue.h"
#include "core/css/CSSURIValue.h" #include "core/css/CSSURIValue.h"
#include "core/css/CSSUnicodeRangeValue.h" #include "core/css/CSSUnicodeRangeValue.h"
#include "core/css/CSSUnsetValue.h" #include "core/css/CSSUnsetValue.h"
...@@ -35,8 +34,7 @@ ...@@ -35,8 +34,7 @@
#include "core/css/parser/CSSPropertyParserHelpers.h" #include "core/css/parser/CSSPropertyParserHelpers.h"
#include "core/css/parser/CSSVariableParser.h" #include "core/css/parser/CSSVariableParser.h"
#include "core/css/properties/CSSPropertyAlignmentUtils.h" #include "core/css/properties/CSSPropertyAlignmentUtils.h"
#include "core/css/properties/CSSPropertyAnimationIterationCountUtils.h" #include "core/css/properties/CSSPropertyAnimationTimingFunctionUtils.h"
#include "core/css/properties/CSSPropertyAnimationNameUtils.h"
#include "core/css/properties/CSSPropertyBorderImageUtils.h" #include "core/css/properties/CSSPropertyBorderImageUtils.h"
#include "core/css/properties/CSSPropertyBoxShadowUtils.h" #include "core/css/properties/CSSPropertyBoxShadowUtils.h"
#include "core/css/properties/CSSPropertyDescriptor.h" #include "core/css/properties/CSSPropertyDescriptor.h"
...@@ -311,192 +309,6 @@ static CSSValue* ConsumeLocale(CSSParserTokenRange& range) { ...@@ -311,192 +309,6 @@ static CSSValue* ConsumeLocale(CSSParserTokenRange& range) {
return ConsumeString(range); return ConsumeString(range);
} }
static CSSValue* ConsumeSteps(CSSParserTokenRange& range) {
DCHECK_EQ(range.Peek().FunctionId(), CSSValueSteps);
CSSParserTokenRange range_copy = range;
CSSParserTokenRange args = ConsumeFunction(range_copy);
CSSPrimitiveValue* steps = ConsumePositiveInteger(args);
if (!steps)
return nullptr;
StepsTimingFunction::StepPosition position =
StepsTimingFunction::StepPosition::END;
if (ConsumeCommaIncludingWhitespace(args)) {
switch (args.ConsumeIncludingWhitespace().Id()) {
case CSSValueMiddle:
if (!RuntimeEnabledFeatures::WebAnimationsAPIEnabled())
return nullptr;
position = StepsTimingFunction::StepPosition::MIDDLE;
break;
case CSSValueStart:
position = StepsTimingFunction::StepPosition::START;
break;
case CSSValueEnd:
position = StepsTimingFunction::StepPosition::END;
break;
default:
return nullptr;
}
}
if (!args.AtEnd())
return nullptr;
range = range_copy;
return CSSStepsTimingFunctionValue::Create(steps->GetIntValue(), position);
}
static CSSValue* ConsumeFrames(CSSParserTokenRange& range) {
DCHECK_EQ(range.Peek().FunctionId(), CSSValueFrames);
CSSParserTokenRange range_copy = range;
CSSParserTokenRange args = ConsumeFunction(range_copy);
CSSPrimitiveValue* frames = ConsumePositiveInteger(args);
if (!frames)
return nullptr;
int frames_int = frames->GetIntValue();
if (frames_int <= 1)
return nullptr;
if (!args.AtEnd())
return nullptr;
range = range_copy;
return CSSFramesTimingFunctionValue::Create(frames_int);
}
static CSSValue* ConsumeCubicBezier(CSSParserTokenRange& range) {
DCHECK_EQ(range.Peek().FunctionId(), CSSValueCubicBezier);
CSSParserTokenRange range_copy = range;
CSSParserTokenRange args = ConsumeFunction(range_copy);
double x1, y1, x2, y2;
if (ConsumeNumberRaw(args, x1) && x1 >= 0 && x1 <= 1 &&
ConsumeCommaIncludingWhitespace(args) && ConsumeNumberRaw(args, y1) &&
ConsumeCommaIncludingWhitespace(args) && ConsumeNumberRaw(args, x2) &&
x2 >= 0 && x2 <= 1 && ConsumeCommaIncludingWhitespace(args) &&
ConsumeNumberRaw(args, y2) && args.AtEnd()) {
range = range_copy;
return CSSCubicBezierTimingFunctionValue::Create(x1, y1, x2, y2);
}
return nullptr;
}
static CSSValue* ConsumeAnimationTimingFunction(CSSParserTokenRange& range) {
CSSValueID id = range.Peek().Id();
if (id == CSSValueEase || id == CSSValueLinear || id == CSSValueEaseIn ||
id == CSSValueEaseOut || id == CSSValueEaseInOut ||
id == CSSValueStepStart || id == CSSValueStepEnd ||
id == CSSValueStepMiddle)
return ConsumeIdent(range);
CSSValueID function = range.Peek().FunctionId();
if (function == CSSValueSteps)
return ConsumeSteps(range);
if (RuntimeEnabledFeatures::FramesTimingFunctionEnabled() &&
function == CSSValueFrames) {
return ConsumeFrames(range);
}
if (function == CSSValueCubicBezier)
return ConsumeCubicBezier(range);
return nullptr;
}
static CSSValue* ConsumeAnimationValue(CSSPropertyID property,
CSSParserTokenRange& range,
const CSSParserContext* context,
bool use_legacy_parsing) {
switch (property) {
case CSSPropertyAnimationDelay:
case CSSPropertyTransitionDelay:
return ConsumeTime(range, kValueRangeAll);
case CSSPropertyAnimationDirection:
return ConsumeIdent<CSSValueNormal, CSSValueAlternate, CSSValueReverse,
CSSValueAlternateReverse>(range);
case CSSPropertyAnimationDuration:
case CSSPropertyTransitionDuration:
return ConsumeTime(range, kValueRangeNonNegative);
case CSSPropertyAnimationFillMode:
return ConsumeIdent<CSSValueNone, CSSValueForwards, CSSValueBackwards,
CSSValueBoth>(range);
case CSSPropertyAnimationIterationCount:
return CSSPropertyAnimationIterationCountUtils::
ConsumeAnimationIterationCount(range);
case CSSPropertyAnimationName:
return CSSPropertyAnimationNameUtils::ConsumeAnimationName(
range, context, use_legacy_parsing);
case CSSPropertyAnimationPlayState:
return ConsumeIdent<CSSValueRunning, CSSValuePaused>(range);
case CSSPropertyTransitionProperty:
return CSSPropertyTransitionPropertyUtils::ConsumeTransitionProperty(
range);
case CSSPropertyAnimationTimingFunction:
case CSSPropertyTransitionTimingFunction:
return ConsumeAnimationTimingFunction(range);
default:
NOTREACHED();
return nullptr;
}
}
bool CSSPropertyParser::ConsumeAnimationShorthand(
const StylePropertyShorthand& shorthand,
bool use_legacy_parsing,
bool important) {
const unsigned longhand_count = shorthand.length();
CSSValueList* longhands[8];
DCHECK_LE(longhand_count, 8u);
for (size_t i = 0; i < longhand_count; ++i)
longhands[i] = CSSValueList::CreateCommaSeparated();
do {
bool parsed_longhand[8] = {false};
do {
bool found_property = false;
for (size_t i = 0; i < longhand_count; ++i) {
if (parsed_longhand[i])
continue;
if (CSSValue* value =
ConsumeAnimationValue(shorthand.properties()[i], range_,
context_, use_legacy_parsing)) {
parsed_longhand[i] = true;
found_property = true;
longhands[i]->Append(*value);
break;
}
}
if (!found_property)
return false;
} while (!range_.AtEnd() && range_.Peek().GetType() != kCommaToken);
// TODO(timloh): This will make invalid longhands, see crbug.com/386459
for (size_t i = 0; i < longhand_count; ++i) {
if (!parsed_longhand[i])
longhands[i]->Append(*CSSInitialValue::Create());
parsed_longhand[i] = false;
}
} while (ConsumeCommaIncludingWhitespace(range_));
for (size_t i = 0; i < longhand_count; ++i) {
// TODO(bugsnash): Refactor out the need to check for
// CSSPropertyTransitionProperty here when this is method implemented in the
// property APIs
if (shorthand.properties()[i] == CSSPropertyTransitionProperty &&
!CSSPropertyTransitionPropertyUtils::IsValidPropertyList(*longhands[i]))
return false;
}
for (size_t i = 0; i < longhand_count; ++i) {
AddParsedProperty(shorthand.properties()[i], shorthand.id(), *longhands[i],
important);
}
return range_.AtEnd();
}
static CSSFunctionValue* ConsumeFilterFunction( static CSSFunctionValue* ConsumeFilterFunction(
CSSParserTokenRange& range, CSSParserTokenRange& range,
const CSSParserContext* context) { const CSSParserContext* context) {
...@@ -1216,7 +1028,9 @@ const CSSValue* CSSPropertyParser::ParseSingleValue( ...@@ -1216,7 +1028,9 @@ const CSSValue* CSSPropertyParser::ParseSingleValue(
kValueRangeNonNegative); kValueRangeNonNegative);
case CSSPropertyAnimationTimingFunction: case CSSPropertyAnimationTimingFunction:
case CSSPropertyTransitionTimingFunction: case CSSPropertyTransitionTimingFunction:
return ConsumeCommaSeparatedList(ConsumeAnimationTimingFunction, range_); return ConsumeCommaSeparatedList(CSSPropertyAnimationTimingFunctionUtils::
ConsumeAnimationTimingFunction,
range_);
case CSSPropertyGridColumnGap: case CSSPropertyGridColumnGap:
case CSSPropertyGridRowGap: case CSSPropertyGridRowGap:
return ConsumeLengthOrPercent(range_, context_->Mode(), return ConsumeLengthOrPercent(range_, context_->Mode(),
...@@ -2321,13 +2135,6 @@ bool CSSPropertyParser::ParseShorthand(CSSPropertyID unresolved_property, ...@@ -2321,13 +2135,6 @@ bool CSSPropertyParser::ParseShorthand(CSSPropertyID unresolved_property,
} }
switch (property) { switch (property) {
case CSSPropertyAnimation:
return ConsumeAnimationShorthand(
animationShorthandForParsing(),
unresolved_property == CSSPropertyAliasWebkitAnimation, important);
case CSSPropertyTransition:
return ConsumeAnimationShorthand(transitionShorthandForParsing(), false,
important);
case CSSPropertyTextDecoration: case CSSPropertyTextDecoration:
DCHECK(RuntimeEnabledFeatures::CSS3TextDecorationsEnabled()); DCHECK(RuntimeEnabledFeatures::CSS3TextDecorationsEnabled());
return ConsumeShorthandGreedily(textDecorationShorthand(), important); return ConsumeShorthandGreedily(textDecorationShorthand(), important);
......
...@@ -88,10 +88,6 @@ class CSSPropertyParser { ...@@ -88,10 +88,6 @@ class CSSPropertyParser {
bool Consume2Values(const StylePropertyShorthand&, bool important); bool Consume2Values(const StylePropertyShorthand&, bool important);
bool Consume4Values(const StylePropertyShorthand&, bool important); bool Consume4Values(const StylePropertyShorthand&, bool important);
// Legacy parsing allows <string>s for animation-name
bool ConsumeAnimationShorthand(const StylePropertyShorthand&,
bool use_legacy_parsing,
bool important);
bool ConsumeBackgroundShorthand(const StylePropertyShorthand&, bool ConsumeBackgroundShorthand(const StylePropertyShorthand&,
bool important); bool important);
......
// Copyright 2017 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 "core/css/properties/CSSPropertyAnimationTimingFunctionUtils.h"
#include "core/css/CSSTimingFunctionValue.h"
#include "core/css/parser/CSSPropertyParserHelpers.h"
#include "platform/RuntimeEnabledFeatures.h"
namespace blink {
namespace {
CSSValue* ConsumeSteps(CSSParserTokenRange& range) {
DCHECK_EQ(range.Peek().FunctionId(), CSSValueSteps);
CSSParserTokenRange range_copy = range;
CSSParserTokenRange args =
CSSPropertyParserHelpers::ConsumeFunction(range_copy);
CSSPrimitiveValue* steps =
CSSPropertyParserHelpers::ConsumePositiveInteger(args);
if (!steps)
return nullptr;
StepsTimingFunction::StepPosition position =
StepsTimingFunction::StepPosition::END;
if (CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args)) {
switch (args.ConsumeIncludingWhitespace().Id()) {
case CSSValueMiddle:
if (!RuntimeEnabledFeatures::WebAnimationsAPIEnabled())
return nullptr;
position = StepsTimingFunction::StepPosition::MIDDLE;
break;
case CSSValueStart:
position = StepsTimingFunction::StepPosition::START;
break;
case CSSValueEnd:
position = StepsTimingFunction::StepPosition::END;
break;
default:
return nullptr;
}
}
if (!args.AtEnd())
return nullptr;
range = range_copy;
return CSSStepsTimingFunctionValue::Create(steps->GetIntValue(), position);
}
CSSValue* ConsumeFrames(CSSParserTokenRange& range) {
DCHECK_EQ(range.Peek().FunctionId(), CSSValueFrames);
CSSParserTokenRange range_copy = range;
CSSParserTokenRange args =
CSSPropertyParserHelpers::ConsumeFunction(range_copy);
CSSPrimitiveValue* frames =
CSSPropertyParserHelpers::ConsumePositiveInteger(args);
if (!frames)
return nullptr;
int frames_int = frames->GetIntValue();
if (frames_int <= 1)
return nullptr;
if (!args.AtEnd())
return nullptr;
range = range_copy;
return CSSFramesTimingFunctionValue::Create(frames_int);
}
CSSValue* ConsumeCubicBezier(CSSParserTokenRange& range) {
DCHECK_EQ(range.Peek().FunctionId(), CSSValueCubicBezier);
CSSParserTokenRange range_copy = range;
CSSParserTokenRange args =
CSSPropertyParserHelpers::ConsumeFunction(range_copy);
double x1, y1, x2, y2;
if (CSSPropertyParserHelpers::ConsumeNumberRaw(args, x1) && x1 >= 0 &&
x1 <= 1 &&
CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args) &&
CSSPropertyParserHelpers::ConsumeNumberRaw(args, y1) &&
CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args) &&
CSSPropertyParserHelpers::ConsumeNumberRaw(args, x2) && x2 >= 0 &&
x2 <= 1 &&
CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args) &&
CSSPropertyParserHelpers::ConsumeNumberRaw(args, y2) && args.AtEnd()) {
range = range_copy;
return CSSCubicBezierTimingFunctionValue::Create(x1, y1, x2, y2);
}
return nullptr;
}
} // namespace
CSSValue*
CSSPropertyAnimationTimingFunctionUtils::ConsumeAnimationTimingFunction(
CSSParserTokenRange& range) {
CSSValueID id = range.Peek().Id();
if (id == CSSValueEase || id == CSSValueLinear || id == CSSValueEaseIn ||
id == CSSValueEaseOut || id == CSSValueEaseInOut ||
id == CSSValueStepStart || id == CSSValueStepEnd ||
id == CSSValueStepMiddle)
return CSSPropertyParserHelpers::ConsumeIdent(range);
CSSValueID function = range.Peek().FunctionId();
if (function == CSSValueSteps)
return ConsumeSteps(range);
if (RuntimeEnabledFeatures::FramesTimingFunctionEnabled() &&
function == CSSValueFrames) {
return ConsumeFrames(range);
}
if (function == CSSValueCubicBezier)
return ConsumeCubicBezier(range);
return nullptr;
}
} // namespace blink
// Copyright 2017 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.
#ifndef CSSPropertyAnimationTimingFunctionUtils_h
#define CSSPropertyAnimationTimingFunctionUtils_h
#include "platform/wtf/Allocator.h"
namespace blink {
class CSSParserTokenRange;
class CSSValue;
class CSSPropertyAnimationTimingFunctionUtils {
STATIC_ONLY(CSSPropertyAnimationTimingFunctionUtils);
public:
static CSSValue* ConsumeAnimationTimingFunction(CSSParserTokenRange&);
};
} // namespace blink
#endif // CSSPropertyAnimationTimingFunctionUtils_h
// Copyright 2017 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 "core/css/properties/CSSPropertyAnimationUtils.h"
#include "core/StylePropertyShorthand.h"
#include "core/css/CSSInitialValue.h"
#include "core/css/parser/CSSPropertyParserHelpers.h"
namespace blink {
bool CSSPropertyAnimationUtils::ConsumeAnimationShorthand(
const StylePropertyShorthand& shorthand,
HeapVector<CSSValueList*, kMaxNumAnimationLonghands>& longhands,
ConsumeAnimationItemValue consumeLonghandItem,
CSSParserTokenRange& range,
const CSSParserContext& context,
bool use_legacy_parsing) {
DCHECK(consumeLonghandItem);
const unsigned longhand_count = shorthand.length();
DCHECK_LE(longhand_count, kMaxNumAnimationLonghands);
for (size_t i = 0; i < longhand_count; ++i)
longhands[i] = CSSValueList::CreateCommaSeparated();
do {
bool parsed_longhand[kMaxNumAnimationLonghands] = {false};
do {
bool found_property = false;
for (size_t i = 0; i < longhand_count; ++i) {
if (parsed_longhand[i])
continue;
CSSValue* value = consumeLonghandItem(shorthand.properties()[i], range,
context, use_legacy_parsing);
if (value) {
parsed_longhand[i] = true;
found_property = true;
longhands[i]->Append(*value);
break;
}
}
if (!found_property)
return false;
} while (!range.AtEnd() && range.Peek().GetType() != kCommaToken);
// TODO(timloh): This will make invalid longhands, see crbug.com/386459
for (size_t i = 0; i < longhand_count; ++i) {
if (!parsed_longhand[i])
longhands[i]->Append(*CSSInitialValue::Create());
parsed_longhand[i] = false;
}
} while (CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(range));
return true;
}
} // namespace blink
// Copyright 2017 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.
#ifndef CSSPropertyAnimationUtils_h
#define CSSPropertyAnimationUtils_h
#include "core/CSSPropertyNames.h"
#include "platform/heap/HeapAllocator.h"
#include "platform/wtf/Allocator.h"
namespace blink {
class CSSParserContext;
class CSSParserTokenRange;
class CSSValue;
class CSSValueList;
class StylePropertyShorthand;
constexpr size_t kMaxNumAnimationLonghands = 8;
using ConsumeAnimationItemValue = CSSValue* (*)(CSSPropertyID,
CSSParserTokenRange&,
const CSSParserContext&,
bool use_legacy_parsing);
class CSSPropertyAnimationUtils {
STATIC_ONLY(CSSPropertyAnimationUtils);
public:
static bool ConsumeAnimationShorthand(
const StylePropertyShorthand&,
HeapVector<CSSValueList*, kMaxNumAnimationLonghands>&,
ConsumeAnimationItemValue,
CSSParserTokenRange&,
const CSSParserContext&,
bool use_legacy_parsing);
};
} // namespace blink
#endif // CSSPropertyAnimationUtils_h
// Copyright 2017 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 "core/css/properties/CSSShorthandPropertyAPIAnimation.h"
#include "core/StylePropertyShorthand.h"
#include "core/css/CSSIdentifierValue.h"
#include "core/css/parser/CSSParserContext.h"
#include "core/css/parser/CSSParserLocalContext.h"
#include "core/css/parser/CSSPropertyParserHelpers.h"
#include "core/css/properties/CSSPropertyAnimationIterationCountUtils.h"
#include "core/css/properties/CSSPropertyAnimationNameUtils.h"
#include "core/css/properties/CSSPropertyAnimationTimingFunctionUtils.h"
#include "core/css/properties/CSSPropertyAnimationUtils.h"
namespace blink {
namespace {
// Legacy parsing allows <string>s for animation-name.
CSSValue* ConsumeAnimationValue(CSSPropertyID property,
CSSParserTokenRange& range,
const CSSParserContext& context,
bool use_legacy_parsing) {
switch (property) {
case CSSPropertyAnimationDelay:
return CSSPropertyParserHelpers::ConsumeTime(range, kValueRangeAll);
case CSSPropertyAnimationDirection:
return CSSPropertyParserHelpers::ConsumeIdent<
CSSValueNormal, CSSValueAlternate, CSSValueReverse,
CSSValueAlternateReverse>(range);
case CSSPropertyAnimationDuration:
return CSSPropertyParserHelpers::ConsumeTime(range,
kValueRangeNonNegative);
case CSSPropertyAnimationFillMode:
return CSSPropertyParserHelpers::ConsumeIdent<
CSSValueNone, CSSValueForwards, CSSValueBackwards, CSSValueBoth>(
range);
case CSSPropertyAnimationIterationCount:
return CSSPropertyAnimationIterationCountUtils::
ConsumeAnimationIterationCount(range);
case CSSPropertyAnimationName:
return CSSPropertyAnimationNameUtils::ConsumeAnimationName(
range, &context, use_legacy_parsing);
case CSSPropertyAnimationPlayState:
return CSSPropertyParserHelpers::ConsumeIdent<CSSValueRunning,
CSSValuePaused>(range);
case CSSPropertyAnimationTimingFunction:
return CSSPropertyAnimationTimingFunctionUtils::
ConsumeAnimationTimingFunction(range);
default:
NOTREACHED();
return nullptr;
}
}
} // namespace
bool CSSShorthandPropertyAPIAnimation::parseShorthand(
bool important,
CSSParserTokenRange& range,
const CSSParserContext& context,
bool use_legacy_parsing,
HeapVector<CSSProperty, 256>& properties) {
const StylePropertyShorthand shorthand = animationShorthandForParsing();
const unsigned longhand_count = shorthand.length();
HeapVector<CSSValueList*, kMaxNumAnimationLonghands> longhands(
longhand_count);
if (!CSSPropertyAnimationUtils::ConsumeAnimationShorthand(
shorthand, longhands, ConsumeAnimationValue, range, context,
use_legacy_parsing)) {
return false;
}
for (size_t i = 0; i < longhand_count; ++i) {
CSSPropertyParserHelpers::AddProperty(
shorthand.properties()[i], shorthand.id(), *longhands[i], important,
CSSPropertyParserHelpers::IsImplicitProperty::kNotImplicit, properties);
}
return range.AtEnd();
}
} // namespace blink
// Copyright 2017 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 "core/css/properties/CSSShorthandPropertyAPITransition.h"
#include "core/StylePropertyShorthand.h"
#include "core/css/CSSIdentifierValue.h"
#include "core/css/parser/CSSParserContext.h"
#include "core/css/parser/CSSParserLocalContext.h"
#include "core/css/parser/CSSPropertyParserHelpers.h"
#include "core/css/properties/CSSPropertyAnimationTimingFunctionUtils.h"
#include "core/css/properties/CSSPropertyAnimationUtils.h"
#include "core/css/properties/CSSPropertyTransitionPropertyUtils.h"
namespace blink {
namespace {
CSSValue* ConsumeTransitionValue(CSSPropertyID property,
CSSParserTokenRange& range,
const CSSParserContext&,
bool use_legacy_parsing) {
switch (property) {
case CSSPropertyTransitionDelay:
return CSSPropertyParserHelpers::ConsumeTime(range, kValueRangeAll);
case CSSPropertyTransitionDuration:
return CSSPropertyParserHelpers::ConsumeTime(range,
kValueRangeNonNegative);
case CSSPropertyTransitionProperty:
return CSSPropertyTransitionPropertyUtils::ConsumeTransitionProperty(
range);
case CSSPropertyTransitionTimingFunction:
return CSSPropertyAnimationTimingFunctionUtils::
ConsumeAnimationTimingFunction(range);
default:
NOTREACHED();
return nullptr;
}
}
} // namespace
bool CSSShorthandPropertyAPITransition::parseShorthand(
bool important,
CSSParserTokenRange& range,
const CSSParserContext& context,
bool use_legacy_parsing,
HeapVector<CSSProperty, 256>& properties) {
const StylePropertyShorthand shorthand = transitionShorthandForParsing();
const unsigned longhand_count = shorthand.length();
HeapVector<CSSValueList*, kMaxNumAnimationLonghands> longhands(
longhand_count);
if (!CSSPropertyAnimationUtils::ConsumeAnimationShorthand(
shorthand, longhands, ConsumeTransitionValue, range, context,
use_legacy_parsing)) {
return false;
}
for (size_t i = 0; i < longhand_count; ++i) {
if (shorthand.properties()[i] == CSSPropertyTransitionProperty &&
!CSSPropertyTransitionPropertyUtils::IsValidPropertyList(*longhands[i]))
return false;
}
for (size_t i = 0; i < longhand_count; ++i) {
CSSPropertyParserHelpers::AddProperty(
shorthand.properties()[i], shorthand.id(), *longhands[i], important,
CSSPropertyParserHelpers::IsImplicitProperty::kNotImplicit, properties);
}
return range.AtEnd();
}
} // namespace blink
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment