Merge from Chromium at DEPS revision 261286
This commit was generated by merge_to_master.py.
Change-Id: I756d37445fd7f470b1689ad81318e715d4244987
diff --git a/Source/core/css/CSSBasicShapes.cpp b/Source/core/css/CSSBasicShapes.cpp
index 876d8b6..72bfcef 100644
--- a/Source/core/css/CSSBasicShapes.cpp
+++ b/Source/core/css/CSSBasicShapes.cpp
@@ -41,7 +41,7 @@
DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CSSBasicShape)
-static String buildCircleString(const String& radius, const String& centerX, const String& centerY, const String& layoutBox)
+static String buildCircleString(const String& radius, const String& centerX, const String& centerY, const String& box)
{
char at[] = "at";
char separator[] = " ";
@@ -60,9 +60,9 @@
result.append(centerY);
}
result.append(")");
- if (layoutBox.length()) {
+ if (box.length()) {
result.appendLiteral(separator);
- result.append(layoutBox);
+ result.append(box);
}
return result.toString();
}
@@ -117,7 +117,7 @@
return buildCircleString(m_radius ? m_radius->cssText() : String(),
serializePositionOffset(*normalizedCX->getPairValue(), *normalizedCY->getPairValue()),
serializePositionOffset(*normalizedCY->getPairValue(), *normalizedCX->getPairValue()),
- m_layoutBox ? m_layoutBox->cssText() : String());
+ m_referenceBox ? m_referenceBox->cssText() : String());
}
bool CSSBasicShapeCircle::equals(const CSSBasicShape& shape) const
@@ -129,7 +129,7 @@
return compareCSSValuePtr(m_centerX, other.m_centerX)
&& compareCSSValuePtr(m_centerY, other.m_centerY)
&& compareCSSValuePtr(m_radius, other.m_radius)
- && compareCSSValuePtr(m_layoutBox, other.m_layoutBox);
+ && compareCSSValuePtr(m_referenceBox, other.m_referenceBox);
}
void CSSBasicShapeCircle::trace(Visitor* visitor)
@@ -184,7 +184,7 @@
m_radiusY ? m_radiusY->cssText() : String(),
serializePositionOffset(*normalizedCX->getPairValue(), *normalizedCY->getPairValue()),
serializePositionOffset(*normalizedCY->getPairValue(), *normalizedCX->getPairValue()),
- m_layoutBox ? m_layoutBox->cssText() : String());
+ m_referenceBox ? m_referenceBox->cssText() : String());
}
bool CSSBasicShapeEllipse::equals(const CSSBasicShape& shape) const
@@ -197,7 +197,7 @@
&& compareCSSValuePtr(m_centerY, other.m_centerY)
&& compareCSSValuePtr(m_radiusX, other.m_radiusX)
&& compareCSSValuePtr(m_radiusY, other.m_radiusY)
- && compareCSSValuePtr(m_layoutBox, other.m_layoutBox);
+ && compareCSSValuePtr(m_referenceBox, other.m_referenceBox);
}
void CSSBasicShapeEllipse::trace(Visitor* visitor)
@@ -209,7 +209,7 @@
CSSBasicShape::trace(visitor);
}
-static String buildPolygonString(const WindRule& windRule, const Vector<String>& points, const String& layoutBox)
+static String buildPolygonString(const WindRule& windRule, const Vector<String>& points, const String& box)
{
ASSERT(!(points.size() % 2));
@@ -227,8 +227,8 @@
// add length of two strings, plus one for the space separator.
length += points[i].length() + 1 + points[i + 1].length();
}
- if (!layoutBox.isEmpty())
- length += layoutBox.length() + 1;
+ if (!box.isEmpty())
+ length += box.length() + 1;
result.reserveCapacity(length);
if (windRule == RULE_EVENODD)
@@ -246,9 +246,9 @@
result.append(')');
- if (!layoutBox.isEmpty()) {
+ if (!box.isEmpty()) {
result.append(' ');
- result.append(layoutBox);
+ result.append(box);
}
return result.toString();
@@ -262,7 +262,7 @@
for (size_t i = 0; i < m_values.size(); ++i)
points.append(m_values.at(i)->cssText());
- return buildPolygonString(m_windRule, points, m_layoutBox ? m_layoutBox->cssText() : String());
+ return buildPolygonString(m_windRule, points, m_referenceBox ? m_referenceBox->cssText() : String());
}
bool CSSBasicShapePolygon::equals(const CSSBasicShape& shape) const
@@ -272,7 +272,7 @@
const CSSBasicShapePolygon& rhs = static_cast<const CSSBasicShapePolygon&>(shape);
- if (!compareCSSValuePtr(m_layoutBox, rhs.m_layoutBox))
+ if (!compareCSSValuePtr(m_referenceBox, rhs.m_referenceBox))
return false;
return compareCSSValueVector(m_values, rhs.m_values);
diff --git a/Source/core/css/CSSBasicShapes.h b/Source/core/css/CSSBasicShapes.h
index 3645169..4c510e0 100644
--- a/Source/core/css/CSSBasicShapes.h
+++ b/Source/core/css/CSSBasicShapes.h
@@ -52,14 +52,14 @@
virtual String cssText() const = 0;
virtual bool equals(const CSSBasicShape&) const = 0;
- CSSPrimitiveValue* layoutBox() const { return m_layoutBox.get(); }
- void setLayoutBox(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> layoutBox) { m_layoutBox = layoutBox; }
+ CSSPrimitiveValue* referenceBox() const { return m_referenceBox.get(); }
+ void setReferenceBox(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> referenceBox) { m_referenceBox = referenceBox; }
- virtual void trace(Visitor* visitor) { visitor->trace(m_layoutBox); }
+ virtual void trace(Visitor* visitor) { visitor->trace(m_referenceBox); }
protected:
CSSBasicShape() { }
- RefPtrWillBeMember<CSSPrimitiveValue> m_layoutBox;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_referenceBox;
};
class CSSBasicShapeCircle FINAL : public CSSBasicShape {
diff --git a/Source/core/css/CSSComputedStyleDeclaration.cpp b/Source/core/css/CSSComputedStyleDeclaration.cpp
index 7a28a22..71388a9 100644
--- a/Source/core/css/CSSComputedStyleDeclaration.cpp
+++ b/Source/core/css/CSSComputedStyleDeclaration.cpp
@@ -296,12 +296,13 @@
CSSPropertyWebkitMaskRepeat,
CSSPropertyWebkitMaskSize,
CSSPropertyOrder,
+ CSSPropertyPerspective,
CSSPropertyWebkitPerspective,
+ CSSPropertyPerspectiveOrigin,
CSSPropertyWebkitPerspectiveOrigin,
CSSPropertyWebkitPrintColorAdjust,
CSSPropertyWebkitRtlOrdering,
CSSPropertyShapeOutside,
- CSSPropertyShapePadding,
CSSPropertyShapeImageThreshold,
CSSPropertyShapeMargin,
CSSPropertyWebkitTapHighlightColor,
@@ -315,7 +316,9 @@
CSSPropertyWebkitTextSecurity,
CSSPropertyWebkitTextStrokeColor,
CSSPropertyWebkitTextStrokeWidth,
+ CSSPropertyTransform,
CSSPropertyWebkitTransform,
+ CSSPropertyTransformOrigin,
CSSPropertyWebkitTransformOrigin,
CSSPropertyTransformStyle,
CSSPropertyWebkitTransformStyle,
@@ -1438,7 +1441,7 @@
if (shapeValue->type() == ShapeValue::Outside)
return cssValuePool().createIdentifierValue(CSSValueOutsideShape);
if (shapeValue->type() == ShapeValue::Box)
- return cssValuePool().createValue(shapeValue->layoutBox());
+ return cssValuePool().createValue(shapeValue->cssBox());
if (shapeValue->type() == ShapeValue::Image) {
if (shapeValue->image())
return shapeValue->image()->cssValue();
@@ -1449,8 +1452,8 @@
RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
list->append(valueForBasicShape(style, shapeValue->shape()));
- if (shapeValue->layoutBox() != BoxMissing)
- list->append(cssValuePool().createValue(shapeValue->layoutBox()));
+ if (shapeValue->cssBox() != BoxMissing)
+ list->append(cssValuePool().createValue(shapeValue->cssBox()));
return list.release();
}
@@ -1490,8 +1493,11 @@
case CSSPropertyLeft:
case CSSPropertyRight:
case CSSPropertyTop:
+ case CSSPropertyPerspectiveOrigin:
case CSSPropertyWebkitPerspectiveOrigin:
+ case CSSPropertyTransform:
case CSSPropertyWebkitTransform:
+ case CSSPropertyTransformOrigin:
case CSSPropertyWebkitTransformOrigin:
case CSSPropertyWidth:
case CSSPropertyWebkitFilter:
@@ -1976,7 +1982,8 @@
return valuesForGridShorthand(gridRowShorthand());
case CSSPropertyGridArea:
return valuesForGridShorthand(gridAreaShorthand());
-
+ case CSSPropertyGridTemplate:
+ return valuesForGridShorthand(gridTemplateShorthand());
case CSSPropertyGridTemplateAreas:
if (!style->namedGridAreaRowCount()) {
ASSERT(!style->namedGridAreaColumnCount());
@@ -2502,10 +2509,12 @@
case CSSPropertyWebkitMarginTopCollapse:
case CSSPropertyWebkitMarginBeforeCollapse:
return cssValuePool().createValue(style->marginBeforeCollapse());
+ case CSSPropertyPerspective:
case CSSPropertyWebkitPerspective:
if (!style->hasPerspective())
return cssValuePool().createIdentifierValue(CSSValueNone);
return zoomAdjustedPixelValue(style->perspective(), *style);
+ case CSSPropertyPerspectiveOrigin:
case CSSPropertyWebkitPerspectiveOrigin: {
RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
if (renderer) {
@@ -2551,8 +2560,10 @@
}
case CSSPropertySpeak:
return cssValuePool().createValue(style->speak());
+ case CSSPropertyTransform:
case CSSPropertyWebkitTransform:
return computedTransform(renderer, *style);
+ case CSSPropertyTransformOrigin:
case CSSPropertyWebkitTransformOrigin: {
RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
if (renderer) {
@@ -2640,8 +2651,6 @@
return cssValuePool().createValue(style->wrapFlow());
case CSSPropertyShapeMargin:
return cssValuePool().createValue(style->shapeMargin());
- case CSSPropertyShapePadding:
- return cssValuePool().createValue(style->shapePadding());
case CSSPropertyShapeImageThreshold:
return cssValuePool().createValue(style->shapeImageThreshold(), CSSPrimitiveValue::CSS_NUMBER);
case CSSPropertyShapeOutside:
@@ -2764,13 +2773,6 @@
ASSERT_NOT_REACHED();
break;
- // FIXME: crbug.com/154772 Unimplemented css-transforms properties
- case CSSPropertyPerspective:
- case CSSPropertyPerspectiveOrigin:
- case CSSPropertyTransform:
- case CSSPropertyTransformOrigin:
- break;
-
/* Unimplemented @font-face properties */
case CSSPropertyFontStretch:
case CSSPropertySrc:
diff --git a/Source/core/css/CSSGradientValue.h b/Source/core/css/CSSGradientValue.h
index c8ca0d7..4ba5d84 100644
--- a/Source/core/css/CSSGradientValue.h
+++ b/Source/core/css/CSSGradientValue.h
@@ -69,6 +69,22 @@
void trace(Visitor*);
};
+} // namespace WebCore
+
+
+// We have to declare the VectorTraits specialization before CSSGradientValue
+// declares its inline capacity vector below.
+namespace WTF {
+
+template <> struct VectorTraits<WebCore::CSSGradientColorStop> : VectorTraitsBase<WebCore::CSSGradientColorStop> {
+ static const bool canInitializeWithMemset = true;
+ static const bool canMoveWithMemcpy = true;
+};
+
+}
+
+namespace WebCore {
+
class CSSGradientValue : public CSSImageGeneratorValue {
public:
PassRefPtr<Image> image(RenderObject*, const IntSize&);
diff --git a/Source/core/css/CSSGrammar.y b/Source/core/css/CSSGrammar.y
index 6b32b95..019aead 100644
--- a/Source/core/css/CSSGrammar.y
+++ b/Source/core/css/CSSGrammar.y
@@ -60,7 +60,7 @@
%}
-%pure_parser
+%pure-parser
%parse-param { BisonCSSParser* parser }
%lex-param { BisonCSSParser* parser }
diff --git a/Source/core/css/CSSMatrix.cpp b/Source/core/css/CSSMatrix.cpp
index 6e11a82..303817a 100644
--- a/Source/core/css/CSSMatrix.cpp
+++ b/Source/core/css/CSSMatrix.cpp
@@ -57,6 +57,7 @@
if (string.isEmpty())
return;
+ // FIXME: crbug.com/154722 - should this continue to use legacy style parsing?
RefPtrWillBeRawPtr<MutableStylePropertySet> styleDeclaration = MutableStylePropertySet::create();
if (BisonCSSParser::parseValue(styleDeclaration.get(), CSSPropertyWebkitTransform, string, true, HTMLStandardMode, 0)) {
// Convert to TransformOperations. This can fail if a property
diff --git a/Source/core/css/CSSParserValues.h b/Source/core/css/CSSParserValues.h
index fbde0b7..1297446 100644
--- a/Source/core/css/CSSParserValues.h
+++ b/Source/core/css/CSSParserValues.h
@@ -191,6 +191,12 @@
--m_current;
return current();
}
+ void setCurrentIndex(unsigned index)
+ {
+ ASSERT(index < m_values.size());
+ if (index < m_values.size())
+ m_current = index;
+ }
CSSParserValue* valueAt(unsigned i) { return i < m_values.size() ? &m_values[i] : 0; }
diff --git a/Source/core/css/CSSPrimitiveValueMappings.h b/Source/core/css/CSSPrimitiveValueMappings.h
index 352dad2..0fc39c2 100644
--- a/Source/core/css/CSSPrimitiveValueMappings.h
+++ b/Source/core/css/CSSPrimitiveValueMappings.h
@@ -4706,11 +4706,11 @@
return TouchActionDelayNone;
}
-template<> inline CSSPrimitiveValue::CSSPrimitiveValue(LayoutBox layoutBox)
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(CSSBoxType cssBox)
: CSSValue(PrimitiveClass)
{
m_primitiveUnitType = CSS_VALUE_ID;
- switch (layoutBox) {
+ switch (cssBox) {
case MarginBox:
m_value.valueID = CSSValueMarginBox;
break;
@@ -4729,7 +4729,7 @@
}
}
-template<> inline CSSPrimitiveValue::operator LayoutBox() const
+template<> inline CSSPrimitiveValue::operator CSSBoxType() const
{
switch (getValueID()) {
case CSSValueMarginBox:
diff --git a/Source/core/css/CSSProperties.in b/Source/core/css/CSSProperties.in
index 7520750..55b9b91 100644
--- a/Source/core/css/CSSProperties.in
+++ b/Source/core/css/CSSProperties.in
@@ -110,7 +110,6 @@
shape-image-threshold type_name=float
shape-margin type_name=Length, converter=convertLength
shape-outside type_name=ShapeValue*, custom_value
-shape-padding type_name=Length, converter=convertLength
size custom_all
speak
table-layout
@@ -214,6 +213,7 @@
-webkit-mask-repeat-x custom_all
-webkit-mask-repeat-y custom_all
-webkit-mask-size custom_all
+perspective-origin custom_all
-webkit-perspective-origin custom_all
-webkit-perspective-origin-x type_name=Length, converter=convertLength
-webkit-perspective-origin-y type_name=Length, converter=convertLength
@@ -228,6 +228,7 @@
-webkit-text-security
-webkit-text-stroke-color custom_all
text-underline-position custom_value
+transform-origin custom_all
-webkit-transform-origin-x type_name=Length, converter=convertLength
-webkit-transform-origin-y type_name=Length, converter=convertLength
-webkit-transform-origin-z type_name=float, converter=convertComputedLength<float>
diff --git a/Source/core/css/CSSProperty.cpp b/Source/core/css/CSSProperty.cpp
index 338634c..e03ad3a 100644
--- a/Source/core/css/CSSProperty.cpp
+++ b/Source/core/css/CSSProperty.cpp
@@ -588,6 +588,7 @@
case CSSPropertyGridColumn:
case CSSPropertyGridColumnEnd:
case CSSPropertyGridColumnStart:
+ case CSSPropertyGridTemplate:
case CSSPropertyGridTemplateColumns:
case CSSPropertyGridTemplateRows:
case CSSPropertyGridRow:
@@ -663,7 +664,6 @@
case CSSPropertyWebkitWrapFlow:
case CSSPropertyShapeMargin:
case CSSPropertyShapeImageThreshold:
- case CSSPropertyShapePadding:
case CSSPropertyShapeOutside:
case CSSPropertyWebkitWrapThrough:
case CSSPropertyWebkitAppRegion:
diff --git a/Source/core/css/CSSPropertyNames.in b/Source/core/css/CSSPropertyNames.in
index 8763716..c06f709 100644
--- a/Source/core/css/CSSPropertyNames.in
+++ b/Source/core/css/CSSPropertyNames.in
@@ -323,6 +323,7 @@
grid-column
grid-column-end
grid-column-start
+grid-template
grid-template-columns
grid-template-rows
grid-row
@@ -411,11 +412,9 @@
-webkit-user-select
-webkit-shape-outside alias_for=shape-outside
-webkit-shape-margin alias_for=shape-margin
--webkit-shape-padding alias_for=shape-padding
-webkit-shape-image-threshold alias_for=shape-image-threshold
shape-outside
shape-margin
-shape-padding
shape-image-threshold
-webkit-wrap-flow
-webkit-wrap-through
diff --git a/Source/core/css/CSSPropertySourceData.cpp b/Source/core/css/CSSPropertySourceData.cpp
index 6a5ff1b..26bf1b6 100644
--- a/Source/core/css/CSSPropertySourceData.cpp
+++ b/Source/core/css/CSSPropertySourceData.cpp
@@ -30,10 +30,6 @@
#include "config.h"
-#ifdef SKIP_STATIC_CONSTRUCTORS_ON_GCC
-#define CSSPROPERTYSOURCEDATA_HIDE_GLOBALS 1
-#endif
-
#include "core/css/CSSPropertySourceData.h"
#include "wtf/StaticConstructors.h"
@@ -114,17 +110,13 @@
return StringHash::hash(name) + 3 * StringHash::hash(value) + 7 * important + 13 * parsedOk + 31;
}
-// Global init routines
-DEFINE_GLOBAL(CSSPropertySourceData, emptyCSSPropertySourceData, "", "e", false, false)
-
-// static
-void CSSPropertySourceData::init()
+void CSSRuleSourceData::trace(Visitor* visitor)
{
- static bool initialized;
- if (!initialized) {
- new ((void *) &emptyCSSPropertySourceData) CSSPropertySourceData("", "e", false, false, false, SourceRange(0, 0));
- initialized = true;
- }
+ visitor->trace(ruleHeaderRange);
+ visitor->trace(ruleBodyRange);
+ visitor->trace(selectorRanges);
+ visitor->trace(styleSourceData);
+ visitor->trace(childRules);
}
} // namespace WebCore
diff --git a/Source/core/css/CSSPropertySourceData.h b/Source/core/css/CSSPropertySourceData.h
index b5d51e2..a4c1ca8 100644
--- a/Source/core/css/CSSPropertySourceData.h
+++ b/Source/core/css/CSSPropertySourceData.h
@@ -31,6 +31,7 @@
#ifndef CSSPropertySourceData_h
#define CSSPropertySourceData_h
+#include "heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/RefCounted.h"
#include "wtf/Vector.h"
@@ -41,17 +42,21 @@
class StyleRuleBase;
struct SourceRange {
+ ALLOW_ONLY_INLINE_ALLOCATION();
+public:
SourceRange();
SourceRange(unsigned start, unsigned end);
unsigned length() const;
+ void trace(Visitor*) { }
+
unsigned start;
unsigned end;
};
struct CSSPropertySourceData {
- static void init();
-
+ ALLOW_ONLY_INLINE_ALLOCATION();
+public:
CSSPropertySourceData(const String& name, const String& value, bool important, bool disabled, bool parsedOk, const SourceRange& range);
CSSPropertySourceData(const CSSPropertySourceData& other);
CSSPropertySourceData();
@@ -59,6 +64,8 @@
String toString() const;
unsigned hash() const;
+ void trace(Visitor* visitor) { visitor->trace(range); }
+
String name;
String value;
bool important;
@@ -67,24 +74,22 @@
SourceRange range;
};
-#ifndef CSSPROPERTYSOURCEDATA_HIDE_GLOBALS
-extern const CSSPropertySourceData emptyCSSPropertySourceData;
-#endif
-
-struct CSSStyleSourceData : public RefCounted<CSSStyleSourceData> {
- static PassRefPtr<CSSStyleSourceData> create()
+struct CSSStyleSourceData : public RefCountedWillBeGarbageCollected<CSSStyleSourceData> {
+ static PassRefPtrWillBeRawPtr<CSSStyleSourceData> create()
{
- return adoptRef(new CSSStyleSourceData());
+ return adoptRefWillBeNoop(new CSSStyleSourceData());
}
- Vector<CSSPropertySourceData> propertyData;
+ void trace(Visitor* visitor) { visitor->trace(propertyData); }
+
+ WillBeHeapVector<CSSPropertySourceData> propertyData;
};
struct CSSRuleSourceData;
-typedef Vector<RefPtr<CSSRuleSourceData> > RuleSourceDataList;
-typedef Vector<SourceRange> SelectorRangeList;
+typedef WillBeHeapVector<RefPtrWillBeMember<CSSRuleSourceData> > RuleSourceDataList;
+typedef WillBeHeapVector<SourceRange> SelectorRangeList;
-struct CSSRuleSourceData : public RefCounted<CSSRuleSourceData> {
+struct CSSRuleSourceData : public RefCountedWillBeGarbageCollected<CSSRuleSourceData> {
enum Type {
UNKNOWN_RULE,
STYLE_RULE,
@@ -99,14 +104,14 @@
FILTER_RULE
};
- static PassRefPtr<CSSRuleSourceData> create(Type type)
+ static PassRefPtrWillBeRawPtr<CSSRuleSourceData> create(Type type)
{
- return adoptRef(new CSSRuleSourceData(type));
+ return adoptRefWillBeNoop(new CSSRuleSourceData(type));
}
- static PassRefPtr<CSSRuleSourceData> createUnknown()
+ static PassRefPtrWillBeRawPtr<CSSRuleSourceData> createUnknown()
{
- return adoptRef(new CSSRuleSourceData(UNKNOWN_RULE));
+ return adoptRefWillBeNoop(new CSSRuleSourceData(UNKNOWN_RULE));
}
CSSRuleSourceData(Type type)
@@ -116,6 +121,8 @@
styleSourceData = CSSStyleSourceData::create();
}
+ void trace(Visitor*);
+
Type type;
// Range of the selector list in the enclosing source.
@@ -128,7 +135,7 @@
SelectorRangeList selectorRanges;
// Only for CSSStyleRules, CSSFontFaceRules, and CSSPageRules.
- RefPtr<CSSStyleSourceData> styleSourceData;
+ RefPtrWillBeMember<CSSStyleSourceData> styleSourceData;
// Only for CSSMediaRules.
RuleSourceDataList childRules;
@@ -136,4 +143,18 @@
} // namespace WebCore
+namespace WTF {
+
+template <> struct VectorTraits<WebCore::SourceRange> : VectorTraitsBase<WebCore::SourceRange> {
+ static const bool canInitializeWithMemset = true;
+ static const bool canMoveWithMemcpy = true;
+};
+
+template <> struct VectorTraits<WebCore::CSSPropertySourceData> : VectorTraitsBase<WebCore::CSSPropertySourceData> {
+ static const bool canInitializeWithMemset = true;
+ static const bool canMoveWithMemcpy = true;
+};
+
+}
+
#endif // CSSPropertySourceData_h
diff --git a/Source/core/css/CSSSelector.cpp b/Source/core/css/CSSSelector.cpp
index cddc68b..94238d4 100644
--- a/Source/core/css/CSSSelector.cpp
+++ b/Source/core/css/CSSSelector.cpp
@@ -397,6 +397,8 @@
if (tagHistory()) {
printf("\n%*s--> (relation == %d)\n", indent, "", relation());
tagHistory()->show(indent + 2);
+ } else {
+ printf("\n%*s--> (relation == %d)\n", indent, "", relation());
}
}
diff --git a/Source/core/css/CSSSelector.h b/Source/core/css/CSSSelector.h
index 00e1551..d9c9933 100644
--- a/Source/core/css/CSSSelector.h
+++ b/Source/core/css/CSSSelector.h
@@ -288,7 +288,7 @@
bool isShadowPseudoElement() const;
bool isHostPseudoClass() const;
- // FIXME: selectors with no tagHistory() get a relation() of Descendant. It should instead be
+ // FIXME: selectors with no tagHistory() get a relation() of Descendant (and sometimes even SubSelector). It should instead be
// None.
Relation relation() const { return static_cast<Relation>(m_relation); }
diff --git a/Source/core/css/CSSShorthands.in b/Source/core/css/CSSShorthands.in
index f66d649..22d246e 100644
--- a/Source/core/css/CSSShorthands.in
+++ b/Source/core/css/CSSShorthands.in
@@ -21,6 +21,7 @@
flex longhands=flex-grow;flex-shrink;flex-basis
flex-flow longhands=flex-direction;flex-wrap
font longhands=font-family;font-size;font-style;font-variant;font-weight;line-height
+grid-template longhands=grid-template-columns;grid-template-rows;grid-template-areas
grid-area longhands=grid-row-start;grid-column-start;grid-row-end;grid-column-end
grid-column longhands=grid-column-start;grid-column-end
grid-row longhands=grid-row-start;grid-row-end
diff --git a/Source/core/css/CSSTokenizer-in.cpp b/Source/core/css/CSSTokenizer-in.cpp
index 69197eb..dec709f 100644
--- a/Source/core/css/CSSTokenizer-in.cpp
+++ b/Source/core/css/CSSTokenizer-in.cpp
@@ -304,14 +304,17 @@
return m_currentCharacter16;
}
-UChar*& CSSTokenizer::currentCharacter16()
+UChar* CSSTokenizer::allocateStringBuffer16(size_t len)
{
- if (!m_currentCharacter16) {
- m_dataStart16 = adoptArrayPtr(new UChar[m_length]);
- m_currentCharacter16 = m_dataStart16.get();
- }
+ // Allocates and returns a CSSTokenizer owned buffer for storing
+ // UTF-16 data. Used to get a suitable life span for UTF-16
+ // strings, identifiers and URIs created by the tokenizer.
+ OwnPtr<UChar[]> buffer = adoptArrayPtr(new UChar[len]);
- return m_currentCharacter16;
+ UChar* bufferPtr = buffer.get();
+
+ m_cssStrings16.append(buffer.release());
+ return bufferPtr;
}
template <>
@@ -412,7 +415,7 @@
return unicode;
}
- return *currentCharacter<CharacterType>()++;
+ return *src++;
}
template <>
@@ -438,6 +441,24 @@
++result;
}
+template <typename SrcCharacterType>
+size_t CSSTokenizer::peekMaxIdentifierLen(SrcCharacterType* src)
+{
+ // The decoded form of an identifier (after resolving escape
+ // sequences) will not contain more characters (ASCII or UTF-16
+ // codepoints) than the input. This code can therefore ignore
+ // escape sequences completely.
+ SrcCharacterType* start = src;
+ do {
+ if (LIKELY(*src != '\\'))
+ src++;
+ else
+ parseEscape<SrcCharacterType>(src);
+ } while (isCSSLetter(src[0]) || (src[0] == '\\' && isCSSEscape(src[1])));
+
+ return src - start;
+}
+
template <typename SrcCharacterType, typename DestCharacterType>
inline bool CSSTokenizer::parseIdentifierInternal(SrcCharacterType*& src, DestCharacterType*& result, bool& hasEscape)
{
@@ -471,7 +492,7 @@
if (UNLIKELY(!parseIdentifierInternal(currentCharacter<CharacterType>(), result, hasEscape))) {
// Found an escape we couldn't handle with 8 bits, copy what has been recognized and continue
ASSERT(is8BitSource());
- UChar*& result16 = currentCharacter16();
+ UChar* result16 = allocateStringBuffer16((result - start) + peekMaxIdentifierLen(currentCharacter<CharacterType>()));
UChar* start16 = result16;
int i = 0;
for (; i < result - start; i++)
@@ -489,6 +510,18 @@
resultString.init(start, result - start);
}
+template <typename SrcCharacterType>
+size_t CSSTokenizer::peekMaxStringLen(SrcCharacterType* src, UChar quote)
+{
+ // The decoded form of a CSS string (after resolving escape
+ // sequences) will not contain more characters (ASCII or UTF-16
+ // codepoints) than the input. This code can therefore ignore
+ // escape sequences completely and just return the length of the
+ // input string (possibly including terminating quote if any).
+ SrcCharacterType* end = checkAndSkipString(src, quote);
+ return end ? end - src : 0;
+}
+
template <typename SrcCharacterType, typename DestCharacterType>
inline bool CSSTokenizer::parseStringInternal(SrcCharacterType*& src, DestCharacterType*& result, UChar quote)
{
@@ -532,7 +565,7 @@
if (UNLIKELY(!parseStringInternal(currentCharacter<CharacterType>(), result, quote))) {
// Found an escape we couldn't handle with 8 bits, copy what has been recognized and continue
ASSERT(is8BitSource());
- UChar*& result16 = currentCharacter16();
+ UChar* result16 = allocateStringBuffer16((result - start) + peekMaxStringLen(currentCharacter<CharacterType>(), quote));
UChar* start16 = result16;
int i = 0;
for (; i < result - start; i++)
@@ -580,6 +613,29 @@
return true;
}
+template <typename SrcCharacterType>
+inline size_t CSSTokenizer::peekMaxURILen(SrcCharacterType* src, UChar quote)
+{
+ // The decoded form of a URI (after resolving escape sequences)
+ // will not contain more characters (ASCII or UTF-16 codepoints)
+ // than the input. This code can therefore ignore escape sequences
+ // completely.
+ SrcCharacterType* start = src;
+ if (quote) {
+ ASSERT(quote == '"' || quote == '\'');
+ return peekMaxStringLen(src, quote);
+ }
+
+ while (isURILetter(*src)) {
+ if (LIKELY(*src != '\\'))
+ src++;
+ else
+ parseEscape<SrcCharacterType>(src);
+ }
+
+ return src - start;
+}
+
template <typename SrcCharacterType, typename DestCharacterType>
inline bool CSSTokenizer::parseURIInternal(SrcCharacterType*& src, DestCharacterType*& dest, UChar quote)
{
@@ -593,7 +649,7 @@
*dest++ = *src++;
} else {
unsigned unicode = parseEscape<SrcCharacterType>(src);
- if (unicode > 0xff && sizeof(SrcCharacterType) == 1)
+ if (unicode > 0xff && sizeof(DestCharacterType) == 1)
return false;
UnicodeToChars(dest, unicode);
}
@@ -619,11 +675,12 @@
// Reset the current character to the start of the URI and re-parse with
// a 16-bit destination.
ASSERT(is8BitSource());
- UChar* uriStart16 = currentCharacter16();
currentCharacter<CharacterType>() = uriStart;
- bool result = parseURIInternal(currentCharacter<CharacterType>(), currentCharacter16(), quote);
+ UChar* result16 = allocateStringBuffer16(peekMaxURILen(currentCharacter<CharacterType>(), quote));
+ UChar* uriStart16 = result16;
+ bool result = parseURIInternal(currentCharacter<CharacterType>(), result16, quote);
ASSERT_UNUSED(result, result);
- string.init(uriStart16, currentCharacter16() - uriStart16);
+ string.init(uriStart16, result16 - uriStart16);
}
currentCharacter<CharacterType>() = uriEnd + 1;
diff --git a/Source/core/css/CSSTokenizer.h b/Source/core/css/CSSTokenizer.h
index 5d8fae1..508bf71 100644
--- a/Source/core/css/CSSTokenizer.h
+++ b/Source/core/css/CSSTokenizer.h
@@ -74,7 +74,7 @@
inline unsigned tokenStartOffset();
private:
- UChar*& currentCharacter16();
+ UChar* allocateStringBuffer16(size_t len);
template <typename CharacterType>
inline CharacterType*& currentCharacter();
@@ -92,29 +92,33 @@
inline CSSParserLocation tokenLocation();
template <typename CharacterType>
- unsigned parseEscape(CharacterType*&);
+ static unsigned parseEscape(CharacterType*&);
template <typename DestCharacterType>
- inline void UnicodeToChars(DestCharacterType*&, unsigned);
- template <typename SrcCharacterType, typename DestCharacterType>
- inline bool parseIdentifierInternal(SrcCharacterType*&, DestCharacterType*&, bool&);
+ static inline void UnicodeToChars(DestCharacterType*&, unsigned);
+ template <typename SrcCharacterType, typename DestCharacterType>
+ static inline bool parseIdentifierInternal(SrcCharacterType*&, DestCharacterType*&, bool&);
+ template <typename SrcCharacterType>
+ static size_t peekMaxIdentifierLen(SrcCharacterType*);
template <typename CharacterType>
inline void parseIdentifier(CharacterType*&, CSSParserString&, bool&);
+ template <typename SrcCharacterType>
+ static size_t peekMaxStringLen(SrcCharacterType*, UChar quote);
template <typename SrcCharacterType, typename DestCharacterType>
- inline bool parseStringInternal(SrcCharacterType*&, DestCharacterType*&, UChar);
-
+ static inline bool parseStringInternal(SrcCharacterType*&, DestCharacterType*&, UChar);
template <typename CharacterType>
inline void parseString(CharacterType*&, CSSParserString& resultString, UChar);
template <typename CharacterType>
inline bool findURI(CharacterType*& start, CharacterType*& end, UChar& quote);
-
+ template <typename SrcCharacterType>
+ static size_t peekMaxURILen(SrcCharacterType*, UChar quote);
template <typename SrcCharacterType, typename DestCharacterType>
- inline bool parseURIInternal(SrcCharacterType*&, DestCharacterType*&, UChar quote);
-
+ static inline bool parseURIInternal(SrcCharacterType*&, DestCharacterType*&, UChar quote);
template <typename CharacterType>
inline void parseURI(CSSParserString&);
+
template <typename CharacterType>
inline bool parseUnicodeRange();
template <typename CharacterType>
@@ -155,6 +159,13 @@
OwnPtr<UChar[]> m_dataStart16;
LChar* m_currentCharacter8;
UChar* m_currentCharacter16;
+
+ // During parsing of an ASCII stylesheet we might locate escape
+ // sequences that expand into UTF-16 code points. Strings,
+ // identifiers and URIs containing such escape sequences are
+ // stored in m_cssStrings16 so that we don't have to store the
+ // whole stylesheet as UTF-16.
+ Vector<OwnPtr<UChar[]> > m_cssStrings16;
union {
LChar* ptr8;
UChar* ptr16;
diff --git a/Source/core/css/MediaList.cpp b/Source/core/css/MediaList.cpp
index 8f27f81..8fc86c2 100644
--- a/Source/core/css/MediaList.cpp
+++ b/Source/core/css/MediaList.cpp
@@ -71,8 +71,16 @@
if (mediaString.isEmpty())
return MediaQuerySet::create();
- return MediaQueryParser::parse(mediaString);
+ BisonCSSParser parser(strictCSSParserContext());
+ return parser.parseMediaQueryList(mediaString);
+}
+PassRefPtrWillBeRawPtr<MediaQuerySet> MediaQuerySet::createOffMainThread(const String& mediaString)
+{
+ if (mediaString.isEmpty())
+ return MediaQuerySet::create();
+
+ return MediaQueryParser::parse(mediaString);
}
bool MediaQuerySet::set(const String& mediaString)
diff --git a/Source/core/css/MediaList.h b/Source/core/css/MediaList.h
index 108448e..15e69d6 100644
--- a/Source/core/css/MediaList.h
+++ b/Source/core/css/MediaList.h
@@ -46,6 +46,7 @@
return adoptRefWillBeNoop(new MediaQuerySet());
}
static PassRefPtrWillBeRawPtr<MediaQuerySet> create(const String& mediaString);
+ static PassRefPtrWillBeRawPtr<MediaQuerySet> createOffMainThread(const String& mediaString);
bool set(const String&);
bool add(const String&);
diff --git a/Source/core/css/MediaQueryList.cpp b/Source/core/css/MediaQueryList.cpp
index 4ada713..d76b5bb 100644
--- a/Source/core/css/MediaQueryList.cpp
+++ b/Source/core/css/MediaQueryList.cpp
@@ -64,11 +64,11 @@
m_matcher->removeListener(listener.get(), this);
}
-void MediaQueryList::evaluate(MediaQueryEvaluator* evaluator, bool& notificationNeeded)
+bool MediaQueryList::evaluate(MediaQueryEvaluator* evaluator)
{
if (m_evaluationRound != m_matcher->evaluationRound() && evaluator)
setMatches(evaluator->eval(m_media.get()));
- notificationNeeded = m_changeRound == m_matcher->evaluationRound();
+ return m_changeRound == m_matcher->evaluationRound();
}
void MediaQueryList::setMatches(bool newValue)
diff --git a/Source/core/css/MediaQueryList.h b/Source/core/css/MediaQueryList.h
index f4af596..e832f29 100644
--- a/Source/core/css/MediaQueryList.h
+++ b/Source/core/css/MediaQueryList.h
@@ -47,7 +47,7 @@
void addListener(PassRefPtrWillBeRawPtr<MediaQueryListListener>);
void removeListener(PassRefPtrWillBeRawPtr<MediaQueryListListener>);
- void evaluate(MediaQueryEvaluator*, bool& notificationNeeded);
+ bool evaluate(MediaQueryEvaluator*);
void trace(Visitor*);
diff --git a/Source/core/css/MediaQueryMatcher.cpp b/Source/core/css/MediaQueryMatcher.cpp
index 4efffd2..bc1f47c 100644
--- a/Source/core/css/MediaQueryMatcher.cpp
+++ b/Source/core/css/MediaQueryMatcher.cpp
@@ -39,9 +39,7 @@
void MediaQueryMatcher::Listener::evaluate(ScriptState* state, MediaQueryEvaluator* evaluator)
{
- bool notify;
- m_query->evaluate(evaluator, notify);
- if (notify)
+ if (m_query->evaluate(evaluator))
m_listener->queryChanged(state, m_query.get());
}
diff --git a/Source/core/css/MediaQuerySetTest.cpp b/Source/core/css/MediaQuerySetTest.cpp
index ef8178c..920e265 100644
--- a/Source/core/css/MediaQuerySetTest.cpp
+++ b/Source/core/css/MediaQuerySetTest.cpp
@@ -16,106 +16,147 @@
typedef struct {
const char* input;
const char* output;
+ bool shouldWorkOnOldParser;
} TestCase;
+static void testMediaQuery(TestCase test, MediaQuerySet& querySet, bool oldParser)
+{
+ StringBuilder output;
+ size_t j = 0;
+ while (j < querySet.queryVector().size()) {
+ String queryText = querySet.queryVector()[j]->cssText();
+ output.append(queryText);
+ ++j;
+ if (j >= querySet.queryVector().size())
+ break;
+ output.append(", ");
+ }
+ if (!oldParser || test.shouldWorkOnOldParser) {
+ if (test.output)
+ ASSERT_STREQ(test.output, output.toString().ascii().data());
+ else
+ ASSERT_STREQ(test.input, output.toString().ascii().data());
+ }
+}
+
TEST(MediaQueryParserTest, Basic)
{
// The first string represents the input string.
// The second string represents the output string, if present.
// Otherwise, the output string is identical to the first string.
TestCase testCases[] = {
- {"screen", 0},
- {"screen and (color)", 0},
- {"all and (min-width:500px)", "(min-width: 500px)"},
- {"all and (min-width:/*bla*/500px)", "(min-width: 500px)"},
- {"(min-width:500px)", "(min-width: 500px)"},
- {"screen and (color), projection and (color)", 0},
- {"not screen and (color)", 0},
- {"only screen and (color)", 0},
- {"screen and (color), projection and (color)", 0},
- {"aural and (device-aspect-ratio: 16/9)", 0},
- {"speech and (min-device-width: 800px)", 0},
- {"example", 0},
- {"screen and (max-weight: 3kg) and (color), (monochrome)", "not all, (monochrome)"},
- {"(min-width: -100px)", "not all"},
- {"(example, all,), speech", "not all, speech"},
- {"&test, screen", "not all, screen"},
- {"print and (min-width: 25cm)", 0},
- {"screen and (min-width: 400px) and (max-width: 700px)", "screen and (max-width: 700px) and (min-width: 400px)"},
- {"screen and (device-width: 800px)", 0},
- {"screen and (device-height: 60em)", 0},
- {"screen and (device-aspect-ratio: 16/9)", 0},
- {"(device-aspect-ratio: 16.0/9.0)", "not all"},
- {"(device-aspect-ratio: 16/ 9)", "(device-aspect-ratio: 16/9)"},
- {"(device-aspect-ratio: 16/\r9)", "(device-aspect-ratio: 16/9)"},
- {"all and (color)", "(color)"},
- {"all and (min-color: 1)", "(min-color: 1)"},
- {"all and (min-color: 1.0)", "not all"},
- {"all and (min-color: 2)", "(min-color: 2)"},
- {"all and (color-index)", "(color-index)"},
- {"all and (min-color-index: 1)", "(min-color-index: 1)"},
- {"all and (monochrome)", "(monochrome)"},
- {"all and (min-monochrome: 1)", "(min-monochrome: 1)"},
- {"all and (min-monochrome: 2)", "(min-monochrome: 2)"},
- {"print and (monochrome)", 0},
- {"handheld and (grid) and (max-width: 15em)", 0},
- {"handheld and (grid) and (max-device-height: 7em)", 0},
- {"screen and (max-width: 50%)", "not all"},
- {"screen and (max-WIDTH: 500px)", "screen and (max-width: 500px)"},
- {"screen and (max-width: 24.4em)", 0},
- {"screen and (max-width: 24.4EM)", "screen and (max-width: 24.4em)"},
- {"screen and (max-width: blabla)", "not all"},
- {"screen and (max-width: 1)", "not all"},
- {"screen and (max-width: 0)", 0},
- {"screen and (max-width: 1deg)", "not all"},
- {"handheld and (min-width: 20em), \nscreen and (min-width: 20em)", "handheld and (min-width: 20em), screen and (min-width: 20em)"},
- {"print and (min-resolution: 300dpi)", 0},
- {"print and (min-resolution: 118dpcm)", 0},
- {"(resolution: 0.83333333333333333333dppx)", "(resolution: 0.8333333333333334dppx)"},
- {"(resolution: 2.4dppx)", 0},
- {"all and(color)", "not all"},
- {"all and (", "not all"},
- {"test;,all", "not all, all"},
- {"(color:20example)", "not all"},
- {"not braille", 0},
- {",screen", "not all, screen"},
- {",all", "not all, all"},
- {",,all,,", "not all, not all, all, not all, not all"},
- {",,all,, ", "not all, not all, all, not all, not all"},
- {",screen,,&invalid,,", "not all, screen, not all, not all, not all, not all"},
- {",screen,,(invalid,),,", "not all, screen, not all, not all, not all, not all"},
- {",(all,),,", "not all, not all, not all, not all"},
- {",", "not all, not all"},
- {" ", ""},
- {"(color", "(color)"},
- {"(min-color: 2", "(min-color: 2)"},
- {"(orientation: portrait)", 0},
- {"tv and (scan: progressive)", 0},
- {"(pointer: coarse)", 0},
- {"(min-orientation:portrait)", "not all"},
- {"all and (orientation:portrait)", "(orientation: portrait)"},
- {"all and (orientation:landscape)", "(orientation: landscape)"},
+ {"screen", 0, true},
+ {"screen and (color)", 0, true},
+ {"all and (min-width:500px)", "(min-width: 500px)", true},
+ {"all and (min-width:/*bla*/500px)", "(min-width: 500px)", true},
+ {"(min-width:500px)", "(min-width: 500px)", true},
+ {"screen and (color), projection and (color)", 0, true},
+ {"not screen and (color)", 0, true},
+ {"only screen and (color)", 0, true},
+ {"screen and (color), projection and (color)", 0, true},
+ {"aural and (device-aspect-ratio: 16/9)", 0, true},
+ {"speech and (min-device-width: 800px)", 0, true},
+ {"example", 0, true},
+ {"screen and (max-weight: 3kg) and (color), (monochrome)", "not all, (monochrome)", true},
+ {"(min-width: -100px)", "not all", true},
+ {"(example, all,), speech", "not all, speech", true},
+ {"&test, screen", "not all, screen", true},
+ {"print and (min-width: 25cm)", 0, true},
+ {"screen and (min-width: 400px) and (max-width: 700px)", "screen and (max-width: 700px) and (min-width: 400px)", true},
+ {"screen and (device-width: 800px)", 0, true},
+ {"screen and (device-height: 60em)", 0, true},
+ {"screen and (device-aspect-ratio: 16/9)", 0, true},
+ {"(device-aspect-ratio: 16.0/9.0)", "not all", true},
+ {"(device-aspect-ratio: 16/ 9)", "(device-aspect-ratio: 16/9)", true},
+ {"(device-aspect-ratio: 16/\r9)", "(device-aspect-ratio: 16/9)", true},
+ {"all and (color)", "(color)", true},
+ {"all and (min-color: 1)", "(min-color: 1)", true},
+ {"all and (min-color: 1.0)", "not all", true},
+ {"all and (min-color: 2)", "(min-color: 2)", true},
+ {"all and (color-index)", "(color-index)", true},
+ {"all and (min-color-index: 1)", "(min-color-index: 1)", true},
+ {"all and (monochrome)", "(monochrome)", true},
+ {"all and (min-monochrome: 1)", "(min-monochrome: 1)", true},
+ {"all and (min-monochrome: 2)", "(min-monochrome: 2)", true},
+ {"print and (monochrome)", 0, true},
+ {"handheld and (grid) and (max-width: 15em)", 0, true},
+ {"handheld and (grid) and (max-device-height: 7em)", 0, true},
+ {"screen and (max-width: 50%)", "not all", true},
+ {"screen and (max-WIDTH: 500px)", "screen and (max-width: 500px)", true},
+ {"screen and (max-width: 24.4em)", 0, true},
+ {"screen and (max-width: 24.4EM)", "screen and (max-width: 24.4em)", true},
+ {"screen and (max-width: blabla)", "not all", true},
+ {"screen and (max-width: 1)", "not all", true},
+ {"screen and (max-width: 0)", 0, true},
+ {"screen and (max-width: 1deg)", "not all", true},
+ {"handheld and (min-width: 20em), \nscreen and (min-width: 20em)", "handheld and (min-width: 20em), screen and (min-width: 20em)", true},
+ {"print and (min-resolution: 300dpi)", 0, true},
+ {"print and (min-resolution: 118dpcm)", 0, true},
+ {"(resolution: 0.83333333333333333333dppx)", "(resolution: 0.8333333333333334dppx)", true},
+ {"(resolution: 2.4dppx)", 0, true},
+ {"all and(color)", "not all", true},
+ {"all and (", "not all", true},
+ {"test;,all", "not all, all", true},
+ {"(color:20example)", "not all", false},
+ {"not braille", 0, true},
+ {",screen", "not all, screen", true},
+ {",all", "not all, all", true},
+ {",,all,,", "not all, not all, all, not all, not all", true},
+ {",,all,, ", "not all, not all, all, not all, not all", true},
+ {",screen,,&invalid,,", "not all, screen, not all, not all, not all, not all", true},
+ {",screen,,(invalid,),,", "not all, screen, not all, not all, not all, not all", true},
+ {",(all,),,", "not all, not all, not all, not all", true},
+ {",", "not all, not all", true},
+ {" ", "", true},
+ {"(color", "(color)", true},
+ {"(min-color: 2", "(min-color: 2)", true},
+ {"(orientation: portrait)", 0, true},
+ {"tv and (scan: progressive)", 0, true},
+ {"(pointer: coarse)", 0, true},
+ {"(min-orientation:portrait)", "not all", true},
+ {"all and (orientation:portrait)", "(orientation: portrait)", true},
+ {"all and (orientation:landscape)", "(orientation: landscape)", true},
{"NOT braille, tv AND (max-width: 200px) and (min-WIDTH: 100px) and (orientation: landscape), (color)",
- "not braille, tv and (max-width: 200px) and (min-width: 100px) and (orientation: landscape), (color)"},
+ "not braille, tv and (max-width: 200px) and (min-width: 100px) and (orientation: landscape), (color)", true},
+ {"(m\\61x-width: 300px)", "(max-width: 300px)", true},
+ {"(max-width: 400\\70\\78)", "(max-width: 400px)", false},
+ {"(max-width: 500\\0070\\0078)", "(max-width: 500px)", false},
+ {"(max-width: 600\\000070\\000078)", "(max-width: 600px)", false},
+ {"(max-width: 700px), (max-width: 700px)", "(max-width: 700px), (max-width: 700px)", true},
+ {"(max-width: 800px()), (max-width: 800px)", "not all, (max-width: 800px)", true},
+ {"(max-width: 900px(()), (max-width: 900px)", "not all", true},
+ {"(max-width: 600px(())))), (max-width: 600px)", "not all, (max-width: 600px)", true},
+ {"(max-width: 500px(((((((((())))), (max-width: 500px)", "not all", true},
+ {"(max-width: 800px[]), (max-width: 800px)", "not all, (max-width: 800px)", true},
+ {"(max-width: 900px[[]), (max-width: 900px)", "not all", true},
+ {"(max-width: 600px[[]]]]), (max-width: 600px)", "not all, (max-width: 600px)", true},
+ {"(max-width: 500px[[[[[[[[[[]]]]), (max-width: 500px)", "not all", true},
+ {"(max-width: 800px{}), (max-width: 800px)", "not all, (max-width: 800px)", true},
+ {"(max-width: 900px{{}), (max-width: 900px)", "not all", true},
+ {"(max-width: 600px{{}}}}), (max-width: 600px)", "not all, (max-width: 600px)", true},
+ {"(max-width: 500px{{{{{{{{{{}}}}), (max-width: 500px)", "not all", true},
+ {"[(), (max-width: 400px)", "not all", true},
+ {"[{}, (max-width: 500px)", "not all", true},
+ {"[{]}], (max-width: 900px)", "not all, (max-width: 900px)", true},
+ {"[{[]{}{{{}}}}], (max-width: 900px)", "not all, (max-width: 900px)", true},
+ {"[{[}], (max-width: 900px)", "not all", true},
+ {"[({)}], (max-width: 900px)", "not all", true},
+ {"[]((), (max-width: 900px)", "not all", true},
+ {"((), (max-width: 900px)", "not all", true},
+ {"(foo(), (max-width: 900px)", "not all", true},
+ {"[](()), (max-width: 900px)", "not all, (max-width: 900px)", true},
+ {"all an[isdfs bla())()]icalc(i)(()), (max-width: 400px)", "not all, (max-width: 400px)", true},
+ {"all an[isdfs bla())(]icalc(i)(()), (max-width: 500px)", "not all", true},
+ {"all an[isdfs bla())(]icalc(i)(())), (max-width: 600px)", "not all", true},
+ {"all an[isdfs bla())(]icalc(i)(()))], (max-width: 800px)", "not all, (max-width: 800px)", true},
{0, 0} // Do not remove the terminator line.
};
for (unsigned i = 0; testCases[i].input; ++i) {
- RefPtrWillBeRawPtr<MediaQuerySet> querySet = MediaQuerySet::create(testCases[i].input);
- StringBuilder output;
- size_t j = 0;
- while (j < querySet->queryVector().size()) {
- String queryText = querySet->queryVector()[j]->cssText();
- output.append(queryText);
- ++j;
- if (j >= querySet->queryVector().size())
- break;
- output.append(", ");
- }
- if (testCases[i].output)
- ASSERT_STREQ(testCases[i].output, output.toString().ascii().data());
- else
- ASSERT_STREQ(testCases[i].input, output.toString().ascii().data());
+ RefPtrWillBeRawPtr<MediaQuerySet> oldParserQuerySet = MediaQuerySet::create(testCases[i].input);
+ RefPtrWillBeRawPtr<MediaQuerySet> threadSafeQuerySet = MediaQuerySet::createOffMainThread(testCases[i].input);
+ testMediaQuery(testCases[i], *oldParserQuerySet, true);
+ testMediaQuery(testCases[i], *threadSafeQuerySet, false);
}
}
diff --git a/Source/core/css/RuleFeature.cpp b/Source/core/css/RuleFeature.cpp
index f8ce8dd..7b793eb 100644
--- a/Source/core/css/RuleFeature.cpp
+++ b/Source/core/css/RuleFeature.cpp
@@ -54,7 +54,7 @@
case CSSSelector::PseudoShadow:
return true;
default:
- return false;
+ return selector.isCustomPseudoElement();
}
}
if (selector.m_match != CSSSelector::PseudoClass)
@@ -103,23 +103,23 @@
}
// This method is somewhat conservative in what it accepts.
-RuleFeatureSet::InvalidationSetMode RuleFeatureSet::supportsClassDescendantInvalidation(const CSSSelector& selector)
+RuleFeatureSet::InvalidationSetMode RuleFeatureSet::invalidationSetModeForSelector(const CSSSelector& selector)
{
bool foundDescendantRelation = false;
bool foundIdent = false;
for (const CSSSelector* component = &selector; component; component = component->tagHistory()) {
// FIXME: next up: Tag and Id.
- if (component->m_match == CSSSelector::Class || component->isAttributeSelector()) {
+ if (component->m_match == CSSSelector::Class || component->isAttributeSelector() || component->isCustomPseudoElement()) {
if (!foundDescendantRelation)
foundIdent = true;
} else if (component->pseudoType() == CSSSelector::PseudoHost || component->pseudoType() == CSSSelector::PseudoAny) {
if (const CSSSelectorList* selectorList = component->selectorList()) {
for (const CSSSelector* selector = selectorList->first(); selector; selector = CSSSelectorList::next(*selector)) {
- InvalidationSetMode hostMode = supportsClassDescendantInvalidation(*selector);
+ InvalidationSetMode hostMode = invalidationSetModeForSelector(*selector);
if (hostMode == UseSubtreeStyleChange)
return foundDescendantRelation ? UseLocalStyleChange : UseSubtreeStyleChange;
- if (hostMode == AddFeatures)
+ if (!foundDescendantRelation && hostMode == AddFeatures)
foundIdent = true;
}
}
@@ -152,6 +152,8 @@
features.classes.append(selector.value());
else if (selector.isAttributeSelector())
features.attributes.append(selector.attribute().localName());
+ else if (selector.isCustomPseudoElement())
+ features.customPseudoElement = true;
}
RuleFeatureSet::RuleFeatureSet()
@@ -170,7 +172,7 @@
RuleFeatureSet::InvalidationSetMode RuleFeatureSet::updateInvalidationSets(const CSSSelector& selector)
{
- InvalidationSetMode mode = supportsClassDescendantInvalidation(selector);
+ InvalidationSetMode mode = invalidationSetModeForSelector(selector);
if (mode != AddFeatures)
return mode;
@@ -216,6 +218,8 @@
invalidationSet->addClass(*it);
for (Vector<AtomicString>::const_iterator it = features.attributes.begin(); it != features.attributes.end(); ++it)
invalidationSet->addAttribute(*it);
+ if (features.customPseudoElement)
+ invalidationSet->setCustomPseudoInvalid();
} else if (current->pseudoType() == CSSSelector::PseudoHost || current->pseudoType() == CSSSelector::PseudoAny) {
if (const CSSSelectorList* selectorList = current->selectorList()) {
for (const CSSSelector* selector = selectorList->first(); selector; selector = CSSSelectorList::next(*selector))
@@ -348,10 +352,10 @@
m_metadata.clear();
m_classInvalidationSets.clear();
m_attributeInvalidationSets.clear();
- m_pendingInvalidationMap.clear();
+ m_styleInvalidator.clearPendingInvalidations();
}
-void RuleFeatureSet::scheduleStyleInvalidationForClassChange(const SpaceSplitString& changedClasses, Element* element)
+void RuleFeatureSet::scheduleStyleInvalidationForClassChange(const SpaceSplitString& changedClasses, Element& element)
{
unsigned changedSize = changedClasses.size();
for (unsigned i = 0; i < changedSize; ++i) {
@@ -359,7 +363,7 @@
}
}
-void RuleFeatureSet::scheduleStyleInvalidationForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, Element* element)
+void RuleFeatureSet::scheduleStyleInvalidationForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, Element& element)
{
if (!oldClasses.size())
scheduleStyleInvalidationForClassChange(newClasses, element);
@@ -392,41 +396,21 @@
}
}
-void RuleFeatureSet::scheduleStyleInvalidationForAttributeChange(const QualifiedName& attributeName, Element* element)
+void RuleFeatureSet::scheduleStyleInvalidationForAttributeChange(const QualifiedName& attributeName, Element& element)
{
- if (RefPtr<DescendantInvalidationSet> invalidationSet = m_attributeInvalidationSets.get(attributeName.localName())) {
- ensurePendingInvalidationList(element).append(invalidationSet);
- element->setNeedsStyleInvalidation();
- }
+ if (RefPtr<DescendantInvalidationSet> invalidationSet = m_attributeInvalidationSets.get(attributeName.localName()))
+ m_styleInvalidator.scheduleInvalidation(invalidationSet, element);
}
-void RuleFeatureSet::addClassToInvalidationSet(const AtomicString& className, Element* element)
+void RuleFeatureSet::addClassToInvalidationSet(const AtomicString& className, Element& element)
{
- if (RefPtr<DescendantInvalidationSet> invalidationSet = m_classInvalidationSets.get(className)) {
- ensurePendingInvalidationList(element).append(invalidationSet);
- element->setNeedsStyleInvalidation();
- }
+ if (RefPtr<DescendantInvalidationSet> invalidationSet = m_classInvalidationSets.get(className))
+ m_styleInvalidator.scheduleInvalidation(invalidationSet, element);
}
-RuleFeatureSet::InvalidationList& RuleFeatureSet::ensurePendingInvalidationList(Element* element)
+StyleInvalidator& RuleFeatureSet::styleInvalidator()
{
- PendingInvalidationMap::AddResult addResult = m_pendingInvalidationMap.add(element, nullptr);
- if (addResult.isNewEntry)
- addResult.storedValue->value = adoptPtr(new InvalidationList);
- return *addResult.storedValue->value;
-}
-
-void RuleFeatureSet::clearStyleInvalidation(Node* node)
-{
- node->clearChildNeedsStyleInvalidation();
- node->clearNeedsStyleInvalidation();
- if (node->isElementNode())
- m_pendingInvalidationMap.remove(toElement(node));
-}
-
-RuleFeatureSet::PendingInvalidationMap& RuleFeatureSet::pendingInvalidationMap()
-{
- return m_pendingInvalidationMap;
+ return m_styleInvalidator;
}
} // namespace WebCore
diff --git a/Source/core/css/RuleFeature.h b/Source/core/css/RuleFeature.h
index 2e6a9b7..6103e22 100644
--- a/Source/core/css/RuleFeature.h
+++ b/Source/core/css/RuleFeature.h
@@ -23,6 +23,7 @@
#define RuleFeature_h
#include "core/css/invalidation/DescendantInvalidationSet.h"
+#include "core/css/invalidation/StyleInvalidator.h"
#include "wtf/Forward.h"
#include "wtf/HashSet.h"
#include "wtf/text/AtomicStringHash.h"
@@ -84,13 +85,10 @@
return m_metadata.idsInRules.contains(idValue);
}
- void scheduleStyleInvalidationForClassChange(const SpaceSplitString& changedClasses, Element*);
- void scheduleStyleInvalidationForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, Element*);
+ void scheduleStyleInvalidationForClassChange(const SpaceSplitString& changedClasses, Element&);
+ void scheduleStyleInvalidationForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, Element&);
- void scheduleStyleInvalidationForAttributeChange(const QualifiedName& attributeName, Element*);
-
- // Clears all style invalidation state for the passed node.
- void clearStyleInvalidation(Node*);
+ void scheduleStyleInvalidationForAttributeChange(const QualifiedName& attributeName, Element&);
int hasIdsInSelectors() const
{
@@ -102,14 +100,11 @@
// FIXME: record these internally to this class instead calls from StyleResolver to here.
void addContentAttr(const AtomicString& attributeName);
+ StyleInvalidator& styleInvalidator();
+
Vector<RuleFeature> siblingRules;
Vector<RuleFeature> uncommonAttributeRules;
- typedef Vector<RefPtr<DescendantInvalidationSet> > InvalidationList;
- typedef HashMap<Element*, OwnPtr<InvalidationList> > PendingInvalidationMap;
-
- PendingInvalidationMap& pendingInvalidationMap();
-
private:
typedef HashMap<AtomicString, RefPtr<DescendantInvalidationSet> > InvalidationSetMap;
@@ -134,7 +129,7 @@
UseSubtreeStyleChange
};
- static InvalidationSetMode supportsClassDescendantInvalidation(const CSSSelector&);
+ static InvalidationSetMode invalidationSetModeForSelector(const CSSSelector&);
void collectFeaturesFromSelector(const CSSSelector&, FeatureMetadata&, InvalidationSetMode);
void collectFeaturesFromSelectorList(const CSSSelectorList*, FeatureMetadata&, InvalidationSetMode);
@@ -146,27 +141,25 @@
InvalidationSetMode updateInvalidationSets(const CSSSelector&);
struct InvalidationSetFeatures {
+ InvalidationSetFeatures() : customPseudoElement(false) { }
Vector<AtomicString> classes;
Vector<AtomicString> attributes;
AtomicString id;
AtomicString tagName;
+ bool customPseudoElement;
};
static void extractInvalidationSetFeature(const CSSSelector&, InvalidationSetFeatures&);
const CSSSelector* extractInvalidationSetFeatures(const CSSSelector&, InvalidationSetFeatures&);
void addFeaturesToInvalidationSets(const CSSSelector&, const InvalidationSetFeatures&);
- void addClassToInvalidationSet(const AtomicString& className, Element*);
-
- InvalidationList& ensurePendingInvalidationList(Element*);
+ void addClassToInvalidationSet(const AtomicString& className, Element&);
FeatureMetadata m_metadata;
InvalidationSetMap m_classInvalidationSets;
InvalidationSetMap m_attributeInvalidationSets;
-
- PendingInvalidationMap m_pendingInvalidationMap;
-
bool m_targetedStyleRecalcEnabled;
+ StyleInvalidator m_styleInvalidator;
};
diff --git a/Source/core/css/RuleSet.cpp b/Source/core/css/RuleSet.cpp
index fefc1e4..a745456 100644
--- a/Source/core/css/RuleSet.cpp
+++ b/Source/core/css/RuleSet.cpp
@@ -177,10 +177,12 @@
#endif
const CSSSelector* it = &component;
- for (; it->relation() == CSSSelector::SubSelector; it = it->tagHistory()) {
+ for (; it && it->relation() == CSSSelector::SubSelector; it = it->tagHistory()) {
extractValuesforSelector(it, id, className, customPseudoElementName, tagName);
}
- extractValuesforSelector(it, id, className, customPseudoElementName, tagName);
+ // FIXME: this null check should not be necessary. See crbug.com/358475
+ if (it)
+ extractValuesforSelector(it, id, className, customPseudoElementName, tagName);
// Prefer rule sets in order of most likely to apply infrequently.
if (!id.isEmpty()) {
diff --git a/Source/core/css/RuntimeCSSEnabled.cpp b/Source/core/css/RuntimeCSSEnabled.cpp
index 07864df..fe1c429 100644
--- a/Source/core/css/RuntimeCSSEnabled.cpp
+++ b/Source/core/css/RuntimeCSSEnabled.cpp
@@ -52,7 +52,6 @@
setCSSPropertiesEnabled(exclusionProperties, WTF_ARRAY_LENGTH(exclusionProperties), RuntimeEnabledFeatures::cssExclusionsEnabled());
CSSPropertyID shapeProperties[] = {
CSSPropertyShapeMargin,
- CSSPropertyShapePadding,
CSSPropertyShapeImageThreshold,
CSSPropertyShapeOutside,
};
@@ -83,6 +82,7 @@
CSSPropertyGridArea,
CSSPropertyGridAutoFlow,
CSSPropertyGridTemplateAreas,
+ CSSPropertyGridTemplate,
CSSPropertyJustifySelf
};
setCSSPropertiesEnabled(cssGridLayoutProperties, WTF_ARRAY_LENGTH(cssGridLayoutProperties), RuntimeEnabledFeatures::cssGridLayoutEnabled());
diff --git a/Source/core/css/StylePropertySerializer.cpp b/Source/core/css/StylePropertySerializer.cpp
index 489527f..3b6e94a 100644
--- a/Source/core/css/StylePropertySerializer.cpp
+++ b/Source/core/css/StylePropertySerializer.cpp
@@ -313,6 +313,7 @@
return getShorthandValue(webkitTextEmphasisShorthand());
case CSSPropertyWebkitTextStroke:
return getShorthandValue(webkitTextStrokeShorthand());
+ case CSSPropertyTransformOrigin:
case CSSPropertyWebkitTransformOrigin:
return getShorthandValue(webkitTransformOriginShorthand());
case CSSPropertyWebkitTransition:
diff --git a/Source/core/css/invalidation/DescendantInvalidationSet.cpp b/Source/core/css/invalidation/DescendantInvalidationSet.cpp
index f7c802d..18bd5b6 100644
--- a/Source/core/css/invalidation/DescendantInvalidationSet.cpp
+++ b/Source/core/css/invalidation/DescendantInvalidationSet.cpp
@@ -38,6 +38,7 @@
DescendantInvalidationSet::DescendantInvalidationSet()
: m_allDescendantsMightBeInvalid(false)
+ , m_customPseudoInvalid(false)
{
}
@@ -52,6 +53,9 @@
return;
}
+ if (other.customPseudoInvalid())
+ setCustomPseudoInvalid();
+
if (other.m_classes) {
HashSet<AtomicString>::const_iterator end = other.m_classes->end();
for (HashSet<AtomicString>::const_iterator it = other.m_classes->begin(); it != end; ++it)
diff --git a/Source/core/css/invalidation/DescendantInvalidationSet.h b/Source/core/css/invalidation/DescendantInvalidationSet.h
index 93c18e6..92646fc 100644
--- a/Source/core/css/invalidation/DescendantInvalidationSet.h
+++ b/Source/core/css/invalidation/DescendantInvalidationSet.h
@@ -66,6 +66,10 @@
void setWholeSubtreeInvalid();
bool wholeSubtreeInvalid() const { return m_allDescendantsMightBeInvalid; }
+
+ void setCustomPseudoInvalid() { m_customPseudoInvalid = true; }
+ bool customPseudoInvalid() const { return m_customPseudoInvalid; }
+
private:
DescendantInvalidationSet();
@@ -77,6 +81,9 @@
// If true, all descendants might be invalidated, so a full subtree recalc is required.
bool m_allDescendantsMightBeInvalid;
+ // If true, all descendants which are custom pseudo elements must be invalidated.
+ bool m_customPseudoInvalid;
+
// FIXME: optimize this if it becomes a memory issue.
OwnPtr<HashSet<AtomicString> > m_classes;
OwnPtr<HashSet<AtomicString> > m_ids;
diff --git a/Source/core/css/invalidation/StyleInvalidator.cpp b/Source/core/css/invalidation/StyleInvalidator.cpp
index fe40049..947c135 100644
--- a/Source/core/css/invalidation/StyleInvalidator.cpp
+++ b/Source/core/css/invalidation/StyleInvalidator.cpp
@@ -16,24 +16,50 @@
namespace WebCore {
-void StyleInvalidator::invalidate()
+void StyleInvalidator::invalidate(Document& document)
{
- if (Element* documentElement = m_document.documentElement())
+ if (Element* documentElement = document.documentElement())
invalidate(*documentElement);
- m_document.clearChildNeedsStyleInvalidation();
- m_document.clearNeedsStyleInvalidation();
+ document.clearChildNeedsStyleInvalidation();
+ document.clearNeedsStyleInvalidation();
+ clearPendingInvalidations();
+}
+
+void StyleInvalidator::scheduleInvalidation(PassRefPtr<DescendantInvalidationSet> invalidationSet, Element& element)
+{
+ ensurePendingInvalidationList(element).append(invalidationSet);
+ element.setNeedsStyleInvalidation();
+}
+
+StyleInvalidator::InvalidationList& StyleInvalidator::ensurePendingInvalidationList(Element& element)
+{
+ PendingInvalidationMap::AddResult addResult = m_pendingInvalidationMap.add(&element, nullptr);
+ if (addResult.isNewEntry)
+ addResult.storedValue->value = adoptPtr(new InvalidationList);
+ return *addResult.storedValue->value;
+}
+
+void StyleInvalidator::clearInvalidation(Node& node)
+{
+ if (node.isElementNode() && node.needsStyleInvalidation())
+ m_pendingInvalidationMap.remove(toElement(&node));
+ node.clearChildNeedsStyleInvalidation();
+ node.clearNeedsStyleInvalidation();
+}
+
+void StyleInvalidator::clearPendingInvalidations()
+{
m_pendingInvalidationMap.clear();
}
-StyleInvalidator::StyleInvalidator(Document& document)
- : m_document(document)
- , m_pendingInvalidationMap(document.styleResolver()->ruleFeatureSet().pendingInvalidationMap())
+StyleInvalidator::StyleInvalidator()
{ }
void StyleInvalidator::RecursionData::pushInvalidationSet(const DescendantInvalidationSet& invalidationSet)
{
invalidationSet.getClasses(m_invalidationClasses);
invalidationSet.getAttributes(m_invalidationAttributes);
+ m_invalidateCustomPseudo = invalidationSet.customPseudoInvalid();
m_foundInvalidationSet = true;
}
@@ -52,6 +78,8 @@
return true;
}
}
+ if (m_invalidateCustomPseudo && element.shadowPseudoId() != nullAtom)
+ return true;
return false;
}
@@ -60,10 +88,10 @@
{
bool thisElementNeedsStyleRecalc = false;
if (element.needsStyleInvalidation()) {
- if (RuleFeatureSet::InvalidationList* invalidationList = m_pendingInvalidationMap.get(&element)) {
+ if (InvalidationList* invalidationList = m_pendingInvalidationMap.get(&element)) {
// FIXME: it's really only necessary to clone the render style for this element, not full style recalc.
thisElementNeedsStyleRecalc = true;
- for (RuleFeatureSet::InvalidationList::const_iterator it = invalidationList->begin(); it != invalidationList->end(); ++it) {
+ for (InvalidationList::const_iterator it = invalidationList->begin(); it != invalidationList->end(); ++it) {
m_recursionData.pushInvalidationSet(**it);
if ((*it)->wholeSubtreeInvalid()) {
element.setNeedsStyleRecalc(SubtreeStyleChange);
diff --git a/Source/core/css/invalidation/StyleInvalidator.h b/Source/core/css/invalidation/StyleInvalidator.h
index 77e6071..d92921c 100644
--- a/Source/core/css/invalidation/StyleInvalidator.h
+++ b/Source/core/css/invalidation/StyleInvalidator.h
@@ -5,16 +5,24 @@
#ifndef StyleInvalidator_h
#define StyleInvalidator_h
-#include "core/css/RuleFeature.h"
#include "heap/Heap.h"
namespace WebCore {
+class DescendantInvalidationSet;
+class Document;
+class Element;
+
class StyleInvalidator {
- STACK_ALLOCATED();
public:
- explicit StyleInvalidator(Document&);
- void invalidate();
+ StyleInvalidator();
+ void invalidate(Document&);
+ void scheduleInvalidation(PassRefPtr<DescendantInvalidationSet>, Element&);
+
+ // Clears all style invalidation state for the passed node.
+ void clearInvalidation(Node&);
+
+ void clearPendingInvalidations();
private:
bool invalidate(Element&);
@@ -23,7 +31,10 @@
bool checkInvalidationSetsAgainstElement(Element&);
struct RecursionData {
- RecursionData() : m_foundInvalidationSet(false) { }
+ RecursionData()
+ : m_foundInvalidationSet(false)
+ , m_invalidateCustomPseudo(false)
+ { }
void pushInvalidationSet(const DescendantInvalidationSet&);
bool matchesCurrentInvalidationSets(Element&);
bool foundInvalidationSet() { return m_foundInvalidationSet; }
@@ -31,6 +42,7 @@
Vector<AtomicString> m_invalidationClasses;
Vector<AtomicString> m_invalidationAttributes;
bool m_foundInvalidationSet;
+ bool m_invalidateCustomPseudo;
};
class RecursionCheckpoint {
@@ -39,6 +51,7 @@
: m_prevClassLength(data->m_invalidationClasses.size()),
m_prevAttributeLength(data->m_invalidationAttributes.size()),
m_prevFoundInvalidationSet(data->m_foundInvalidationSet),
+ m_prevInvalidateCustomPseudo(data->m_invalidateCustomPseudo),
m_data(data)
{ }
~RecursionCheckpoint()
@@ -46,17 +59,23 @@
m_data->m_invalidationClasses.remove(m_prevClassLength, m_data->m_invalidationClasses.size() - m_prevClassLength);
m_data->m_invalidationAttributes.remove(m_prevAttributeLength, m_data->m_invalidationAttributes.size() - m_prevAttributeLength);
m_data->m_foundInvalidationSet = m_prevFoundInvalidationSet;
+ m_data->m_invalidateCustomPseudo = m_prevInvalidateCustomPseudo;
}
private:
int m_prevClassLength;
int m_prevAttributeLength;
bool m_prevFoundInvalidationSet;
+ bool m_prevInvalidateCustomPseudo;
RecursionData* m_data;
};
- Document& m_document;
- RuleFeatureSet::PendingInvalidationMap& m_pendingInvalidationMap;
+ typedef Vector<RefPtr<DescendantInvalidationSet> > InvalidationList;
+ typedef HashMap<Element*, OwnPtr<InvalidationList> > PendingInvalidationMap;
+
+ InvalidationList& ensurePendingInvalidationList(Element&);
+
+ PendingInvalidationMap m_pendingInvalidationMap;
RecursionData m_recursionData;
};
diff --git a/Source/core/css/parser/BisonCSSParser-in.cpp b/Source/core/css/parser/BisonCSSParser-in.cpp
index 1bd084d..59dc912 100644
--- a/Source/core/css/parser/BisonCSSParser-in.cpp
+++ b/Source/core/css/parser/BisonCSSParser-in.cpp
@@ -109,7 +109,7 @@
: m_context(context)
, m_important(false)
, m_id(CSSPropertyInvalid)
- , m_styleSheet(0)
+ , m_styleSheet(nullptr)
, m_supportsCondition(false)
, m_selectorListForParseSelector(0)
, m_numParsedPropertiesBeforeMarginBox(INVALID_NUM_PARSED_PROPERTIES)
@@ -129,7 +129,6 @@
#if YYDEBUG > 0
cssyydebug = 1;
#endif
- CSSPropertySourceData::init();
}
BisonCSSParser::~BisonCSSParser()
@@ -287,7 +286,6 @@
acceptsNegativeNumbers = false;
return true;
case CSSPropertyShapeMargin:
- case CSSPropertyShapePadding:
acceptsNegativeNumbers = false;
return RuntimeEnabledFeatures::cssShapesEnabled();
case CSSPropertyBottom:
@@ -331,7 +329,7 @@
static bool parseSimpleLengthValue(MutableStylePropertySet* declaration, CSSPropertyID propertyId, const String& string, bool important, CSSParserMode cssParserMode)
{
ASSERT(!string.isEmpty());
- bool acceptsNegativeNumbers;
+ bool acceptsNegativeNumbers = false;
// In @viewport, width and height are shorthands, not simple length values.
if (isCSSViewportParsingEnabledForMode(cssParserMode) || !isSimpleLengthPropertyID(propertyId, acceptsNegativeNumbers))
@@ -971,7 +969,7 @@
static bool parseTranslateTransform(MutableStylePropertySet* properties, CSSPropertyID propertyID, const String& string, bool important)
{
- if (propertyID != CSSPropertyWebkitTransform)
+ if (propertyID != CSSPropertyTransform && propertyID != CSSPropertyWebkitTransform)
return false;
if (string.isEmpty())
return false;
@@ -989,7 +987,7 @@
if (!transformList)
return false;
}
- properties->addParsedProperty(CSSProperty(CSSPropertyWebkitTransform, transformList.release(), important));
+ properties->addParsedProperty(CSSProperty(propertyID, transformList.release(), important));
return true;
}
@@ -1212,6 +1210,19 @@
return ok;
}
+PassRefPtrWillBeRawPtr<MediaQuerySet> BisonCSSParser::parseMediaQueryList(const String& string)
+{
+ ASSERT(!m_mediaList);
+
+ // can't use { because tokenizer state switches from mediaquery to initial state when it sees { token.
+ // instead insert one " " (which is caught by maybe_space in CSSGrammar.y)
+ setupParser("@-internal-medialist ", string, "");
+ cssyyparse(this);
+
+ ASSERT(m_mediaList);
+ return m_mediaList.release();
+}
+
static inline void filterProperties(bool important, const WillBeHeapVector<CSSProperty, 256>& input, WillBeHeapVector<CSSProperty, 256>& output, size_t& unusedEntries, BitArray<numCSSProperties>& seenProperties)
{
// Add properties in reverse order so that highest priority definitions are reached first. Duplicate definitions can then be ignored when found.
@@ -1405,14 +1416,14 @@
CSSPropertyParser::Units m_unit;
};
-PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseTransform()
+PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseTransform(CSSPropertyID propId)
{
if (!m_valueList)
return nullptr;
RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
- RefPtrWillBeRawPtr<CSSValue> parsedTransformValue = parseTransformValue(value);
+ RefPtrWillBeRawPtr<CSSValue> parsedTransformValue = parseTransformValue(propId, value);
if (!parsedTransformValue)
return nullptr;
@@ -1422,7 +1433,7 @@
return list.release();
}
-PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseTransformValue(CSSParserValue *value)
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseTransformValue(CSSPropertyID propId, CSSParserValue *value)
{
if (value->unit != CSSParserValue::Function || !value->function)
return nullptr;
@@ -1466,7 +1477,8 @@
return nullptr;
} else if (info.type() == CSSTransformValue::PerspectiveTransformOperation && !argNumber) {
// 1st param of perspective() must be a non-negative number (deprecated) or length.
- if (!validUnit(a, FNumber | FLength | FNonNeg, HTMLStandardMode))
+ if ((propId == CSSPropertyWebkitTransform && !validUnit(a, FNumber | FLength | FNonNeg, HTMLStandardMode))
+ || (propId == CSSPropertyTransform && !validUnit(a, FLength | FNonNeg, HTMLStandardMode)))
return nullptr;
} else if (!validUnit(a, unit, HTMLStandardMode)) {
return nullptr;
@@ -1682,7 +1694,7 @@
{
m_allowImportRules = m_allowNamespaceDeclarations = false;
- RefPtr<CSSRuleSourceData> data = popSupportsRuleData();
+ RefPtrWillBeRawPtr<CSSRuleSourceData> data = popSupportsRuleData();
RefPtrWillBeRawPtr<StyleRuleSupports> rule = nullptr;
String conditionText;
unsigned conditionOffset = data->ruleHeaderRange.start + 9;
@@ -1709,9 +1721,9 @@
void BisonCSSParser::markSupportsRuleHeaderStart()
{
if (!m_supportsRuleDataStack)
- m_supportsRuleDataStack = adoptPtr(new RuleSourceDataList());
+ m_supportsRuleDataStack = adoptPtrWillBeNoop(new RuleSourceDataList());
- RefPtr<CSSRuleSourceData> data = CSSRuleSourceData::create(CSSRuleSourceData::SUPPORTS_RULE);
+ RefPtrWillBeRawPtr<CSSRuleSourceData> data = CSSRuleSourceData::create(CSSRuleSourceData::SUPPORTS_RULE);
data->ruleHeaderRange.start = m_tokenizer.tokenStartOffset();
m_supportsRuleDataStack->append(data);
}
@@ -1726,10 +1738,10 @@
m_supportsRuleDataStack->last()->ruleHeaderRange.end = m_tokenizer.tokenStart<UChar>() - m_tokenizer.m_dataStart16.get();
}
-PassRefPtr<CSSRuleSourceData> BisonCSSParser::popSupportsRuleData()
+PassRefPtrWillBeRawPtr<CSSRuleSourceData> BisonCSSParser::popSupportsRuleData()
{
ASSERT(m_supportsRuleDataStack && !m_supportsRuleDataStack->isEmpty());
- RefPtr<CSSRuleSourceData> data = m_supportsRuleDataStack->last();
+ RefPtrWillBeRawPtr<CSSRuleSourceData> data = m_supportsRuleDataStack->last();
m_supportsRuleDataStack->removeLast();
return data.release();
}
diff --git a/Source/core/css/parser/BisonCSSParser.h b/Source/core/css/parser/BisonCSSParser.h
index 90c9c7e..d801e31 100644
--- a/Source/core/css/parser/BisonCSSParser.h
+++ b/Source/core/css/parser/BisonCSSParser.h
@@ -78,10 +78,10 @@
};
class BisonCSSParser {
+ STACK_ALLOCATED();
friend inline int cssyylex(void*, BisonCSSParser*);
-
public:
- BisonCSSParser(const CSSParserContext&);
+ explicit BisonCSSParser(const CSSParserContext&);
~BisonCSSParser();
void rollbackLastProperties(int num);
@@ -98,6 +98,7 @@
static PassRefPtrWillBeRawPtr<CSSValue> parseAnimationTimingFunctionValue(const String&);
bool parseDeclaration(MutableStylePropertySet*, const String&, CSSParserObserver*, StyleSheetContents* contextStyleSheet);
static PassRefPtr<ImmutableStylePropertySet> parseInlineStyleDeclaration(const String&, Element*);
+ PassRefPtrWillBeRawPtr<MediaQuerySet> parseMediaQueryList(const String&);
PassOwnPtr<Vector<double> > parseKeyframeKeyList(const String&);
static bool parseValue(MutableStylePropertySet*, CSSPropertyID, const String&, bool important, const Document&);
@@ -137,7 +138,7 @@
StyleRuleBase* createSupportsRule(bool conditionIsSupported, RuleList*);
void markSupportsRuleHeaderStart();
void markSupportsRuleHeaderEnd();
- PassRefPtr<CSSRuleSourceData> popSupportsRuleData();
+ PassRefPtrWillBeRawPtr<CSSRuleSourceData> popSupportsRuleData();
StyleRuleBase* createHostRule(RuleList* rules);
void startDeclarationsForMarginBox();
@@ -177,14 +178,14 @@
bool m_important;
CSSPropertyID m_id;
- StyleSheetContents* m_styleSheet;
- RefPtrWillBePersistent<StyleRuleBase> m_rule;
- RefPtrWillBePersistent<StyleKeyframe> m_keyframe;
- RefPtrWillBePersistent<MediaQuerySet> m_mediaList;
+ RawPtrWillBeMember<StyleSheetContents> m_styleSheet;
+ RefPtrWillBeMember<StyleRuleBase> m_rule;
+ RefPtrWillBeMember<StyleKeyframe> m_keyframe;
+ RefPtrWillBeMember<MediaQuerySet> m_mediaList;
OwnPtr<CSSParserValueList> m_valueList;
bool m_supportsCondition;
- WillBePersistentHeapVector<CSSProperty, 256> m_parsedProperties;
+ WillBeHeapVector<CSSProperty, 256> m_parsedProperties;
CSSSelectorList* m_selectorListForParseSelector;
unsigned m_numParsedPropertiesBeforeMarginBox;
@@ -227,6 +228,7 @@
private:
class StyleDeclarationScope {
+ STACK_ALLOCATED();
WTF_MAKE_NONCOPYABLE(StyleDeclarationScope);
public:
StyleDeclarationScope(BisonCSSParser* parser, const StylePropertySet* declaration)
@@ -288,24 +290,24 @@
CSSParserLocation m_locationLabel;
- WillBePersistentHeapVector<RefPtrWillBeMember<StyleRuleBase> > m_parsedRules;
- WillBePersistentHeapVector<RefPtrWillBeMember<StyleKeyframe> > m_parsedKeyframes;
- WillBePersistentHeapVector<RefPtrWillBeMember<MediaQuerySet> > m_parsedMediaQuerySets;
- WillBePersistentHeapVector<OwnPtrWillBeMember<RuleList> > m_parsedRuleLists;
+ WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> > m_parsedRules;
+ WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> > m_parsedKeyframes;
+ WillBeHeapVector<RefPtrWillBeMember<MediaQuerySet> > m_parsedMediaQuerySets;
+ WillBeHeapVector<OwnPtrWillBeMember<RuleList> > m_parsedRuleLists;
Vector<CSSParserSelector*> m_floatingSelectors;
Vector<Vector<OwnPtr<CSSParserSelector> >*> m_floatingSelectorVectors;
Vector<CSSParserValueList*> m_floatingValueLists;
Vector<CSSParserFunction*> m_floatingFunctions;
- OwnPtrWillBePersistent<MediaQuery> m_floatingMediaQuery;
- OwnPtrWillBePersistent<MediaQueryExp> m_floatingMediaQueryExp;
- OwnPtrWillBePersistent<WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > > m_floatingMediaQueryExpList;
+ OwnPtrWillBeMember<MediaQuery> m_floatingMediaQuery;
+ OwnPtrWillBeMember<MediaQueryExp> m_floatingMediaQueryExp;
+ OwnPtrWillBeMember<WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > > m_floatingMediaQueryExpList;
- OwnPtrWillBePersistent<WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> > > m_floatingKeyframeVector;
+ OwnPtrWillBeMember<WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> > > m_floatingKeyframeVector;
Vector<OwnPtr<CSSParserSelector> > m_reusableSelectorVector;
- OwnPtr<RuleSourceDataList> m_supportsRuleDataStack;
+ OwnPtrWillBeMember<RuleSourceDataList> m_supportsRuleDataStack;
bool isLoggingErrors();
void logError(const String& message, const CSSParserLocation&);
diff --git a/Source/core/css/parser/CSSParserObserver.h b/Source/core/css/parser/CSSParserObserver.h
index c795f50..c6711a4 100644
--- a/Source/core/css/parser/CSSParserObserver.h
+++ b/Source/core/css/parser/CSSParserObserver.h
@@ -49,6 +49,7 @@
// This only implemented by StyleSheetHandler in InspectorStyleSheet.cpp.
class CSSParserObserver {
+ STACK_ALLOCATED();
public:
virtual void startRuleHeader(CSSRuleSourceData::Type, unsigned offset) = 0;
virtual void endRuleHeader(unsigned offset) = 0;
diff --git a/Source/core/css/parser/CSSPropertyParser.cpp b/Source/core/css/parser/CSSPropertyParser.cpp
index 5b96d31..8a1a642 100644
--- a/Source/core/css/parser/CSSPropertyParser.cpp
+++ b/Source/core/css/parser/CSSPropertyParser.cpp
@@ -1108,11 +1108,12 @@
else
validPrimitive = validUnit(value, FTime | FInteger | FNonNeg);
break;
+ case CSSPropertyTransform:
case CSSPropertyWebkitTransform:
if (id == CSSValueNone)
validPrimitive = true;
else {
- RefPtrWillBeRawPtr<CSSValue> transformValue = parseTransform();
+ RefPtrWillBeRawPtr<CSSValue> transformValue = parseTransform(propId);
if (transformValue) {
addProperty(propId, transformValue.release(), important);
return true;
@@ -1120,6 +1121,18 @@
return false;
}
break;
+ case CSSPropertyTransformOrigin: {
+ RefPtrWillBeRawPtr<CSSValueList> list = parseTransformOrigin();
+ if (!list)
+ return false;
+ // These values are added to match gecko serialization.
+ if (list->length() == 1)
+ list->append(cssValuePool().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE));
+ if (list->length() == 2)
+ list->append(cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PX));
+ addProperty(propId, list.release(), important);
+ return true;
+ }
case CSSPropertyWebkitTransformOrigin:
case CSSPropertyWebkitTransformOriginX:
case CSSPropertyWebkitTransformOriginY:
@@ -1128,7 +1141,7 @@
RefPtrWillBeRawPtr<CSSValue> val2 = nullptr;
RefPtrWillBeRawPtr<CSSValue> val3 = nullptr;
CSSPropertyID propId1, propId2, propId3;
- if (parseTransformOrigin(propId, propId1, propId2, propId3, val1, val2, val3)) {
+ if (parseWebkitTransformOrigin(propId, propId1, propId2, propId3, val1, val2, val3)) {
addProperty(propId1, val1.release(), important);
if (val2)
addProperty(propId2, val2.release(), important);
@@ -1138,28 +1151,40 @@
}
return false;
}
- case CSSPropertyWebkitPerspective:
- if (id == CSSValueNone)
+ case CSSPropertyPerspective:
+ if (id == CSSValueNone) {
validPrimitive = true;
- else {
- // Accepting valueless numbers is a quirk of the -webkit prefixed version of the property.
- if (validUnit(value, FNumber | FLength | FNonNeg)) {
- RefPtrWillBeRawPtr<CSSValue> val = createPrimitiveNumericValue(value);
- if (val) {
- addProperty(propId, val.release(), important);
- return true;
- }
- return false;
- }
+ } else if (validUnit(value, FLength | FNonNeg)) {
+ addProperty(propId, createPrimitiveNumericValue(value), important);
+ return true;
}
break;
+ case CSSPropertyWebkitPerspective:
+ if (id == CSSValueNone) {
+ validPrimitive = true;
+ } else if (validUnit(value, FNumber | FLength | FNonNeg)) {
+ // Accepting valueless numbers is a quirk of the -webkit prefixed version of the property.
+ addProperty(propId, createPrimitiveNumericValue(value), important);
+ return true;
+ }
+ break;
+ case CSSPropertyPerspectiveOrigin: {
+ RefPtrWillBeRawPtr<CSSValueList> list = parseTransformOrigin();
+ if (!list || list->length() == 3)
+ return false;
+ // This values are added to match gecko serialization.
+ if (list->length() == 1)
+ list->append(cssValuePool().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE));
+ addProperty(propId, list.release(), important);
+ return true;
+ }
case CSSPropertyWebkitPerspectiveOrigin:
case CSSPropertyWebkitPerspectiveOriginX:
case CSSPropertyWebkitPerspectiveOriginY: {
RefPtrWillBeRawPtr<CSSValue> val1 = nullptr;
RefPtrWillBeRawPtr<CSSValue> val2 = nullptr;
CSSPropertyID propId1, propId2;
- if (parsePerspectiveOrigin(propId, propId1, propId2, val1, val2)) {
+ if (parseWebkitPerspectiveOrigin(propId, propId1, propId2, val1, val2)) {
addProperty(propId1, val1.release(), important);
if (val2)
addProperty(propId2, val2.release(), important);
@@ -1218,7 +1243,8 @@
case CSSPropertyGridTemplateRows:
if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
return false;
- return parseGridTrackList(propId, important);
+ parsedValue = parseGridTrackList(important);
+ break;
case CSSPropertyGridColumnEnd:
case CSSPropertyGridColumnStart:
@@ -1246,6 +1272,11 @@
parsedValue = parseGridTemplateAreas();
break;
+ case CSSPropertyGridTemplate:
+ if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
+ return false;
+ return parseGridTemplateShorthand(important);
+
case CSSPropertyWebkitMarginCollapse: {
if (num == 1) {
ShorthandScope scope(this, CSSPropertyWebkitMarginCollapse);
@@ -1483,7 +1514,6 @@
parsedValue = parseShapeProperty(propId);
break;
case CSSPropertyShapeMargin:
- case CSSPropertyShapePadding:
validPrimitive = (RuntimeEnabledFeatures::cssShapesEnabled() && !id && validUnit(value, FLength | FNonNeg));
break;
case CSSPropertyShapeImageThreshold:
@@ -1609,12 +1639,6 @@
case CSSPropertyUserZoom:
validPrimitive = false;
break;
- // FIXME: crbug.com/154772 Unimplemented css-transforms properties
- case CSSPropertyPerspective:
- case CSSPropertyPerspectiveOrigin:
- case CSSPropertyTransform:
- case CSSPropertyTransformOrigin:
- return false;
default:
return parseSVGValue(propId, important);
}
@@ -3103,7 +3127,7 @@
return nullptr;
}
-bool CSSPropertyParser::parseTransformOriginShorthand(RefPtrWillBeRawPtr<CSSValue>& value1, RefPtrWillBeRawPtr<CSSValue>& value2, RefPtrWillBeRawPtr<CSSValue>& value3)
+bool CSSPropertyParser::parseWebkitTransformOriginShorthand(RefPtrWillBeRawPtr<CSSValue>& value1, RefPtrWillBeRawPtr<CSSValue>& value2, RefPtrWillBeRawPtr<CSSValue>& value3)
{
parse2ValuesFillPosition(m_valueList.get(), value1, value2);
@@ -3458,6 +3482,122 @@
return true;
}
+bool CSSPropertyParser::parseGridTemplateRowsAndAreas(PassRefPtrWillBeRawPtr<CSSValue> templateColumns, bool important)
+{
+ NamedGridAreaMap gridAreaMap;
+ size_t rowCount = 0;
+ size_t columnCount = 0;
+ bool trailingIdentWasAdded = false;
+ RefPtrWillBeRawPtr<CSSValueList> templateRows = CSSValueList::createSpaceSeparated();
+
+ // At least template-areas strings must be defined.
+ if (!m_valueList->current())
+ return false;
+
+ while (m_valueList->current()) {
+ // Handle leading <custom-ident>*.
+ if (m_valueList->current()->unit == CSSParserValue::ValueList) {
+ if (trailingIdentWasAdded) {
+ // A row's trailing ident must be concatenated with the next row's leading one.
+ parseGridLineNames(*m_valueList, *templateRows, static_cast<CSSGridLineNamesValue*>(templateRows->item(templateRows->length() - 1)));
+ } else {
+ parseGridLineNames(*m_valueList, *templateRows);
+ }
+ }
+
+ // Handle a template-area's row.
+ if (!parseGridTemplateAreasRow(gridAreaMap, rowCount, columnCount))
+ return false;
+ ++rowCount;
+
+ // Handle template-rows's track-size.
+ if (m_valueList->current() && m_valueList->current()->unit != CSSParserValue::ValueList && m_valueList->current()->unit != CSSPrimitiveValue::CSS_STRING) {
+ RefPtrWillBeRawPtr<CSSValue> value = parseGridTrackSize(*m_valueList);
+ if (!value)
+ return false;
+ templateRows->append(value);
+ } else {
+ templateRows->append(cssValuePool().createIdentifierValue(CSSValueAuto));
+ }
+
+ // This will handle the trailing/leading <custom-ident>* in the grammar.
+ trailingIdentWasAdded = false;
+ if (m_valueList->current() && m_valueList->current()->unit == CSSParserValue::ValueList) {
+ parseGridLineNames(*m_valueList, *templateRows);
+ trailingIdentWasAdded = true;
+ }
+ }
+
+ // [<track-list> /]?
+ if (templateColumns)
+ addProperty(CSSPropertyGridTemplateColumns, templateColumns, important);
+ else
+ addProperty(CSSPropertyGridTemplateColumns, cssValuePool().createIdentifierValue(CSSValueNone), important);
+
+ // [<line-names>? <string> [<track-size> <line-names>]? ]+
+ RefPtrWillBeRawPtr<CSSValue> templateAreas = CSSGridTemplateAreasValue::create(gridAreaMap, rowCount, columnCount);
+ addProperty(CSSPropertyGridTemplateAreas, templateAreas.release(), important);
+ addProperty(CSSPropertyGridTemplateRows, templateRows.release(), important);
+
+
+ return true;
+}
+
+
+bool CSSPropertyParser::parseGridTemplateShorthand(bool important)
+{
+ ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
+
+ ShorthandScope scope(this, CSSPropertyGridTemplate);
+ ASSERT(gridTemplateShorthand().length() == 3);
+
+ // At least "none" must be defined.
+ if (!m_valueList->current())
+ return false;
+
+ bool firstValueIsNone = m_valueList->current()->id == CSSValueNone;
+
+ // 1- 'none' case.
+ if (firstValueIsNone && !m_valueList->next()) {
+ addProperty(CSSPropertyGridTemplateColumns, cssValuePool().createIdentifierValue(CSSValueNone), important);
+ addProperty(CSSPropertyGridTemplateRows, cssValuePool().createIdentifierValue(CSSValueNone), important);
+ addProperty(CSSPropertyGridTemplateAreas, cssValuePool().createIdentifierValue(CSSValueNone), important);
+ return true;
+ }
+
+ unsigned index = 0;
+ RefPtrWillBeRawPtr<CSSValue> columnsValue = nullptr;
+ if (firstValueIsNone) {
+ columnsValue = cssValuePool().createIdentifierValue(CSSValueNone);
+ } else {
+ columnsValue = parseGridTrackList(important);
+ }
+
+ // 2- <grid-template-columns> / <grid-template-columns> syntax.
+ if (columnsValue) {
+ if (!(m_valueList->current() && isForwardSlashOperator(m_valueList->current()) && m_valueList->next()))
+ return false;
+ index = m_valueList->currentIndex();
+ if (RefPtrWillBeRawPtr<CSSValue> rowsValue = parseGridTrackList(important)) {
+ if (m_valueList->current())
+ return false;
+ addProperty(CSSPropertyGridTemplateColumns, columnsValue, important);
+ addProperty(CSSPropertyGridTemplateRows, rowsValue, important);
+ addProperty(CSSPropertyGridTemplateAreas, cssValuePool().createIdentifierValue(CSSValueNone), important);
+ return true;
+ }
+ }
+
+
+ // 3- [<track-list> /]? [<line-names>? <string> [<track-size> <line-names>]? ]+ syntax.
+ // The template-columns <track-list> can't be 'none'.
+ if (firstValueIsNone)
+ return false;
+ // It requires to rewind parsing due to previous syntax failures.
+ m_valueList->setCurrentIndex(index);
+ return parseGridTemplateRowsAndAreas(columnsValue, important);
+}
+
bool CSSPropertyParser::parseGridAreaShorthand(bool important)
{
ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
@@ -3513,72 +3653,76 @@
return true;
}
-void CSSPropertyParser::parseGridLineNames(CSSParserValueList* parserValueList, CSSValueList& valueList)
+void CSSPropertyParser::parseGridLineNames(CSSParserValueList& inputList, CSSValueList& valueList, CSSGridLineNamesValue* previousNamedAreaTrailingLineNames)
{
- ASSERT(parserValueList->current() && parserValueList->current()->unit == CSSParserValue::ValueList);
+ ASSERT(inputList.current() && inputList.current()->unit == CSSParserValue::ValueList);
- CSSParserValueList* identList = parserValueList->current()->valueList;
+ CSSParserValueList* identList = inputList.current()->valueList;
if (!identList->size()) {
- parserValueList->next();
+ inputList.next();
return;
}
- RefPtrWillBeRawPtr<CSSGridLineNamesValue> lineNames = CSSGridLineNamesValue::create();
+ // Need to ensure the identList is at the heading index, since the parserList might have been rewound.
+ identList->setCurrentIndex(0);
+
+ RefPtrWillBeRawPtr<CSSGridLineNamesValue> lineNames = previousNamedAreaTrailingLineNames;
+ if (!lineNames)
+ lineNames = CSSGridLineNamesValue::create();
while (CSSParserValue* identValue = identList->current()) {
ASSERT(identValue->unit == CSSPrimitiveValue::CSS_IDENT);
RefPtrWillBeRawPtr<CSSPrimitiveValue> lineName = createPrimitiveStringValue(identValue);
lineNames->append(lineName.release());
identList->next();
}
- valueList.append(lineNames.release());
+ if (!previousNamedAreaTrailingLineNames)
+ valueList.append(lineNames.release());
- parserValueList->next();
+ inputList.next();
}
-bool CSSPropertyParser::parseGridTrackList(CSSPropertyID propId, bool important)
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseGridTrackList(bool important)
{
ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
CSSParserValue* value = m_valueList->current();
if (value->id == CSSValueNone) {
- if (m_valueList->next())
- return false;
-
- addProperty(propId, cssValuePool().createIdentifierValue(value->id), important);
- return true;
+ m_valueList->next();
+ return cssValuePool().createIdentifierValue(CSSValueNone);
}
RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createSpaceSeparated();
// Handle leading <ident>*.
value = m_valueList->current();
if (value && value->unit == CSSParserValue::ValueList)
- parseGridLineNames(m_valueList.get(), *values);
+ parseGridLineNames(*m_valueList, *values);
bool seenTrackSizeOrRepeatFunction = false;
while (CSSParserValue* currentValue = m_valueList->current()) {
+ if (isForwardSlashOperator(currentValue))
+ break;
if (currentValue->unit == CSSParserValue::Function && equalIgnoringCase(currentValue->function->name, "repeat(")) {
if (!parseGridTrackRepeatFunction(*values))
- return false;
+ return nullptr;
seenTrackSizeOrRepeatFunction = true;
} else {
RefPtrWillBeRawPtr<CSSValue> value = parseGridTrackSize(*m_valueList);
if (!value)
- return false;
+ return nullptr;
values->append(value);
seenTrackSizeOrRepeatFunction = true;
}
// This will handle the trailing <ident>* in the grammar.
value = m_valueList->current();
if (value && value->unit == CSSParserValue::ValueList)
- parseGridLineNames(m_valueList.get(), *values);
+ parseGridLineNames(*m_valueList, *values);
}
// We should have found a <track-size> or else it is not a valid <track-list>
if (!seenTrackSizeOrRepeatFunction)
- return false;
+ return nullptr;
- addProperty(propId, values.release(), important);
- return true;
+ return values;
}
bool CSSPropertyParser::parseGridTrackRepeatFunction(CSSValueList& list)
@@ -3596,7 +3740,7 @@
// Handle leading <ident>*.
CSSParserValue* currentValue = arguments->current();
if (currentValue && currentValue->unit == CSSParserValue::ValueList)
- parseGridLineNames(arguments, *repeatedValues);
+ parseGridLineNames(*arguments, *repeatedValues);
while (arguments->current()) {
RefPtrWillBeRawPtr<CSSValue> trackSize = parseGridTrackSize(*arguments);
@@ -3608,7 +3752,7 @@
// This takes care of any trailing <ident>* in the grammar.
currentValue = arguments->current();
if (currentValue && currentValue->unit == CSSParserValue::ValueList)
- parseGridLineNames(arguments, *repeatedValues);
+ parseGridLineNames(*arguments, *repeatedValues);
}
for (size_t i = 0; i < repetitions; ++i) {
@@ -3676,71 +3820,79 @@
return createPrimitiveNumericValue(currentValue);
}
+bool CSSPropertyParser::parseGridTemplateAreasRow(NamedGridAreaMap& gridAreaMap, const size_t rowCount, size_t& columnCount)
+{
+ CSSParserValue* currentValue = m_valueList->current();
+ if (!currentValue || currentValue->unit != CSSPrimitiveValue::CSS_STRING)
+ return false;
+
+ String gridRowNames = currentValue->string;
+ if (!gridRowNames.length())
+ return false;
+
+ Vector<String> columnNames;
+ gridRowNames.split(' ', columnNames);
+
+ if (!columnCount) {
+ columnCount = columnNames.size();
+ ASSERT(columnCount);
+ } else if (columnCount != columnNames.size()) {
+ // The declaration is invalid is all the rows don't have the number of columns.
+ return false;
+ }
+
+ for (size_t currentCol = 0; currentCol < columnCount; ++currentCol) {
+ const String& gridAreaName = columnNames[currentCol];
+
+ // Unamed areas are always valid (we consider them to be 1x1).
+ if (gridAreaName == ".")
+ continue;
+
+ // We handle several grid areas with the same name at once to simplify the validation code.
+ size_t lookAheadCol;
+ for (lookAheadCol = currentCol; lookAheadCol < (columnCount - 1); ++lookAheadCol) {
+ if (columnNames[lookAheadCol + 1] != gridAreaName)
+ break;
+ }
+
+ NamedGridAreaMap::iterator gridAreaIt = gridAreaMap.find(gridAreaName);
+ if (gridAreaIt == gridAreaMap.end()) {
+ gridAreaMap.add(gridAreaName, GridCoordinate(GridSpan(rowCount, rowCount), GridSpan(currentCol, lookAheadCol)));
+ } else {
+ GridCoordinate& gridCoordinate = gridAreaIt->value;
+
+ // The following checks test that the grid area is a single filled-in rectangle.
+ // 1. The new row is adjacent to the previously parsed row.
+ if (rowCount != gridCoordinate.rows.finalPositionIndex + 1)
+ return false;
+
+ // 2. The new area starts at the same position as the previously parsed area.
+ if (currentCol != gridCoordinate.columns.initialPositionIndex)
+ return false;
+
+ // 3. The new area ends at the same position as the previously parsed area.
+ if (lookAheadCol != gridCoordinate.columns.finalPositionIndex)
+ return false;
+
+ ++gridCoordinate.rows.finalPositionIndex;
+ }
+ currentCol = lookAheadCol;
+ }
+
+ m_valueList->next();
+ return true;
+}
+
PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseGridTemplateAreas()
{
NamedGridAreaMap gridAreaMap;
size_t rowCount = 0;
size_t columnCount = 0;
- while (CSSParserValue* currentValue = m_valueList->current()) {
- if (currentValue->unit != CSSPrimitiveValue::CSS_STRING)
+ while (m_valueList->current()) {
+ if (!parseGridTemplateAreasRow(gridAreaMap, rowCount, columnCount))
return nullptr;
-
- String gridRowNames = currentValue->string;
- if (!gridRowNames.length())
- return nullptr;
-
- Vector<String> columnNames;
- gridRowNames.split(' ', columnNames);
-
- if (!columnCount) {
- columnCount = columnNames.size();
- ASSERT(columnCount);
- } else if (columnCount != columnNames.size()) {
- // The declaration is invalid is all the rows don't have the number of columns.
- return nullptr;
- }
-
- for (size_t currentCol = 0; currentCol < columnCount; ++currentCol) {
- const String& gridAreaName = columnNames[currentCol];
-
- // Unamed areas are always valid (we consider them to be 1x1).
- if (gridAreaName == ".")
- continue;
-
- // We handle several grid areas with the same name at once to simplify the validation code.
- size_t lookAheadCol;
- for (lookAheadCol = currentCol; lookAheadCol < (columnCount - 1); ++lookAheadCol) {
- if (columnNames[lookAheadCol + 1] != gridAreaName)
- break;
- }
-
- NamedGridAreaMap::iterator gridAreaIt = gridAreaMap.find(gridAreaName);
- if (gridAreaIt == gridAreaMap.end()) {
- gridAreaMap.add(gridAreaName, GridCoordinate(GridSpan(rowCount, rowCount), GridSpan(currentCol, lookAheadCol)));
- } else {
- GridCoordinate& gridCoordinate = gridAreaIt->value;
-
- // The following checks test that the grid area is a single filled-in rectangle.
- // 1. The new row is adjacent to the previously parsed row.
- if (rowCount != gridCoordinate.rows.finalPositionIndex + 1)
- return nullptr;
-
- // 2. The new area starts at the same position as the previously parsed area.
- if (currentCol != gridCoordinate.columns.initialPositionIndex)
- return nullptr;
-
- // 3. The new area ends at the same position as the previously parsed area.
- if (lookAheadCol != gridCoordinate.columns.finalPositionIndex)
- return nullptr;
-
- ++gridCoordinate.rows.finalPositionIndex;
- }
- currentCol = lookAheadCol;
- }
-
++rowCount;
- m_valueList->next();
}
if (!rowCount || !columnCount)
@@ -7232,8 +7384,71 @@
return list.release();
}
+PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseTransformOrigin()
+{
+ CSSParserValue* value = m_valueList->current();
+ CSSValueID id = value->id;
+ RefPtrWillBeRawPtr<CSSValue> xValue = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> yValue = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> zValue = nullptr;
+ if (id == CSSValueLeft || id == CSSValueRight) {
+ xValue = cssValuePool().createIdentifierValue(id);
+ } else if (id == CSSValueTop || id == CSSValueBottom) {
+ yValue = cssValuePool().createIdentifierValue(id);
+ } else if (id == CSSValueCenter) {
+ // Unresolved as to whether this is X or Y.
+ } else if (validUnit(value, FPercent | FLength)) {
+ xValue = createPrimitiveNumericValue(value);
+ } else {
+ return nullptr;
+ }
-bool CSSPropertyParser::parseTransformOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, CSSPropertyID& propId3, RefPtrWillBeRawPtr<CSSValue>& value, RefPtrWillBeRawPtr<CSSValue>& value2, RefPtrWillBeRawPtr<CSSValue>& value3)
+ if ((value = m_valueList->next())) {
+ id = value->id;
+ if (!xValue && (id == CSSValueLeft || id == CSSValueRight)) {
+ xValue = cssValuePool().createIdentifierValue(id);
+ } else if (!yValue && (id == CSSValueTop || id == CSSValueBottom)) {
+ yValue = cssValuePool().createIdentifierValue(id);
+ } else if (id == CSSValueCenter) {
+ // Resolved below.
+ } else if (!yValue && validUnit(value, FPercent | FLength)) {
+ yValue = createPrimitiveNumericValue(value);
+ } else {
+ return nullptr;
+ }
+
+ // If X or Y have not been resolved, they must be center.
+ if (!xValue)
+ xValue = cssValuePool().createIdentifierValue(CSSValueCenter);
+ if (!yValue)
+ yValue = cssValuePool().createIdentifierValue(CSSValueCenter);
+
+ if ((value = m_valueList->next())) {
+ if (!validUnit(value, FLength))
+ return nullptr;
+ zValue = createPrimitiveNumericValue(value);
+
+ if ((value = m_valueList->next()))
+ return nullptr;
+ }
+ } else if (!xValue) {
+ if (yValue) {
+ xValue = cssValuePool().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE);
+ } else {
+ xValue = cssValuePool().createIdentifierValue(CSSValueCenter);
+ }
+ }
+
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ list->append(xValue.release());
+ if (yValue)
+ list->append(yValue.release());
+ if (zValue)
+ list->append(zValue.release());
+ return list.release();
+}
+
+bool CSSPropertyParser::parseWebkitTransformOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, CSSPropertyID& propId3, RefPtrWillBeRawPtr<CSSValue>& value, RefPtrWillBeRawPtr<CSSValue>& value2, RefPtrWillBeRawPtr<CSSValue>& value3)
{
propId1 = propId;
propId2 = propId;
@@ -7246,9 +7461,9 @@
switch (propId) {
case CSSPropertyWebkitTransformOrigin:
- if (!parseTransformOriginShorthand(value, value2, value3))
+ if (!parseWebkitTransformOriginShorthand(value, value2, value3))
return false;
- // parseTransformOriginShorthand advances the m_valueList pointer
+ // parseWebkitTransformOriginShorthand advances the m_valueList pointer
break;
case CSSPropertyWebkitTransformOriginX: {
value = parseFillPositionX(m_valueList.get());
@@ -7277,7 +7492,7 @@
return value;
}
-bool CSSPropertyParser::parsePerspectiveOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, RefPtrWillBeRawPtr<CSSValue>& value, RefPtrWillBeRawPtr<CSSValue>& value2)
+bool CSSPropertyParser::parseWebkitPerspectiveOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, RefPtrWillBeRawPtr<CSSValue>& value, RefPtrWillBeRawPtr<CSSValue>& value2)
{
propId1 = propId;
propId2 = propId;
diff --git a/Source/core/css/parser/CSSPropertyParser.h b/Source/core/css/parser/CSSPropertyParser.h
index c78a167..11877a3 100644
--- a/Source/core/css/parser/CSSPropertyParser.h
+++ b/Source/core/css/parser/CSSPropertyParser.h
@@ -29,6 +29,7 @@
#include "core/css/CSSCalculationValue.h"
#include "core/css/CSSFilterValue.h"
#include "core/css/CSSGradientValue.h"
+#include "core/css/CSSGridTemplateAreasValue.h"
#include "core/css/CSSParserMode.h"
#include "core/css/CSSParserValues.h"
#include "core/css/CSSProperty.h"
@@ -50,6 +51,7 @@
class CSSValueList;
class CSSBasicShape;
class CSSBasicShapeInset;
+class CSSGridLineNamesValue;
class Document;
class Element;
class ImmutableStylePropertySet;
@@ -137,7 +139,7 @@
PassRefPtrWillBeRawPtr<CSSValue> parseAnimationProperty(AnimationParseContext&);
PassRefPtrWillBeRawPtr<CSSValue> parseAnimationTimingFunction();
- bool parseTransformOriginShorthand(RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&);
+ bool parseWebkitTransformOriginShorthand(RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&);
bool parseCubicBezierTimingFunctionValue(CSSParserValueList*& args, double& result);
bool parseAnimationProperty(CSSPropertyID, RefPtrWillBeRawPtr<CSSValue>&, AnimationParseContext&);
bool parseTransitionShorthand(CSSPropertyID, bool important);
@@ -150,14 +152,17 @@
PassRefPtrWillBeRawPtr<CSSValue> parseGridPosition();
bool parseIntegerOrStringFromGridPosition(RefPtrWillBeRawPtr<CSSPrimitiveValue>& numericValue, RefPtrWillBeRawPtr<CSSPrimitiveValue>& gridLineName);
bool parseGridItemPositionShorthand(CSSPropertyID, bool important);
+ bool parseGridTemplateRowsAndAreas(PassRefPtrWillBeRawPtr<CSSValue>, bool important);
+ bool parseGridTemplateShorthand(bool important);
bool parseGridAreaShorthand(bool important);
bool parseSingleGridAreaLonghand(RefPtrWillBeRawPtr<CSSValue>&);
- bool parseGridTrackList(CSSPropertyID, bool important);
+ PassRefPtrWillBeRawPtr<CSSValue> parseGridTrackList(bool important);
bool parseGridTrackRepeatFunction(CSSValueList&);
PassRefPtrWillBeRawPtr<CSSValue> parseGridTrackSize(CSSParserValueList& inputList);
PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseGridBreadth(CSSParserValue*);
+ bool parseGridTemplateAreasRow(NamedGridAreaMap&, const size_t, size_t&);
PassRefPtrWillBeRawPtr<CSSValue> parseGridTemplateAreas();
- void parseGridLineNames(CSSParserValueList* inputList, CSSValueList&);
+ void parseGridLineNames(CSSParserValueList&, CSSValueList&, CSSGridLineNamesValue* = 0);
bool parseClipShape(CSSPropertyID, bool important);
@@ -237,10 +242,11 @@
static bool isBlendMode(CSSValueID);
static bool isCompositeOperator(CSSValueID);
- PassRefPtrWillBeRawPtr<CSSValueList> parseTransform();
- PassRefPtrWillBeRawPtr<CSSValue> parseTransformValue(CSSParserValue*);
- bool parseTransformOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, CSSPropertyID& propId3, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&);
- bool parsePerspectiveOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&);
+ PassRefPtrWillBeRawPtr<CSSValueList> parseTransformOrigin();
+ PassRefPtrWillBeRawPtr<CSSValueList> parseTransform(CSSPropertyID);
+ PassRefPtrWillBeRawPtr<CSSValue> parseTransformValue(CSSPropertyID, CSSParserValue*);
+ bool parseWebkitTransformOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, CSSPropertyID& propId3, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&);
+ bool parseWebkitPerspectiveOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&);
bool parseTextEmphasisStyle(bool important);
diff --git a/Source/core/css/parser/MediaQueryParser.cpp b/Source/core/css/parser/MediaQueryParser.cpp
index a4afb61..108a299 100644
--- a/Source/core/css/parser/MediaQueryParser.cpp
+++ b/Source/core/css/parser/MediaQueryParser.cpp
@@ -25,7 +25,7 @@
const MediaQueryParser::State MediaQueryParser::ReadFeatureValue = &MediaQueryParser::readFeatureValue;
const MediaQueryParser::State MediaQueryParser::ReadFeatureEnd = &MediaQueryParser::readFeatureEnd;
const MediaQueryParser::State MediaQueryParser::SkipUntilComma = &MediaQueryParser::skipUntilComma;
-const MediaQueryParser::State MediaQueryParser::SkipUntilParenthesis = &MediaQueryParser::skipUntilParenthesis;
+const MediaQueryParser::State MediaQueryParser::SkipUntilBlockEnd = &MediaQueryParser::skipUntilBlockEnd;
const MediaQueryParser::State MediaQueryParser::Done = &MediaQueryParser::done;
// FIXME: Replace the MediaQueryTokenizer with a generic CSSTokenizer, once there is one,
@@ -111,7 +111,7 @@
--token;
m_state = ReadFeatureEnd;
} else {
- m_state = SkipUntilParenthesis;
+ m_state = SkipUntilBlockEnd;
}
}
@@ -136,31 +136,69 @@
m_mediaQueryData.addParserValue(type, *token);
m_state = ReadFeatureValue;
} else {
- m_state = SkipUntilParenthesis;
+ m_state = SkipUntilBlockEnd;
}
}
void MediaQueryParser::skipUntilComma(MediaQueryTokenType type, TokenIterator& token)
{
- if (type == CommaToken || type == EOFToken) {
+ if ((type == CommaToken && m_blockStack.isEmpty()) || type == EOFToken) {
m_state = ReadRestrictor;
m_mediaQueryData.clear();
m_querySet->addMediaQuery(MediaQuery::createNotAll());
}
}
-void MediaQueryParser::skipUntilParenthesis(MediaQueryTokenType type, TokenIterator& token)
+void MediaQueryParser::skipUntilBlockEnd(MediaQueryTokenType type, TokenIterator& token)
{
- if (type == RightParenthesisToken)
+ if (m_blockStack.isEmpty())
m_state = SkipUntilComma;
}
void MediaQueryParser::done(MediaQueryTokenType type, TokenIterator& token) { }
+void MediaQueryParser::popIfBlockMatches(Vector<BlockType>& blockStack, BlockType type)
+{
+ if (!blockStack.isEmpty() && blockStack.last() == type)
+ blockStack.removeLast();
+}
+
+bool MediaQueryParser::observeBlock(BlockParameters& parameters, MediaQueryTokenType type)
+{
+ if (type == parameters.leftToken) {
+ if (parameters.stateChange == ModifyState)
+ m_state = SkipUntilBlockEnd;
+ m_blockStack.append(parameters.blockType);
+ } else if (type == parameters.rightToken) {
+ popIfBlockMatches(m_blockStack, parameters.blockType);
+ } else {
+ return false;
+ }
+ return true;
+}
+
+void MediaQueryParser::observeBlocks(MediaQueryTokenType type)
+{
+ enum { BlockParametersCount = 4 };
+ BlockParameters blockParameterSet[BlockParametersCount] = {
+ { LeftParenthesisToken, RightParenthesisToken, ParenthesisBlock, DoNotModifyState },
+ { FunctionToken, RightParenthesisToken, ParenthesisBlock, ModifyState },
+ { LeftBracketToken, RightBracketToken, BracketsBlock, ModifyState },
+ { LeftBraceToken, RightBraceToken, BracesBlock, ModifyState }
+ };
+
+ for (unsigned i = 0; i < BlockParametersCount; ++i) {
+ if (observeBlock(blockParameterSet[i], type))
+ break;
+ }
+}
+
void MediaQueryParser::processToken(TokenIterator& token)
{
MediaQueryTokenType type = token->type();
+ observeBlocks(type);
+
// Call the function that handles current state
if (type != WhitespaceToken && type != CommentToken)
((this)->*(m_state))(type, token);
diff --git a/Source/core/css/parser/MediaQueryParser.h b/Source/core/css/parser/MediaQueryParser.h
index fcb82c5..27496a7 100644
--- a/Source/core/css/parser/MediaQueryParser.h
+++ b/Source/core/css/parser/MediaQueryParser.h
@@ -58,6 +58,24 @@
typedef Vector<MediaQueryToken>::iterator TokenIterator;
+ enum BlockType {
+ ParenthesisBlock,
+ BracketsBlock,
+ BracesBlock
+ };
+
+ enum StateChange {
+ ModifyState,
+ DoNotModifyState
+ };
+
+ struct BlockParameters {
+ MediaQueryTokenType leftToken;
+ MediaQueryTokenType rightToken;
+ BlockType blockType;
+ StateChange stateChange;
+ };
+
void processToken(TokenIterator&);
void readRestrictor(MediaQueryTokenType, TokenIterator&);
@@ -69,17 +87,21 @@
void readFeatureValue(MediaQueryTokenType, TokenIterator&);
void readFeatureEnd(MediaQueryTokenType, TokenIterator&);
void skipUntilComma(MediaQueryTokenType, TokenIterator&);
- void skipUntilParenthesis(MediaQueryTokenType, TokenIterator&);
+ void skipUntilBlockEnd(MediaQueryTokenType, TokenIterator&);
void done(MediaQueryTokenType, TokenIterator&);
typedef void (MediaQueryParser::*State)(MediaQueryTokenType, TokenIterator&);
void setStateAndRestrict(State, MediaQuery::Restrictor);
+ bool observeBlock(BlockParameters&, MediaQueryTokenType);
+ void observeBlocks(MediaQueryTokenType);
+ static void popIfBlockMatches(Vector<MediaQueryParser::BlockType>& blockStack, BlockType);
State m_state;
Vector<MediaQueryToken> m_tokens;
MediaQueryData m_mediaQueryData;
RefPtrWillBeMember<MediaQuerySet> m_querySet;
+ Vector<BlockType> m_blockStack;
const static State ReadRestrictor;
const static State ReadMediaType;
@@ -90,7 +112,7 @@
const static State ReadFeatureValue;
const static State ReadFeatureEnd;
const static State SkipUntilComma;
- const static State SkipUntilParenthesis;
+ const static State SkipUntilBlockEnd;
const static State Done;
};
diff --git a/Source/core/css/parser/MediaQueryToken.h b/Source/core/css/parser/MediaQueryToken.h
index 4629ef3..156ff79 100644
--- a/Source/core/css/parser/MediaQueryToken.h
+++ b/Source/core/css/parser/MediaQueryToken.h
@@ -23,8 +23,12 @@
CommaToken = 9,
LeftParenthesisToken = 10,
RightParenthesisToken = 11,
- EOFToken = 12,
- CommentToken = 13,
+ LeftBracketToken = 12,
+ RightBracketToken = 13,
+ LeftBraceToken = 14,
+ RightBraceToken = 15,
+ EOFToken = 16,
+ CommentToken = 17,
};
enum NumericValueType {
diff --git a/Source/core/css/parser/MediaQueryTokenizer.cpp b/Source/core/css/parser/MediaQueryTokenizer.cpp
index df0ea53..4e09cc2 100644
--- a/Source/core/css/parser/MediaQueryTokenizer.cpp
+++ b/Source/core/css/parser/MediaQueryTokenizer.cpp
@@ -77,6 +77,26 @@
return MediaQueryToken(RightParenthesisToken);
}
+MediaQueryToken MediaQueryTokenizer::leftBracket(UChar cc)
+{
+ return MediaQueryToken(LeftBracketToken);
+}
+
+MediaQueryToken MediaQueryTokenizer::rightBracket(UChar cc)
+{
+ return MediaQueryToken(RightBracketToken);
+}
+
+MediaQueryToken MediaQueryTokenizer::leftBrace(UChar cc)
+{
+ return MediaQueryToken(LeftBraceToken);
+}
+
+MediaQueryToken MediaQueryTokenizer::rightBrace(UChar cc)
+{
+ return MediaQueryToken(RightBraceToken);
+}
+
MediaQueryToken MediaQueryTokenizer::plusOrFullStop(UChar cc)
{
if (nextCharsAreNumber()) {
@@ -333,20 +353,19 @@
{
// FIXME: Is this as efficient as it can be?
// The possibility of escape chars mandates a copy AFAICT.
- Vector<UChar> result;
+ StringBuilder result;
while (true) {
- if (isNameChar(m_input.currentInputChar())) {
- result.append(consume());
+ UChar cc = consume();
+ if (isNameChar(cc)) {
+ result.append(cc);
continue;
}
- if (nextTwoCharsAreValidEscape()) {
- // "consume()" fixes a spec bug.
- // The first code point should be consumed before consuming the escaped code point.
- consume();
+ if (twoCharsAreValidEscape(cc, m_input.currentInputChar())) {
result.append(consumeEscape());
continue;
}
- return String(result);
+ reconsume(cc);
+ return result.toString();
}
}
@@ -357,14 +376,15 @@
ASSERT(cc != '\n');
if (isASCIIHexDigit(cc)) {
unsigned consumedHexDigits = 1;
- String hexChars;
- do {
- hexChars.append(cc);
+ StringBuilder hexChars;
+ hexChars.append(cc);
+ while (consumedHexDigits < 6 && isASCIIHexDigit(m_input.currentInputChar())) {
cc = consume();
+ hexChars.append(cc);
consumedHexDigits++;
- } while (consumedHexDigits < 6 && isASCIIHexDigit(cc));
+ };
bool ok = false;
- UChar codePoint = hexChars.toUIntStrict(&ok, 16);
+ UChar codePoint = hexChars.toString().toUIntStrict(&ok, 16);
if (!ok)
return WTF::Unicode::replacementCharacter;
return codePoint;
@@ -376,11 +396,11 @@
return cc;
}
-bool MediaQueryTokenizer::nextTwoCharsAreValidEscape()
+bool MediaQueryTokenizer::nextTwoCharsAreValidEscape(unsigned offset)
{
- if (m_input.leftChars() < 2)
+ if (m_input.leftChars() < offset + 1)
return false;
- return twoCharsAreValidEscape(m_input.peek(1), m_input.peek(2));
+ return twoCharsAreValidEscape(m_input.peek(offset), m_input.peek(offset + 1));
}
// http://www.w3.org/TR/css3-syntax/#starts-with-a-number
@@ -401,13 +421,13 @@
bool MediaQueryTokenizer::nextCharsAreIdentifier()
{
UChar firstChar = m_input.currentInputChar();
- if (isNameStart(firstChar) || nextTwoCharsAreValidEscape())
+ if (isNameStart(firstChar) || nextTwoCharsAreValidEscape(0))
return true;
if (firstChar == '-') {
if (isNameStart(m_input.peek(1)))
return true;
- return nextTwoCharsAreValidEscape();
+ return nextTwoCharsAreValidEscape(1);
}
return false;
diff --git a/Source/core/css/parser/MediaQueryTokenizer.h b/Source/core/css/parser/MediaQueryTokenizer.h
index b31c0cb..0625d28 100644
--- a/Source/core/css/parser/MediaQueryTokenizer.h
+++ b/Source/core/css/parser/MediaQueryTokenizer.h
@@ -40,7 +40,7 @@
String consumeName();
UChar consumeEscape();
- bool nextTwoCharsAreValidEscape();
+ bool nextTwoCharsAreValidEscape(unsigned offset);
bool nextCharsAreNumber();
bool nextCharsAreIdentifier();
@@ -51,6 +51,10 @@
MediaQueryToken whiteSpace(UChar);
MediaQueryToken leftParenthesis(UChar);
MediaQueryToken rightParenthesis(UChar);
+ MediaQueryToken leftBracket(UChar);
+ MediaQueryToken rightBracket(UChar);
+ MediaQueryToken leftBrace(UChar);
+ MediaQueryToken rightBrace(UChar);
MediaQueryToken plusOrFullStop(UChar);
MediaQueryToken comma(UChar);
MediaQueryToken hyphenMinus(UChar);
diff --git a/Source/core/css/parser/MediaQueryTokenizerTest.cpp b/Source/core/css/parser/MediaQueryTokenizerTest.cpp
index ea08889..48a972b 100644
--- a/Source/core/css/parser/MediaQueryTokenizerTest.cpp
+++ b/Source/core/css/parser/MediaQueryTokenizerTest.cpp
@@ -19,6 +19,7 @@
{
TestCase testCases[] = {
{ "(max-width: 50px)", "(max-width: 50px)" },
+ { "(max-width: 50\\70\\78)", "(max-width: 50px)" },
{ "(max-width: /* comment */50px)", "(max-width: 50px)" },
{ "(max-width: /** *commen*t */60px)", "(max-width: 60px)" },
{ "(max-width: /** *commen*t **/70px)", "(max-width: 70px)" },
@@ -66,6 +67,14 @@
testToken(c, LeftParenthesisToken);
else if (c == ')')
testToken(c, RightParenthesisToken);
+ else if (c == '[')
+ testToken(c, LeftBracketToken);
+ else if (c == ']')
+ testToken(c, RightBracketToken);
+ else if (c == '{')
+ testToken(c, LeftBraceToken);
+ else if (c == '}')
+ testToken(c, RightBraceToken);
else if (c == '.' || c == '+' || c == '-' || c == '/' || c == '\\')
testToken(c, DelimiterToken);
else if (c == ',')
diff --git a/Source/core/css/resolver/AnimatedStyleBuilder.cpp b/Source/core/css/resolver/AnimatedStyleBuilder.cpp
index 22dca93..70f3200 100644
--- a/Source/core/css/resolver/AnimatedStyleBuilder.cpp
+++ b/Source/core/css/resolver/AnimatedStyleBuilder.cpp
@@ -40,6 +40,7 @@
#include "core/animation/AnimatableLengthBox.h"
#include "core/animation/AnimatableLengthBoxAndBool.h"
#include "core/animation/AnimatableLengthPoint.h"
+#include "core/animation/AnimatableLengthPoint3D.h"
#include "core/animation/AnimatableLengthSize.h"
#include "core/animation/AnimatableRepeatable.h"
#include "core/animation/AnimatableSVGLength.h"
@@ -553,13 +554,22 @@
case CSSPropertyWebkitMaskSize:
setOnFillLayers<CSSPropertyWebkitMaskSize>(style->accessMaskLayers(), value, state);
return;
- case CSSPropertyWebkitPerspective:
+ case CSSPropertyPerspective:
style->setPerspective(clampTo<float>(toAnimatableDouble(value)->toDouble()));
return;
+ case CSSPropertyPerspectiveOrigin: {
+ ASSERT(RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
+ const AnimatableLengthPoint* animatableLengthPoint = toAnimatableLengthPoint(value);
+ style->setPerspectiveOriginX(animatableValueToLength(animatableLengthPoint->x(), state));
+ style->setPerspectiveOriginY(animatableValueToLength(animatableLengthPoint->y(), state));
+ return;
+ }
case CSSPropertyWebkitPerspectiveOriginX:
+ ASSERT(!RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
style->setPerspectiveOriginX(animatableValueToLength(value, state));
return;
case CSSPropertyWebkitPerspectiveOriginY:
+ ASSERT(!RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
style->setPerspectiveOriginY(animatableValueToLength(value, state));
return;
case CSSPropertyShapeOutside:
@@ -575,19 +585,30 @@
style->setTextStrokeColor(toAnimatableColor(value)->color());
style->setVisitedLinkTextStrokeColor(toAnimatableColor(value)->visitedLinkColor());
return;
- case CSSPropertyWebkitTransform: {
+ case CSSPropertyTransform: {
const TransformOperations& operations = toAnimatableTransform(value)->transformOperations();
// FIXME: This normalization (handling of 'none') should be performed at input in AnimatableValueFactory.
style->setTransform(operations.size() ? operations : TransformOperations(true));
return;
}
+ case CSSPropertyTransformOrigin: {
+ ASSERT(RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
+ const AnimatableLengthPoint3D* animatableLengthPoint3D = toAnimatableLengthPoint3D(value);
+ style->setTransformOriginX(animatableValueToLength(animatableLengthPoint3D->x(), state));
+ style->setTransformOriginY(animatableValueToLength(animatableLengthPoint3D->y(), state));
+ style->setTransformOriginZ(clampTo<float>(toAnimatableDouble(animatableLengthPoint3D->z())->toDouble()));
+ return;
+ }
case CSSPropertyWebkitTransformOriginX:
+ ASSERT(!RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
style->setTransformOriginX(animatableValueToLength(value, state));
return;
case CSSPropertyWebkitTransformOriginY:
+ ASSERT(!RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
style->setTransformOriginY(animatableValueToLength(value, state));
return;
case CSSPropertyWebkitTransformOriginZ:
+ ASSERT(!RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
style->setTransformOriginZ(toAnimatableDouble(value)->toDouble());
return;
case CSSPropertyWidows:
diff --git a/Source/core/css/resolver/ElementResolveContext.h b/Source/core/css/resolver/ElementResolveContext.h
index 04056fe..0b3996e 100644
--- a/Source/core/css/resolver/ElementResolveContext.h
+++ b/Source/core/css/resolver/ElementResolveContext.h
@@ -34,6 +34,7 @@
// ElementResolveContext is immutable and serves as an input to the style resolve process.
class ElementResolveContext {
+ STACK_ALLOCATED();
public:
ElementResolveContext()
: m_element(0)
diff --git a/Source/core/css/resolver/SharedStyleFinder.cpp b/Source/core/css/resolver/SharedStyleFinder.cpp
index 021f0b6..16ebf2f 100644
--- a/Source/core/css/resolver/SharedStyleFinder.cpp
+++ b/Source/core/css/resolver/SharedStyleFinder.cpp
@@ -212,16 +212,8 @@
return false;
if (candidate.isLink() != element().isLink())
return false;
- if (candidate.hovered() != element().hovered())
- return false;
- if (candidate.active() != element().active())
- return false;
- if (candidate.focused() != element().focused())
- return false;
if (candidate.shadowPseudoId() != element().shadowPseudoId())
return false;
- if (candidate == document().cssTarget())
- return false;
if (!sharingCandidateHasIdenticalStyleAffectingAttributes(candidate))
return false;
if (candidate.additionalPresentationAttributeStyle() != element().additionalPresentationAttributeStyle())
diff --git a/Source/core/css/resolver/SharedStyleFinder.h b/Source/core/css/resolver/SharedStyleFinder.h
index 0c263cd..e41c3aa 100644
--- a/Source/core/css/resolver/SharedStyleFinder.h
+++ b/Source/core/css/resolver/SharedStyleFinder.h
@@ -36,6 +36,7 @@
class StyleResolver;
class SharedStyleFinder {
+ STACK_ALLOCATED();
public:
// RuleSets are passed non-const as the act of matching against them can cause them
// to be compacted. :(
@@ -72,8 +73,8 @@
bool m_elementAffectedByClassRules;
const RuleFeatureSet& m_features;
- RuleSet* m_siblingRuleSet;
- RuleSet* m_uncommonAttributeRuleSet;
+ RawPtrWillBeMember<RuleSet> m_siblingRuleSet;
+ RawPtrWillBeMember<RuleSet> m_uncommonAttributeRuleSet;
StyleResolver& m_styleResolver;
const ElementResolveContext& m_context;
};
diff --git a/Source/core/css/resolver/StyleAdjuster.cpp b/Source/core/css/resolver/StyleAdjuster.cpp
index 624d735..af6781c 100644
--- a/Source/core/css/resolver/StyleAdjuster.cpp
+++ b/Source/core/css/resolver/StyleAdjuster.cpp
@@ -34,6 +34,7 @@
#include "core/dom/ContainerNode.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
+#include "core/dom/NodeRenderStyle.h"
#include "core/html/HTMLIFrameElement.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/HTMLTableCellElement.h"
@@ -166,9 +167,11 @@
for (size_t i = 0; i < style->willChangeProperties().size(); ++i) {
switch (style->willChangeProperties()[i]) {
case CSSPropertyOpacity:
+ case CSSPropertyTransform:
case CSSPropertyWebkitTransform:
case CSSPropertyTransformStyle:
case CSSPropertyWebkitTransformStyle:
+ case CSSPropertyPerspective:
case CSSPropertyWebkitPerspective:
case CSSPropertyWebkitMask:
case CSSPropertyWebkitMaskBoxImage:
@@ -236,7 +239,7 @@
// will-change:transform should result in the same rendering behavior as having a transform,
// including the creation of a containing block for fixed position descendants.
- if (!style->hasTransform() && style->willChangeProperties().contains(CSSPropertyWebkitTransform)) {
+ if (!style->hasTransform() && (style->willChangeProperties().contains(CSSPropertyWebkitTransform) || style->willChangeProperties().contains(CSSPropertyTransform))) {
bool makeIdentity = true;
style->setTransform(TransformOperations(makeIdentity));
}
@@ -281,6 +284,13 @@
if ((isSVGForeignObjectElement(*e) || isSVGTextElement(*e)) && style->isDisplayInlineType())
style->setDisplay(BLOCK);
}
+
+ if (e && e->renderStyle() && e->renderStyle()->textAutosizingMultiplier() != 1) {
+ // Preserve the text autosizing multiplier on style recalc.
+ // (The autosizer will update it during layout if it needs to be changed.)
+ style->setTextAutosizingMultiplier(e->renderStyle()->textAutosizingMultiplier());
+ style->setUnique();
+ }
}
void StyleAdjuster::adjustStyleForTagName(RenderStyle* style, RenderStyle* parentStyle, Element& element)
diff --git a/Source/core/css/resolver/StyleBuilderCustom.cpp b/Source/core/css/resolver/StyleBuilderCustom.cpp
index 6e0ba84..25509fd 100644
--- a/Source/core/css/resolver/StyleBuilderCustom.cpp
+++ b/Source/core/css/resolver/StyleBuilderCustom.cpp
@@ -582,6 +582,121 @@
state.style()->setTextIndentLine(TextIndentFirstLine);
}
+void StyleBuilderFunctions::applyInitialCSSPropertyTransformOrigin(StyleResolverState& state)
+{
+ applyInitialCSSPropertyWebkitTransformOriginX(state);
+ applyInitialCSSPropertyWebkitTransformOriginY(state);
+ applyInitialCSSPropertyWebkitTransformOriginZ(state);
+}
+
+void StyleBuilderFunctions::applyInheritCSSPropertyTransformOrigin(StyleResolverState& state)
+{
+ applyInheritCSSPropertyWebkitTransformOriginX(state);
+ applyInheritCSSPropertyWebkitTransformOriginY(state);
+ applyInheritCSSPropertyWebkitTransformOriginZ(state);
+}
+
+void StyleBuilderFunctions::applyValueCSSPropertyTransformOrigin(StyleResolverState& state, CSSValue* value)
+{
+ CSSValueList* list = toCSSValueList(value);
+ ASSERT(list->length() == 3);
+ CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(list->item(0));
+ if (primitiveValue->isValueID()) {
+ switch (primitiveValue->getValueID()) {
+ case CSSValueLeft:
+ state.style()->setTransformOriginX(Length(0, Percent));
+ break;
+ case CSSValueRight:
+ state.style()->setTransformOriginX(Length(100, Percent));
+ break;
+ case CSSValueCenter:
+ state.style()->setTransformOriginX(Length(50, Percent));
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ } else {
+ state.style()->setTransformOriginX(StyleBuilderConverter::convertLength(state, primitiveValue));
+ }
+
+ primitiveValue = toCSSPrimitiveValue(list->item(1));
+ if (primitiveValue->isValueID()) {
+ switch (primitiveValue->getValueID()) {
+ case CSSValueTop:
+ state.style()->setTransformOriginY(Length(0, Percent));
+ break;
+ case CSSValueBottom:
+ state.style()->setTransformOriginY(Length(100, Percent));
+ break;
+ case CSSValueCenter:
+ state.style()->setTransformOriginY(Length(50, Percent));
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ } else {
+ state.style()->setTransformOriginY(StyleBuilderConverter::convertLength(state, primitiveValue));
+ }
+
+ primitiveValue = toCSSPrimitiveValue(list->item(2));
+ state.style()->setTransformOriginZ(StyleBuilderConverter::convertComputedLength<float>(state, primitiveValue));
+}
+
+void StyleBuilderFunctions::applyInitialCSSPropertyPerspectiveOrigin(StyleResolverState& state)
+{
+ applyInitialCSSPropertyWebkitPerspectiveOriginX(state);
+ applyInitialCSSPropertyWebkitPerspectiveOriginY(state);
+}
+
+void StyleBuilderFunctions::applyInheritCSSPropertyPerspectiveOrigin(StyleResolverState& state)
+{
+ applyInheritCSSPropertyWebkitPerspectiveOriginX(state);
+ applyInheritCSSPropertyWebkitPerspectiveOriginY(state);
+}
+
+void StyleBuilderFunctions::applyValueCSSPropertyPerspectiveOrigin(StyleResolverState& state, CSSValue* value)
+{
+ CSSValueList* list = toCSSValueList(value);
+ ASSERT(list->length() == 2);
+ CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(list->item(0));
+ if (primitiveValue->isValueID()) {
+ switch (primitiveValue->getValueID()) {
+ case CSSValueLeft:
+ state.style()->setPerspectiveOriginX(Length(0, Percent));
+ break;
+ case CSSValueRight:
+ state.style()->setPerspectiveOriginX(Length(100, Percent));
+ break;
+ case CSSValueCenter:
+ state.style()->setPerspectiveOriginX(Length(50, Percent));
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ } else {
+ state.style()->setPerspectiveOriginX(StyleBuilderConverter::convertLength(state, primitiveValue));
+ }
+
+ primitiveValue = toCSSPrimitiveValue(list->item(1));
+ if (primitiveValue->isValueID()) {
+ switch (primitiveValue->getValueID()) {
+ case CSSValueTop:
+ state.style()->setPerspectiveOriginY(Length(0, Percent));
+ break;
+ case CSSValueBottom:
+ state.style()->setPerspectiveOriginY(Length(100, Percent));
+ break;
+ case CSSValueCenter:
+ state.style()->setPerspectiveOriginY(Length(50, Percent));
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ } else {
+ state.style()->setPerspectiveOriginY(StyleBuilderConverter::convertLength(state, primitiveValue));
+ }
+}
+
void StyleBuilderFunctions::applyValueCSSPropertyVerticalAlign(StyleResolverState& state, CSSValue* value)
{
if (!value->isPrimitiveValue())
@@ -1339,6 +1454,7 @@
case CSSPropertyWebkitColumnRule:
case CSSPropertyFlex:
case CSSPropertyFlexFlow:
+ case CSSPropertyGridTemplate:
case CSSPropertyGridColumn:
case CSSPropertyGridRow:
case CSSPropertyGridArea:
@@ -1422,6 +1538,7 @@
state.style()->setTextStrokeWidth(width);
return;
}
+ case CSSPropertyTransform:
case CSSPropertyWebkitTransform: {
HANDLE_INHERIT_AND_INITIAL(transform, Transform);
TransformOperations operations;
@@ -1429,6 +1546,7 @@
state.style()->setTransform(operations);
return;
}
+ case CSSPropertyPerspective:
case CSSPropertyWebkitPerspective: {
HANDLE_INHERIT_AND_INITIAL(perspective, Perspective)
@@ -1443,8 +1561,8 @@
float perspectiveValue;
if (primitiveValue->isLength()) {
perspectiveValue = primitiveValue->computeLength<float>(state.cssToLengthConversionData());
- } else if (primitiveValue->isNumber()) {
- // For backward compatibility, treat valueless numbers as px.
+ } else if (id == CSSPropertyWebkitPerspective && primitiveValue->isNumber()) {
+ // Prefixed version treats unitless numbers as px.
perspectiveValue = CSSPrimitiveValue::create(primitiveValue->getDoubleValue(), CSSPrimitiveValue::CSS_PX)->computeLength<float>(state.cssToLengthConversionData());
} else {
return;
@@ -1740,12 +1858,6 @@
return;
}
- // FIXME: crbug.com/154772 Unimplemented css-transforms properties
- case CSSPropertyPerspective:
- case CSSPropertyPerspectiveOrigin:
- case CSSPropertyTransform:
- case CSSPropertyTransformOrigin:
- return;
// These properties are aliased and we already applied the property on the prefixed version.
case CSSPropertyAnimationDelay:
case CSSPropertyAnimationDirection:
@@ -1950,6 +2062,7 @@
case CSSPropertyWebkitMaskRepeatX:
case CSSPropertyWebkitMaskRepeatY:
case CSSPropertyWebkitMaskSize:
+ case CSSPropertyPerspectiveOrigin:
case CSSPropertyWebkitPerspectiveOrigin:
case CSSPropertyWebkitPerspectiveOriginX:
case CSSPropertyWebkitPerspectiveOriginY:
@@ -1967,6 +2080,7 @@
case CSSPropertyWebkitTransformOriginX:
case CSSPropertyWebkitTransformOriginY:
case CSSPropertyWebkitTransformOriginZ:
+ case CSSPropertyTransformOrigin:
case CSSPropertyTransformStyle:
case CSSPropertyWebkitTransformStyle:
case CSSPropertyWebkitTransitionDelay:
@@ -1979,7 +2093,6 @@
case CSSPropertyWebkitClipPath:
case CSSPropertyWebkitWrapFlow:
case CSSPropertyShapeMargin:
- case CSSPropertyShapePadding:
case CSSPropertyShapeImageThreshold:
case CSSPropertyWebkitWrapThrough:
case CSSPropertyShapeOutside:
diff --git a/Source/core/css/resolver/StyleResolver.cpp b/Source/core/css/resolver/StyleResolver.cpp
index 0d1fee7..4094b23 100644
--- a/Source/core/css/resolver/StyleResolver.cpp
+++ b/Source/core/css/resolver/StyleResolver.cpp
@@ -1084,7 +1084,7 @@
// the style to impose the stacking rules. Note that this is also
// done in StyleResolver::adjustRenderStyle().
RenderStyle* style = state.style();
- if (style->hasAutoZIndex() && (style->opacity() < 1.0f || style->hasTransform()))
+ if (style->hasAutoZIndex() && (style->opacity() < 1.0f || style->hasTransformRelatedProperty()))
style->setZIndex(0);
// Start loading resources used by animations.
diff --git a/Source/core/css/resolver/ViewportStyleResolver.cpp b/Source/core/css/resolver/ViewportStyleResolver.cpp
index 2a5d3f1..84b1c11 100644
--- a/Source/core/css/resolver/ViewportStyleResolver.cpp
+++ b/Source/core/css/resolver/ViewportStyleResolver.cpp
@@ -45,8 +45,8 @@
DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(ViewportStyleResolver);
ViewportStyleResolver::ViewportStyleResolver(Document* document)
- : m_document(document),
- m_hasAuthorStyle(false)
+ : m_document(document)
+ , m_hasAuthorStyle(false)
{
ASSERT(m_document);
}
@@ -87,10 +87,8 @@
if (!m_document)
return;
- if (!m_propertySet || (!m_hasAuthorStyle && m_document->hasLegacyViewportTag())) {
- ASSERT(!m_hasAuthorStyle);
- m_propertySet = nullptr;
- m_document->setViewportDescription(ViewportDescription());
+ if (!m_propertySet) {
+ m_document->setViewportDescription(ViewportDescription(ViewportDescription::UserAgentStyleSheet));
return;
}