diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-06-01 10:36:58 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-06-01 10:36:58 +0200 |
commit | b1e9e47fa11f608ae16bc07f97a2acf95bf80272 (patch) | |
tree | c88c45e80c9c44506e7cdf9a3bb39ebf82a8cd5b /Source/WebCore/css | |
parent | be01689f43cf6882cf670d33df49ead1f570c53a (diff) | |
download | qtwebkit-b1e9e47fa11f608ae16bc07f97a2acf95bf80272.tar.gz |
Imported WebKit commit 499c84c99aa98e9870fa7eaa57db476c6d160d46 (http://svn.webkit.org/repository/webkit/trunk@119200)
Weekly update :). Particularly relevant changes for Qt are the use of the WebCore image decoders and direct usage
of libpng/libjpeg if available in the system.
Diffstat (limited to 'Source/WebCore/css')
37 files changed, 543 insertions, 289 deletions
diff --git a/Source/WebCore/css/CSSCalculationValue.cpp b/Source/WebCore/css/CSSCalculationValue.cpp index 618c39c12..54247e035 100755 --- a/Source/WebCore/css/CSSCalculationValue.cpp +++ b/Source/WebCore/css/CSSCalculationValue.cpp @@ -74,7 +74,17 @@ static CalculationCategory unitCategory(CSSPrimitiveValue::UnitTypes type) String CSSCalcValue::customCssText() const { - return ""; + StringBuilder result; + + result.append("-webkit-calc"); + String expression = m_expression->customCssText(); + bool expressionHasSingleTerm = expression[0] != '('; + if (expressionHasSingleTerm) + result.append('('); + result.append(expression); + if (expressionHasSingleTerm) + result.append(')'); + return result.toString(); } double CSSCalcValue::clampToPermittedRange(double value) const @@ -109,7 +119,7 @@ public: return !m_value->getDoubleValue(); } - virtual String cssText() const + virtual String customCssText() const { return m_value->cssText(); } @@ -250,6 +260,20 @@ public: return evaluate(leftValue, rightValue); } + virtual String customCssText() const + { + StringBuilder result; + result.append('('); + result.append(m_leftSide->customCssText()); + result.append(' '); + result.append(static_cast<char>(m_operator)); + result.append(' '); + result.append(m_rightSide->customCssText()); + result.append(')'); + + return result.toString(); + } + private: CSSCalcBinaryOperation(PassRefPtr<CSSCalcExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide, CalcOperator op, CalculationCategory category) : CSSCalcExpressionNode(category, leftSide->isInteger() && rightSide->isInteger()) diff --git a/Source/WebCore/css/CSSCalculationValue.h b/Source/WebCore/css/CSSCalculationValue.h index ac9be46d3..57a249f89 100755 --- a/Source/WebCore/css/CSSCalculationValue.h +++ b/Source/WebCore/css/CSSCalculationValue.h @@ -63,6 +63,7 @@ public: virtual PassOwnPtr<CalcExpressionNode> toCalcValue(RenderStyle*, RenderStyle* rootStyle, double zoom = 1.0) const = 0; virtual double doubleValue() const = 0; virtual double computeLengthPx(RenderStyle* currentStyle, RenderStyle* rootStyle, double multiplier = 1.0, bool computingFontSize = false) const = 0; + virtual String customCssText() const = 0; CalculationCategory category() const { return m_category; } bool isInteger() const { return m_isInteger; } diff --git a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp index 596fa7cde..589cc2f35 100644 --- a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp +++ b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp @@ -199,6 +199,7 @@ static const CSSPropertyID computedProperties[] = { CSSPropertyWebkitBorderImage, CSSPropertyWebkitBorderVerticalSpacing, CSSPropertyWebkitBoxAlign, + CSSPropertyWebkitBoxDecorationBreak, CSSPropertyWebkitBoxDirection, CSSPropertyWebkitBoxFlex, CSSPropertyWebkitBoxFlexGroup, @@ -227,11 +228,11 @@ static const CSSPropertyID computedProperties[] = { CSSPropertyWebkitFilter, #endif #if ENABLE(CSS3_FLEXBOX) + CSSPropertyWebkitAlignItems, + CSSPropertyWebkitAlignSelf, CSSPropertyWebkitFlex, CSSPropertyWebkitFlexOrder, CSSPropertyWebkitFlexPack, - CSSPropertyWebkitFlexAlign, - CSSPropertyWebkitFlexItemAlign, CSSPropertyWebkitFlexDirection, CSSPropertyWebkitFlexFlow, CSSPropertyWebkitFlexLinePack, @@ -1540,6 +1541,10 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert return getPositionOffsetValue(style.get(), CSSPropertyBottom, m_node->document()->renderView()); case CSSPropertyWebkitBoxAlign: return cssValuePool().createValue(style->boxAlign()); + case CSSPropertyWebkitBoxDecorationBreak: + if (style->boxDecorationBreak() == DSLICE) + return cssValuePool().createIdentifierValue(CSSValueSlice); + return cssValuePool().createIdentifierValue(CSSValueClone); case CSSPropertyWebkitBoxDirection: return cssValuePool().createValue(style->boxDirection()); case CSSPropertyWebkitBoxFlex: @@ -1649,15 +1654,15 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert return cssValuePool().createValue(style->flexOrder(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitFlexPack: return cssValuePool().createValue(style->flexPack()); - case CSSPropertyWebkitFlexAlign: - return cssValuePool().createValue(style->flexAlign()); - case CSSPropertyWebkitFlexItemAlign: - if (style->flexItemAlign() == AlignAuto) { + case CSSPropertyWebkitAlignItems: + return cssValuePool().createValue(style->alignItems()); + case CSSPropertyWebkitAlignSelf: + if (style->alignSelf() == AlignAuto) { if (m_node && m_node->parentNode() && m_node->parentNode()->computedStyle()) - return cssValuePool().createValue(m_node->parentNode()->computedStyle()->flexAlign()); + return cssValuePool().createValue(m_node->parentNode()->computedStyle()->alignItems()); return cssValuePool().createValue(AlignStretch); } - return cssValuePool().createValue(style->flexItemAlign()); + return cssValuePool().createValue(style->alignSelf()); case CSSPropertyWebkitFlexDirection: return cssValuePool().createValue(style->flexDirection()); case CSSPropertyWebkitFlexWrap: @@ -2634,14 +2639,14 @@ PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getCSSPropertyValuesForSid PassRefPtr<StylePropertySet> CSSComputedStyleDeclaration::copyPropertiesInSet(const CSSPropertyID* set, unsigned length) const { - StylePropertyVector list; + Vector<CSSProperty, 256> list; list.reserveInitialCapacity(length); for (unsigned i = 0; i < length; ++i) { RefPtr<CSSValue> value = getPropertyCSSValue(set[i]); if (value) list.append(CSSProperty(set[i], value.release(), false)); } - return StylePropertySet::adopt(list); + return StylePropertySet::create(list.data(), list.size()); } CSSRule* CSSComputedStyleDeclaration::parentRule() const diff --git a/Source/WebCore/css/CSSFontFaceRule.cpp b/Source/WebCore/css/CSSFontFaceRule.cpp index 8bb94db63..bcc8639ed 100644 --- a/Source/WebCore/css/CSSFontFaceRule.cpp +++ b/Source/WebCore/css/CSSFontFaceRule.cpp @@ -42,7 +42,7 @@ CSSFontFaceRule::~CSSFontFaceRule() CSSStyleDeclaration* CSSFontFaceRule::style() const { if (!m_propertiesCSSOMWrapper) - m_propertiesCSSOMWrapper = StyleRuleCSSStyleDeclaration::create(m_fontFaceRule->properties(), const_cast<CSSFontFaceRule*>(this)); + m_propertiesCSSOMWrapper = StyleRuleCSSStyleDeclaration::create(m_fontFaceRule->mutableProperties(), const_cast<CSSFontFaceRule*>(this)); return m_propertiesCSSOMWrapper.get(); } @@ -60,7 +60,7 @@ void CSSFontFaceRule::reattach(StyleRuleFontFace* rule) ASSERT(rule); m_fontFaceRule = rule; if (m_propertiesCSSOMWrapper) - m_propertiesCSSOMWrapper->reattach(m_fontFaceRule->properties()); + m_propertiesCSSOMWrapper->reattach(m_fontFaceRule->mutableProperties()); } } // namespace WebCore diff --git a/Source/WebCore/css/CSSFontFaceSrcValue.cpp b/Source/WebCore/css/CSSFontFaceSrcValue.cpp index 08518a763..79ae0e741 100644 --- a/Source/WebCore/css/CSSFontFaceSrcValue.cpp +++ b/Source/WebCore/css/CSSFontFaceSrcValue.cpp @@ -73,7 +73,7 @@ String CSSFontFaceSrcValue::customCssText() const return result; } -void CSSFontFaceSrcValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const StyleSheetContents* styleSheet) +void CSSFontFaceSrcValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const StyleSheetContents* styleSheet) const { if (!isLocal()) addSubresourceURL(urls, styleSheet->completeURL(m_resource)); diff --git a/Source/WebCore/css/CSSFontFaceSrcValue.h b/Source/WebCore/css/CSSFontFaceSrcValue.h index a529c1644..94607fed0 100644 --- a/Source/WebCore/css/CSSFontFaceSrcValue.h +++ b/Source/WebCore/css/CSSFontFaceSrcValue.h @@ -65,7 +65,7 @@ public: String customCssText() const; - void addSubresourceStyleURLs(ListHashSet<KURL>&, const StyleSheetContents*); + void addSubresourceStyleURLs(ListHashSet<KURL>&, const StyleSheetContents*) const; CachedFont* cachedFont(Document*); diff --git a/Source/WebCore/css/CSSGrammar.y b/Source/WebCore/css/CSSGrammar.y index b6168858e..9eddc17a1 100644 --- a/Source/WebCore/css/CSSGrammar.y +++ b/Source/WebCore/css/CSSGrammar.y @@ -954,14 +954,9 @@ simple_selector: static_cast<CSSParser*>(parser)->updateSpecifiersWithElementName(nullAtom, starAtom, $$); } | namespace_selector element_name { - AtomicString namespacePrefix = $1; CSSParser* p = static_cast<CSSParser*>(parser); $$ = p->createFloatingSelector(); - if (p->m_styleSheet) - $$->setTag(QualifiedName(namespacePrefix, $2, - p->m_styleSheet->determineNamespace(namespacePrefix))); - else // FIXME: Shouldn't this case be an error? - $$->setTag(QualifiedName(nullAtom, $2, p->m_defaultNamespace)); + $$->setTag(p->determineNameInNamespace($1, $2)); } | namespace_selector element_name specifier_list { $$ = $3; @@ -1087,19 +1082,15 @@ attrib: $$->setValue($6); } | '[' maybe_space namespace_selector attr_name ']' { - AtomicString namespacePrefix = $3; CSSParser* p = static_cast<CSSParser*>(parser); $$ = p->createFloatingSelector(); - $$->setAttribute(QualifiedName(namespacePrefix, $4, - p->m_styleSheet->determineNamespace(namespacePrefix))); + $$->setAttribute(p->determineNameInNamespace($3, $4)); $$->setMatch(CSSSelector::Set); } | '[' maybe_space namespace_selector attr_name match maybe_space ident_or_string maybe_space ']' { - AtomicString namespacePrefix = $3; CSSParser* p = static_cast<CSSParser*>(parser); $$ = p->createFloatingSelector(); - $$->setAttribute(QualifiedName(namespacePrefix, $4, - p->m_styleSheet->determineNamespace(namespacePrefix))); + $$->setAttribute(p->determineNameInNamespace($3, $4)); $$->setMatch((CSSSelector::Match)$5); $$->setValue($7); } diff --git a/Source/WebCore/css/CSSPageRule.cpp b/Source/WebCore/css/CSSPageRule.cpp index 70bbab7ba..42859aa2a 100644 --- a/Source/WebCore/css/CSSPageRule.cpp +++ b/Source/WebCore/css/CSSPageRule.cpp @@ -48,7 +48,7 @@ CSSPageRule::~CSSPageRule() CSSStyleDeclaration* CSSPageRule::style() const { if (!m_propertiesCSSOMWrapper) - m_propertiesCSSOMWrapper = StyleRuleCSSStyleDeclaration::create(m_pageRule->properties(), const_cast<CSSPageRule*>(this)); + m_propertiesCSSOMWrapper = StyleRuleCSSStyleDeclaration::create(m_pageRule->mutableProperties(), const_cast<CSSPageRule*>(this)); return m_propertiesCSSOMWrapper.get(); } @@ -92,7 +92,7 @@ void CSSPageRule::reattach(StyleRulePage* rule) ASSERT(rule); m_pageRule = rule; if (m_propertiesCSSOMWrapper) - m_propertiesCSSOMWrapper->reattach(m_pageRule->properties()); + m_propertiesCSSOMWrapper->reattach(m_pageRule->mutableProperties()); } } // namespace WebCore diff --git a/Source/WebCore/css/CSSParser.cpp b/Source/WebCore/css/CSSParser.cpp index 725bc245e..695dee916 100644 --- a/Source/WebCore/css/CSSParser.cpp +++ b/Source/WebCore/css/CSSParser.cpp @@ -664,6 +664,10 @@ static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int if (valueID == CSSValueStretch || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline) return true; break; + case CSSPropertyWebkitBoxDecorationBreak: + if (valueID == CSSValueClone || valueID == CSSValueSlice) + return true; + break; case CSSPropertyWebkitBoxDirection: if (valueID == CSSValueNormal || valueID == CSSValueReverse) return true; @@ -685,24 +689,24 @@ static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int return true; break; #if ENABLE(CSS3_FLEXBOX) - case CSSPropertyWebkitFlexAlign: + case CSSPropertyWebkitAlignItems: if (valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline || valueID == CSSValueStretch) return true; break; + case CSSPropertyWebkitAlignSelf: + if (valueID == CSSValueAuto || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline || valueID == CSSValueStretch) + return true; + break; case CSSPropertyWebkitFlexDirection: if (valueID == CSSValueRow || valueID == CSSValueRowReverse || valueID == CSSValueColumn || valueID == CSSValueColumnReverse) return true; break; - case CSSPropertyWebkitFlexItemAlign: - if (valueID == CSSValueAuto || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline || valueID == CSSValueStretch) - return true; - break; case CSSPropertyWebkitFlexLinePack: - if (valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueJustify || valueID == CSSValueDistribute || valueID == CSSValueStretch) + if (valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueSpaceBetween || valueID == CSSValueSpaceAround || valueID == CSSValueStretch) return true; break; case CSSPropertyWebkitFlexPack: - if (valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueJustify || valueID == CSSValueDistribute) + if (valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueSpaceBetween || valueID == CSSValueSpaceAround) return true; break; case CSSPropertyWebkitFlexWrap: @@ -905,6 +909,7 @@ static inline bool isKeywordPropertyID(CSSPropertyID propertyId) case CSSPropertyWebkitBorderFit: case CSSPropertyWebkitBorderStartStyle: case CSSPropertyWebkitBoxAlign: + case CSSPropertyWebkitBoxDecorationBreak: case CSSPropertyWebkitBoxDirection: case CSSPropertyWebkitBoxLines: case CSSPropertyWebkitBoxOrient: @@ -915,9 +920,9 @@ static inline bool isKeywordPropertyID(CSSPropertyID propertyId) case CSSPropertyWebkitColumnBreakInside: case CSSPropertyWebkitColumnRuleStyle: #if ENABLE(CSS3_FLEXBOX) - case CSSPropertyWebkitFlexAlign: + case CSSPropertyWebkitAlignItems: + case CSSPropertyWebkitAlignSelf: case CSSPropertyWebkitFlexDirection: - case CSSPropertyWebkitFlexItemAlign: case CSSPropertyWebkitFlexLinePack: case CSSPropertyWebkitFlexPack: case CSSPropertyWebkitFlexWrap: @@ -1105,8 +1110,6 @@ bool CSSParser::parseSystemColor(RGBA32& color, const String& string, Document* void CSSParser::parseSelector(const String& string, CSSSelectorList& selectorList) { - RefPtr<StyleSheetContents> dummyStyleSheet = StyleSheetContents::create(); - setStyleSheet(dummyStyleSheet.get()); m_selectorListForParseSelector = &selectorList; setupParser("@-webkit-selector{", string, "}"); @@ -1114,9 +1117,6 @@ void CSSParser::parseSelector(const String& string, CSSSelectorList& selectorLis cssyyparse(this); m_selectorListForParseSelector = 0; - - // The style sheet will be deleted right away, so it won't outlive the document. - ASSERT(dummyStyleSheet->hasOneRef()); } bool CSSParser::parseDeclaration(StylePropertySet* declaration, const String& string, RefPtr<CSSStyleSourceData>* styleSourceData, StyleSheetContents* contextStyleSheet) @@ -1177,40 +1177,35 @@ PassOwnPtr<MediaQuery> CSSParser::parseMediaQuery(const String& string) return m_mediaQuery.release(); } -PassRefPtr<StylePropertySet> CSSParser::createStylePropertySet() +static inline void filterProperties(bool important, const CSSParser::ParsedPropertyVector& input, Vector<CSSProperty, 256>& output, size_t& unusedEntries, BitArray<numCSSProperties>& seenProperties) { - BitArray<numCSSProperties> seenProperties; - BitArray<numCSSProperties> seenImportantProperties; - - StylePropertyVector results; - results.reserveInitialCapacity(m_parsedProperties.size()); - - for (unsigned i = 0; i < m_parsedProperties.size(); ++i) { - const CSSProperty& property = m_parsedProperties[i]; + // Add properties in reverse order so that highest priority definitions are reached first. Duplicate definitions can then be ignored when found. + for (int i = input.size() - 1; i >= 0; --i) { + const CSSProperty& property = input[i]; + if (property.isImportant() != important) + continue; const unsigned propertyIDIndex = property.id() - firstCSSProperty; - - // Ignore non-important properties if we already have an important property with the same ID. - if (!property.isImportant() && seenImportantProperties.get(propertyIDIndex)) + if (seenProperties.get(propertyIDIndex)) continue; + seenProperties.set(propertyIDIndex); + output[--unusedEntries] = property; + } +} - // If we already had this property, this new one takes precedence, so wipe out the old one. - if (seenProperties.get(propertyIDIndex)) { - for (unsigned i = 0; i < results.size(); ++i) { - if (results[i].id() == property.id()) { - results.remove(i); - break; - } - } - } +PassRefPtr<StylePropertySet> CSSParser::createStylePropertySet() +{ + BitArray<numCSSProperties> seenProperties; + size_t unusedEntries = m_parsedProperties.size(); + Vector<CSSProperty, 256> results(unusedEntries); - if (property.isImportant()) - seenImportantProperties.set(propertyIDIndex); - seenProperties.set(propertyIDIndex); + // Important properties have higher priority, so add them first. Duplicate definitions can then be ignored when found. + filterProperties(true, m_parsedProperties, results, unusedEntries, seenProperties); + filterProperties(false, m_parsedProperties, results, unusedEntries, seenProperties); - results.uncheckedAppend(property); - } + if (unusedEntries) + results.remove(0, unusedEntries); - return StylePropertySet::adopt(results, m_context.mode); + return StylePropertySet::createImmutable(results.data(), results.size(), m_context.mode); } void CSSParser::addProperty(CSSPropertyID propId, PassRefPtr<CSSValue> value, bool important, bool implicit) @@ -2548,6 +2543,7 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) case CSSPropertyWebkitBorderFit: case CSSPropertyWebkitBorderStartStyle: case CSSPropertyWebkitBoxAlign: + case CSSPropertyWebkitBoxDecorationBreak: case CSSPropertyWebkitBoxDirection: case CSSPropertyWebkitBoxLines: case CSSPropertyWebkitBoxOrient: @@ -2558,9 +2554,9 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) case CSSPropertyWebkitColumnBreakInside: case CSSPropertyWebkitColumnRuleStyle: #if ENABLE(CSS3_FLEXBOX) - case CSSPropertyWebkitFlexAlign: + case CSSPropertyWebkitAlignItems: + case CSSPropertyWebkitAlignSelf: case CSSPropertyWebkitFlexDirection: - case CSSPropertyWebkitFlexItemAlign: case CSSPropertyWebkitFlexLinePack: case CSSPropertyWebkitFlexPack: case CSSPropertyWebkitFlexWrap: @@ -5601,7 +5597,7 @@ PassRefPtr<CSSValue> CSSParser::parseFlex(CSSParserValueList* args) if (positiveFlex == unsetValue) positiveFlex = 1; if (negativeFlex == unsetValue) - negativeFlex = 0; + negativeFlex = positiveFlex ? 1 : 0; if (!preferredSize) preferredSize = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PX); @@ -7369,9 +7365,6 @@ bool CSSParser::cssGridLayoutEnabled() const #if ENABLE(CSS_REGIONS) bool CSSParser::parseFlowThread(const String& flowName) { - RefPtr<StyleSheetContents> dummyStyleSheet = StyleSheetContents::create(); - setStyleSheet(dummyStyleSheet.get()); - setupParser("@-webkit-decls{-webkit-flow-into:", flowName, "}"); cssyyparse(this); @@ -9200,6 +9193,13 @@ void CSSParser::addNamespace(const AtomicString& prefix, const AtomicString& uri m_defaultNamespace = uri; } +QualifiedName CSSParser::determineNameInNamespace(const AtomicString& prefix, const AtomicString& localName) +{ + if (!m_styleSheet) + return QualifiedName(prefix, localName, m_defaultNamespace); + return QualifiedName(prefix, localName, m_styleSheet->determineNamespace(prefix)); +} + void CSSParser::updateSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector* specifiers) { AtomicString determinedNamespace = namespacePrefix != nullAtom && m_styleSheet ? m_styleSheet->determineNamespace(namespacePrefix) : m_defaultNamespace; diff --git a/Source/WebCore/css/CSSParser.h b/Source/WebCore/css/CSSParser.h index f52394413..7c5a62377 100644 --- a/Source/WebCore/css/CSSParser.h +++ b/Source/WebCore/css/CSSParser.h @@ -267,6 +267,7 @@ public: PassOwnPtr<MediaQuery> sinkFloatingMediaQuery(MediaQuery*); void addNamespace(const AtomicString& prefix, const AtomicString& uri); + QualifiedName determineNameInNamespace(const AtomicString& prefix, const AtomicString& localName); void updateSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector*); CSSParserSelector* updateSpecifiers(CSSParserSelector*, CSSParserSelector*); @@ -293,7 +294,8 @@ public: RefPtr<StyleKeyframe> m_keyframe; OwnPtr<MediaQuery> m_mediaQuery; OwnPtr<CSSParserValueList> m_valueList; - Vector<CSSProperty, 256> m_parsedProperties; + typedef Vector<CSSProperty, 256> ParsedPropertyVector; + ParsedPropertyVector m_parsedProperties; CSSSelectorList* m_selectorListForParseSelector; unsigned m_numParsedPropertiesBeforeMarginBox; diff --git a/Source/WebCore/css/CSSPrimitiveValue.cpp b/Source/WebCore/css/CSSPrimitiveValue.cpp index 0bf66ad96..592494a0e 100644 --- a/Source/WebCore/css/CSSPrimitiveValue.cpp +++ b/Source/WebCore/css/CSSPrimitiveValue.cpp @@ -1064,7 +1064,7 @@ String CSSPrimitiveValue::customCssText() const return text; } -void CSSPrimitiveValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const StyleSheetContents* styleSheet) +void CSSPrimitiveValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const StyleSheetContents* styleSheet) const { if (m_primitiveUnitType == CSS_URI) addSubresourceURL(urls, styleSheet->completeURL(m_value.string)); diff --git a/Source/WebCore/css/CSSPrimitiveValue.h b/Source/WebCore/css/CSSPrimitiveValue.h index a8a0bbcd9..ccd187be7 100644 --- a/Source/WebCore/css/CSSPrimitiveValue.h +++ b/Source/WebCore/css/CSSPrimitiveValue.h @@ -283,7 +283,7 @@ public: bool isQuirkValue() { return m_isQuirkValue; } - void addSubresourceStyleURLs(ListHashSet<KURL>&, const StyleSheetContents*); + void addSubresourceStyleURLs(ListHashSet<KURL>&, const StyleSheetContents*) const; Length viewportPercentageLength(); diff --git a/Source/WebCore/css/CSSPrimitiveValueMappings.h b/Source/WebCore/css/CSSPrimitiveValueMappings.h index 24a7d445c..f206b3f35 100644 --- a/Source/WebCore/css/CSSPrimitiveValueMappings.h +++ b/Source/WebCore/css/CSSPrimitiveValueMappings.h @@ -743,6 +743,33 @@ template<> inline CSSPrimitiveValue::operator EBoxAlignment() const } } +template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EBoxDecorationBreak e) + : CSSValue(PrimitiveClass) +{ + m_primitiveUnitType = CSS_IDENT; + switch (e) { + case DSLICE: + m_value.ident = CSSValueSlice; + break; + case DCLONE: + m_value.ident = CSSValueClone; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EBoxDecorationBreak() const +{ + switch (m_value.ident) { + case CSSValueSlice: + return DSLICE; + case CSSValueClone: + return DCLONE; + default: + ASSERT_NOT_REACHED(); + return DSLICE; + } +} + template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EBoxSizing e) : CSSValue(PrimitiveClass) { @@ -1170,7 +1197,7 @@ template<> inline CSSPrimitiveValue::operator EEmptyCell() const #if ENABLE(CSS3_FLEXBOX) -template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EFlexAlign e) +template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EAlignItems e) : CSSValue(PrimitiveClass) { m_primitiveUnitType = CSS_IDENT; @@ -1196,7 +1223,7 @@ template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EFlexAlign e) } } -template<> inline CSSPrimitiveValue::operator EFlexAlign() const +template<> inline CSSPrimitiveValue::operator EAlignItems() const { switch (m_value.ident) { case CSSValueAuto: @@ -1231,11 +1258,11 @@ template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EFlexPack e) case PackCenter: m_value.ident = CSSValueCenter; break; - case PackJustify: - m_value.ident = CSSValueJustify; + case PackSpaceBetween: + m_value.ident = CSSValueSpaceBetween; break; - case PackDistribute: - m_value.ident = CSSValueDistribute; + case PackSpaceAround: + m_value.ident = CSSValueSpaceAround; break; } } @@ -1249,10 +1276,10 @@ template<> inline CSSPrimitiveValue::operator EFlexPack() const return PackEnd; case CSSValueCenter: return PackCenter; - case CSSValueJustify: - return PackJustify; - case CSSValueDistribute: - return PackDistribute; + case CSSValueSpaceBetween: + return PackSpaceBetween; + case CSSValueSpaceAround: + return PackSpaceAround; default: ASSERT_NOT_REACHED(); return PackStart; @@ -1310,11 +1337,11 @@ template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EFlexLinePack e) case LinePackCenter: m_value.ident = CSSValueCenter; break; - case LinePackJustify: - m_value.ident = CSSValueJustify; + case LinePackSpaceBetween: + m_value.ident = CSSValueSpaceBetween; break; - case LinePackDistribute: - m_value.ident = CSSValueDistribute; + case LinePackSpaceAround: + m_value.ident = CSSValueSpaceAround; break; case LinePackStretch: m_value.ident = CSSValueStretch; @@ -1331,10 +1358,10 @@ template<> inline CSSPrimitiveValue::operator EFlexLinePack() const return LinePackEnd; case CSSValueCenter: return LinePackCenter; - case CSSValueJustify: - return LinePackJustify; - case CSSValueDistribute: - return LinePackDistribute; + case CSSValueSpaceBetween: + return LinePackSpaceBetween; + case CSSValueSpaceAround: + return LinePackSpaceAround; case CSSValueStretch: return LinePackStretch; default: diff --git a/Source/WebCore/css/CSSProperty.cpp b/Source/WebCore/css/CSSProperty.cpp index 319b02614..29eb85033 100644 --- a/Source/WebCore/css/CSSProperty.cpp +++ b/Source/WebCore/css/CSSProperty.cpp @@ -513,6 +513,7 @@ bool CSSProperty::isInheritedProperty(CSSPropertyID propertyID) case CSSPropertyWebkitBorderStartStyle: case CSSPropertyWebkitBorderStartWidth: case CSSPropertyWebkitBoxAlign: + case CSSPropertyWebkitBoxDecorationBreak: case CSSPropertyWebkitBoxFlex: case CSSPropertyWebkitBoxFlexGroup: case CSSPropertyWebkitBoxLines: @@ -538,11 +539,11 @@ bool CSSProperty::isInheritedProperty(CSSPropertyID propertyID) case CSSPropertyWebkitFilter: #endif #if ENABLE(CSS3_FLEXBOX) + case CSSPropertyWebkitAlignItems: + case CSSPropertyWebkitAlignSelf: case CSSPropertyWebkitFlex: case CSSPropertyWebkitFlexOrder: case CSSPropertyWebkitFlexPack: - case CSSPropertyWebkitFlexAlign: - case CSSPropertyWebkitFlexItemAlign: case CSSPropertyWebkitFlexDirection: case CSSPropertyWebkitFlexFlow: case CSSPropertyWebkitFlexLinePack: diff --git a/Source/WebCore/css/CSSProperty.h b/Source/WebCore/css/CSSProperty.h index 0f99e677f..b746d80b9 100644 --- a/Source/WebCore/css/CSSProperty.h +++ b/Source/WebCore/css/CSSProperty.h @@ -71,4 +71,11 @@ private: } // namespace WebCore +namespace WTF { +template <> struct VectorTraits<WebCore::CSSProperty> : VectorTraitsBase<false, WebCore::CSSProperty> { + static const bool canInitializeWithMemset = true; + static const bool canMoveWithMemcpy = true; +}; +} + #endif // CSSProperty_h diff --git a/Source/WebCore/css/CSSPropertyNames.in b/Source/WebCore/css/CSSPropertyNames.in index 2739dbafc..34985f255 100644 --- a/Source/WebCore/css/CSSPropertyNames.in +++ b/Source/WebCore/css/CSSPropertyNames.in @@ -253,15 +253,16 @@ z-index -webkit-column-span -webkit-column-width -webkit-columns +-webkit-box-decoration-break #if defined(ENABLE_CSS_FILTERS) && ENABLE_CSS_FILTERS -webkit-filter #endif #if defined(ENABLE_CSS3_FLEXBOX) && ENABLE_CSS3_FLEXBOX +-webkit-align-items +-webkit-align-self -webkit-flex --webkit-flex-align -webkit-flex-direction -webkit-flex-flow --webkit-flex-item-align -webkit-flex-line-pack -webkit-flex-order -webkit-flex-pack diff --git a/Source/WebCore/css/CSSReflectValue.cpp b/Source/WebCore/css/CSSReflectValue.cpp index f5d658e18..b36c3ad7b 100644 --- a/Source/WebCore/css/CSSReflectValue.cpp +++ b/Source/WebCore/css/CSSReflectValue.cpp @@ -59,7 +59,7 @@ String CSSReflectValue::customCssText() const return result; } -void CSSReflectValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const StyleSheetContents* styleSheet) +void CSSReflectValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const StyleSheetContents* styleSheet) const { if (m_mask) m_mask->addSubresourceStyleURLs(urls, styleSheet); diff --git a/Source/WebCore/css/CSSReflectValue.h b/Source/WebCore/css/CSSReflectValue.h index 9a844259e..5cfb20e27 100644 --- a/Source/WebCore/css/CSSReflectValue.h +++ b/Source/WebCore/css/CSSReflectValue.h @@ -49,7 +49,7 @@ public: String customCssText() const; - void addSubresourceStyleURLs(ListHashSet<KURL>&, const StyleSheetContents*); + void addSubresourceStyleURLs(ListHashSet<KURL>&, const StyleSheetContents*) const; private: CSSReflectValue(CSSReflectionDirection direction, PassRefPtr<CSSPrimitiveValue> offset, PassRefPtr<CSSValue> mask) diff --git a/Source/WebCore/css/CSSSelector.cpp b/Source/WebCore/css/CSSSelector.cpp index 5bc0ee378..13479b640 100644 --- a/Source/WebCore/css/CSSSelector.cpp +++ b/Source/WebCore/css/CSSSelector.cpp @@ -81,10 +81,9 @@ inline unsigned CSSSelector::specificityForOneSelector() const case End: // FIXME: PsuedoAny should base the specificity on the sub-selectors. // See http://lists.w3.org/Archives/Public/www-style/2010Sep/0530.html - if (pseudoType() == PseudoNot) { - ASSERT(selectorList()); + if (pseudoType() == PseudoNot && selectorList()) s += selectorList()->first()->specificityForOneSelector(); - } else + else s += 0x100; case None: break; @@ -544,8 +543,8 @@ String CSSSelector::selectorText() const switch (cs->pseudoType()) { case PseudoNot: - ASSERT(cs->selectorList()); - str += cs->selectorList()->first()->selectorText(); + if (CSSSelectorList* selectorList = cs->selectorList()) + str += selectorList->first()->selectorText(); str += ")"; break; case PseudoLang: diff --git a/Source/WebCore/css/CSSStyleRule.cpp b/Source/WebCore/css/CSSStyleRule.cpp index 5a780264a..1eeb32d42 100644 --- a/Source/WebCore/css/CSSStyleRule.cpp +++ b/Source/WebCore/css/CSSStyleRule.cpp @@ -59,8 +59,9 @@ CSSStyleRule::~CSSStyleRule() CSSStyleDeclaration* CSSStyleRule::style() const { - if (!m_propertiesCSSOMWrapper) - m_propertiesCSSOMWrapper = StyleRuleCSSStyleDeclaration::create(m_styleRule->properties(), const_cast<CSSStyleRule*>(this)); + if (!m_propertiesCSSOMWrapper) { + m_propertiesCSSOMWrapper = StyleRuleCSSStyleDeclaration::create(m_styleRule->mutableProperties(), const_cast<CSSStyleRule*>(this)); + } return m_propertiesCSSOMWrapper.get(); } @@ -123,7 +124,7 @@ void CSSStyleRule::reattach(StyleRule* rule) { m_styleRule = rule; if (m_propertiesCSSOMWrapper) - m_propertiesCSSOMWrapper->reattach(m_styleRule->properties()); + m_propertiesCSSOMWrapper->reattach(m_styleRule->mutableProperties()); } } // namespace WebCore diff --git a/Source/WebCore/css/CSSValue.cpp b/Source/WebCore/css/CSSValue.cpp index 1151959e0..f568cc5f4 100644 --- a/Source/WebCore/css/CSSValue.cpp +++ b/Source/WebCore/css/CSSValue.cpp @@ -99,19 +99,19 @@ CSSValue::Type CSSValue::cssValueType() const return CSS_CUSTOM; } -void CSSValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const StyleSheetContents* styleSheet) +void CSSValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const StyleSheetContents* styleSheet) const { // This should get called for internal instances only. ASSERT(!isCSSOMSafe()); if (isPrimitiveValue()) - static_cast<CSSPrimitiveValue*>(this)->addSubresourceStyleURLs(urls, styleSheet); + static_cast<const CSSPrimitiveValue*>(this)->addSubresourceStyleURLs(urls, styleSheet); else if (isValueList()) - static_cast<CSSValueList*>(this)->addSubresourceStyleURLs(urls, styleSheet); + static_cast<const CSSValueList*>(this)->addSubresourceStyleURLs(urls, styleSheet); else if (classType() == FontFaceSrcClass) - static_cast<CSSFontFaceSrcValue*>(this)->addSubresourceStyleURLs(urls, styleSheet); + static_cast<const CSSFontFaceSrcValue*>(this)->addSubresourceStyleURLs(urls, styleSheet); else if (classType() == ReflectClass) - static_cast<CSSReflectValue*>(this)->addSubresourceStyleURLs(urls, styleSheet); + static_cast<const CSSReflectValue*>(this)->addSubresourceStyleURLs(urls, styleSheet); } String CSSValue::cssText() const diff --git a/Source/WebCore/css/CSSValue.h b/Source/WebCore/css/CSSValue.h index d5c023105..fe56428a1 100644 --- a/Source/WebCore/css/CSSValue.h +++ b/Source/WebCore/css/CSSValue.h @@ -107,7 +107,7 @@ public: PassRefPtr<CSSValue> cloneForCSSOM() const; - void addSubresourceStyleURLs(ListHashSet<KURL>&, const StyleSheetContents*); + void addSubresourceStyleURLs(ListHashSet<KURL>&, const StyleSheetContents*) const; protected: diff --git a/Source/WebCore/css/CSSValueKeywords.in b/Source/WebCore/css/CSSValueKeywords.in index 28e14cf4a..e39b0166d 100644 --- a/Source/WebCore/css/CSSValueKeywords.in +++ b/Source/WebCore/css/CSSValueKeywords.in @@ -463,6 +463,10 @@ end //center //baseline +// CSS_PROP_BOX_DECORATION_BREAK +clone +slice + // CSS_PROP_BOX_DIRECTION // normal reverse @@ -495,8 +499,8 @@ multiple // start // end // center -// justify -distribute +space-between +space-around // CSS_PROP_FLEX_FLOW row @@ -511,8 +515,8 @@ wrap-reverse // start // end // center -// justify -// distribute +// space-between +// space-around // stretch #endif @@ -901,6 +905,11 @@ wrap // -webkit-line-align edges +// (pointer:) media feature +// none +coarse +fine + #if defined(ENABLE_CSS_FILTERS) && ENABLE_CSS_FILTERS // -webkit-filter #if defined(ENABLE_CSS_SHADERS) && ENABLE_CSS_SHADERS diff --git a/Source/WebCore/css/CSSValueList.cpp b/Source/WebCore/css/CSSValueList.cpp index 537f135da..3ab7f9411 100644 --- a/Source/WebCore/css/CSSValueList.cpp +++ b/Source/WebCore/css/CSSValueList.cpp @@ -136,7 +136,7 @@ String CSSValueList::customCssText() const return result.toString(); } -void CSSValueList::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const StyleSheetContents* styleSheet) +void CSSValueList::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const StyleSheetContents* styleSheet) const { size_t size = m_values.size(); for (size_t i = 0; i < size; ++i) diff --git a/Source/WebCore/css/CSSValueList.h b/Source/WebCore/css/CSSValueList.h index a80152112..a4c59b4b0 100644 --- a/Source/WebCore/css/CSSValueList.h +++ b/Source/WebCore/css/CSSValueList.h @@ -60,7 +60,7 @@ public: String customCssText() const; - void addSubresourceStyleURLs(ListHashSet<KURL>&, const StyleSheetContents*); + void addSubresourceStyleURLs(ListHashSet<KURL>&, const StyleSheetContents*) const; PassRefPtr<CSSValueList> cloneForCSSOM() const; diff --git a/Source/WebCore/css/MediaFeatureNames.h b/Source/WebCore/css/MediaFeatureNames.h index 1daa4e9e1..b08439e4a 100644 --- a/Source/WebCore/css/MediaFeatureNames.h +++ b/Source/WebCore/css/MediaFeatureNames.h @@ -30,6 +30,7 @@ namespace WebCore { macro(grid, "grid") \ macro(monochrome, "monochrome") \ macro(height, "height") \ + macro(hover, "hover") \ macro(width, "width") \ macro(orientation, "orientation") \ macro(aspect_ratio, "aspect-ratio") \ @@ -55,6 +56,7 @@ namespace WebCore { macro(min_height, "min-height") \ macro(min_monochrome, "min-monochrome") \ macro(min_width, "min-width") \ + macro(pointer, "pointer") \ macro(transform_2d, "-webkit-transform-2d") \ macro(transform_3d, "-webkit-transform-3d") \ macro(transition, "-webkit-transition") \ diff --git a/Source/WebCore/css/MediaQueryEvaluator.cpp b/Source/WebCore/css/MediaQueryEvaluator.cpp index 4f045c67a..90c9df286 100644 --- a/Source/WebCore/css/MediaQueryEvaluator.cpp +++ b/Source/WebCore/css/MediaQueryEvaluator.cpp @@ -45,6 +45,7 @@ #include "PlatformScreen.h" #include "RenderView.h" #include "RenderStyle.h" +#include "Settings.h" #include "StyleResolver.h" #include <wtf/HashMap.h> @@ -536,6 +537,66 @@ static bool view_modeMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* fram return Page::stringToViewMode(static_cast<CSSPrimitiveValue*>(value)->getStringValue()) == frame->page()->viewMode(); } +enum PointerDeviceType { TouchPointer, MousePointer, NoPointer, UnknownPointer }; + +static PointerDeviceType leastCapablePrimaryPointerDeviceType(Frame* frame) +{ + if (frame->settings()->deviceSupportsTouch()) + return TouchPointer; + + // FIXME: We should also try to determine if we know we have a mouse. + // When we do this, we'll also need to differentiate between known not to + // have mouse or touch screen (NoPointer) and unknown (UnknownPointer). + // We could also take into account other preferences like accessibility + // settings to decide which of the available pointers should be considered + // "primary". + + return UnknownPointer; +} + +static bool hoverMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix) +{ + PointerDeviceType pointer = leastCapablePrimaryPointerDeviceType(frame); + + // If we're on a port that hasn't explicitly opted into providing pointer device information + // (or otherwise can't be confident in the pointer hardware available), then behave exactly + // as if this feature feature isn't supported. + if (pointer == UnknownPointer) + return false; + + float number = 1; + if (value) { + if (!numberValue(value, number)) + return false; + } + + return (pointer == NoPointer && !number) + || (pointer == TouchPointer && !number) + || (pointer == MousePointer && number == 1); +} + +static bool pointerMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix) +{ + PointerDeviceType pointer = leastCapablePrimaryPointerDeviceType(frame); + + // If we're on a port that hasn't explicitly opted into providing pointer device information + // (or otherwise can't be confident in the pointer hardware available), then behave exactly + // as if this feature feature isn't supported. + if (pointer == UnknownPointer) + return false; + + if (!value) + return pointer != NoPointer; + + if (!value->isPrimitiveValue()) + return false; + + String str = static_cast<CSSPrimitiveValue*>(value)->getStringValue(); + return (pointer == NoPointer && str == "none") + || (pointer == TouchPointer && str == "coarse") + || (pointer == MousePointer && str == "fine"); +} + static void createFunctionMap() { // Create the table. diff --git a/Source/WebCore/css/SelectorChecker.cpp b/Source/WebCore/css/SelectorChecker.cpp index 55af512ea..50fed4808 100644 --- a/Source/WebCore/css/SelectorChecker.cpp +++ b/Source/WebCore/css/SelectorChecker.cpp @@ -403,10 +403,13 @@ static inline bool isFastCheckableRelation(CSSSelector::Relation relation) static inline bool isFastCheckableMatch(const CSSSelector* selector) { - if (selector->m_match == CSSSelector::Set) - return true; + if (selector->m_match == CSSSelector::Set) { + // Style attribute is generated lazily but the fast path doesn't trigger it. + // Disallow them here rather than making the fast path more branchy. + return selector->attribute() != styleAttr; + } if (selector->m_match == CSSSelector::Exact) - return !htmlAttributeHasCaseInsensitiveValue(selector->attribute()); + return selector->attribute() != styleAttr && !htmlAttributeHasCaseInsensitiveValue(selector->attribute()); return selector->m_match == CSSSelector::None || selector->m_match == CSSSelector::Id || selector->m_match == CSSSelector::Class; } @@ -729,10 +732,15 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P if (selector->m_match == CSSSelector::PseudoClass) { // Handle :not up front. if (selector->pseudoType() == CSSSelector::PseudoNot) { - ASSERT(selector->selectorList()); + CSSSelectorList* selectorList = selector->selectorList(); + + // FIXME: We probably should fix the parser and make it never produce :not rules with missing selector list. + if (!selectorList) + return false; + SelectorCheckingContext subContext(context); subContext.isSubSelector = true; - for (subContext.selector = selector->selectorList()->first(); subContext.selector; subContext.selector = subContext.selector->tagHistory()) { + for (subContext.selector = selectorList->first(); subContext.selector; subContext.selector = subContext.selector->tagHistory()) { // :not cannot nest. I don't really know why this is a // restriction in CSS3, but it is, so let's honor it. // the parser enforces that this never occurs @@ -1043,7 +1051,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P } break; case CSSSelector::PseudoEnabled: - if (element && element->isFormControlElement()) + if (element && (element->isFormControlElement() || element->hasTagName(optionTag) || element->hasTagName(optgroupTag))) return element->isEnabledFormControl(); break; case CSSSelector::PseudoFullPageMedia: @@ -1052,7 +1060,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P case CSSSelector::PseudoDefault: return element && element->isDefaultButtonForForm(); case CSSSelector::PseudoDisabled: - if (element && (element->isFormControlElement() || element->hasTagName(optionTag))) + if (element && (element->isFormControlElement() || element->hasTagName(optionTag) || element->hasTagName(optgroupTag))) return !element->isEnabledFormControl(); break; case CSSSelector::PseudoReadOnly: @@ -1321,13 +1329,19 @@ unsigned SelectorChecker::determineLinkMatchType(const CSSSelector* selector) for (; selector; selector = selector->tagHistory()) { switch (selector->pseudoType()) { case CSSSelector::PseudoNot: - // :not(:visited) is equivalent to :link. Parser enforces that :not can't nest. - for (CSSSelector* subSelector = selector->selectorList()->first(); subSelector; subSelector = subSelector->tagHistory()) { - CSSSelector::PseudoType subType = subSelector->pseudoType(); - if (subType == CSSSelector::PseudoVisited) - linkMatchType &= ~SelectorChecker::MatchVisited; - else if (subType == CSSSelector::PseudoLink) - linkMatchType &= ~SelectorChecker::MatchLink; + { + // :not(:visited) is equivalent to :link. Parser enforces that :not can't nest. + CSSSelectorList* selectorList = selector->selectorList(); + if (!selectorList) + break; + + for (CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = subSelector->tagHistory()) { + CSSSelector::PseudoType subType = subSelector->pseudoType(); + if (subType == CSSSelector::PseudoVisited) + linkMatchType &= ~SelectorChecker::MatchVisited; + else if (subType == CSSSelector::PseudoLink) + linkMatchType &= ~SelectorChecker::MatchLink; + } } break; case CSSSelector::PseudoLink: diff --git a/Source/WebCore/css/StyleBuilder.cpp b/Source/WebCore/css/StyleBuilder.cpp index 4c5bae6e5..7c974dc27 100644 --- a/Source/WebCore/css/StyleBuilder.cpp +++ b/Source/WebCore/css/StyleBuilder.cpp @@ -1723,8 +1723,11 @@ public: { if (value->isPrimitiveValue()) { CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - if (primitiveValue->getIdent() == CSSValueNone) - applyInitialValue(styleResolver); + if (primitiveValue->getIdent() == CSSValueNone) { + styleResolver->style()->setPositiveFlex(0); + styleResolver->style()->setNegativeFlex(0); + styleResolver->style()->setFlexPreferredSize(Length(Auto)); + } return; } @@ -1911,6 +1914,7 @@ StyleBuilder::StyleBuilder() setPropertyHandler(CSSPropertyWebkitBorderRadius, CSSPropertyBorderRadius); setPropertyHandler(CSSPropertyWebkitBorderVerticalSpacing, ApplyPropertyComputeLength<short, &RenderStyle::verticalBorderSpacing, &RenderStyle::setVerticalBorderSpacing, &RenderStyle::initialVerticalBorderSpacing>::createHandler()); setPropertyHandler(CSSPropertyWebkitBoxAlign, ApplyPropertyDefault<EBoxAlignment, &RenderStyle::boxAlign, EBoxAlignment, &RenderStyle::setBoxAlign, EBoxAlignment, &RenderStyle::initialBoxAlign>::createHandler()); + setPropertyHandler(CSSPropertyWebkitBoxDecorationBreak, ApplyPropertyDefault<EBoxDecorationBreak, &RenderStyle::boxDecorationBreak, EBoxDecorationBreak, &RenderStyle::setBoxDecorationBreak, EBoxDecorationBreak, &RenderStyle::initialBoxDecorationBreak>::createHandler()); setPropertyHandler(CSSPropertyWebkitBoxDirection, ApplyPropertyDefault<EBoxDirection, &RenderStyle::boxDirection, EBoxDirection, &RenderStyle::setBoxDirection, EBoxDirection, &RenderStyle::initialBoxDirection>::createHandler()); setPropertyHandler(CSSPropertyWebkitBoxFlex, ApplyPropertyDefault<float, &RenderStyle::boxFlex, float, &RenderStyle::setBoxFlex, float, &RenderStyle::initialBoxFlex>::createHandler()); setPropertyHandler(CSSPropertyWebkitBoxFlexGroup, ApplyPropertyDefault<unsigned int, &RenderStyle::boxFlexGroup, unsigned int, &RenderStyle::setBoxFlexGroup, unsigned int, &RenderStyle::initialBoxFlexGroup>::createHandler()); @@ -1932,11 +1936,11 @@ StyleBuilder::StyleBuilder() setPropertyHandler(CSSPropertyWebkitColumnRuleStyle, ApplyPropertyDefault<EBorderStyle, &RenderStyle::columnRuleStyle, EBorderStyle, &RenderStyle::setColumnRuleStyle, EBorderStyle, &RenderStyle::initialBorderStyle>::createHandler()); setPropertyHandler(CSSPropertyWebkitColumnWidth, ApplyPropertyAuto<float, &RenderStyle::columnWidth, &RenderStyle::setColumnWidth, &RenderStyle::hasAutoColumnWidth, &RenderStyle::setHasAutoColumnWidth, ComputeLength>::createHandler()); #if ENABLE(CSS3_FLEXBOX) + setPropertyHandler(CSSPropertyWebkitAlignItems, ApplyPropertyDefault<EAlignItems, &RenderStyle::alignItems, EAlignItems, &RenderStyle::setAlignItems, EAlignItems, &RenderStyle::initialAlignItems>::createHandler()); + setPropertyHandler(CSSPropertyWebkitAlignSelf, ApplyPropertyDefault<EAlignItems, &RenderStyle::alignSelf, EAlignItems, &RenderStyle::setAlignSelf, EAlignItems, &RenderStyle::initialAlignSelf>::createHandler()); setPropertyHandler(CSSPropertyWebkitFlex, ApplyPropertyFlex::createHandler()); - setPropertyHandler(CSSPropertyWebkitFlexAlign, ApplyPropertyDefault<EFlexAlign, &RenderStyle::flexAlign, EFlexAlign, &RenderStyle::setFlexAlign, EFlexAlign, &RenderStyle::initialFlexAlign>::createHandler()); setPropertyHandler(CSSPropertyWebkitFlexDirection, ApplyPropertyDefault<EFlexDirection, &RenderStyle::flexDirection, EFlexDirection, &RenderStyle::setFlexDirection, EFlexDirection, &RenderStyle::initialFlexDirection>::createHandler()); setPropertyHandler(CSSPropertyWebkitFlexFlow, ApplyPropertyExpanding<SuppressValue, CSSPropertyWebkitFlexDirection, CSSPropertyWebkitFlexWrap>::createHandler()); - setPropertyHandler(CSSPropertyWebkitFlexItemAlign, ApplyPropertyDefault<EFlexAlign, &RenderStyle::flexItemAlign, EFlexAlign, &RenderStyle::setFlexItemAlign, EFlexAlign, &RenderStyle::initialFlexItemAlign>::createHandler()); setPropertyHandler(CSSPropertyWebkitFlexLinePack, ApplyPropertyDefault<EFlexLinePack, &RenderStyle::flexLinePack, EFlexLinePack, &RenderStyle::setFlexLinePack, EFlexLinePack, &RenderStyle::initialFlexLinePack>::createHandler()); setPropertyHandler(CSSPropertyWebkitFlexOrder, ApplyPropertyDefault<int, &RenderStyle::flexOrder, int, &RenderStyle::setFlexOrder, int, &RenderStyle::initialFlexOrder>::createHandler()); setPropertyHandler(CSSPropertyWebkitFlexPack, ApplyPropertyDefault<EFlexPack, &RenderStyle::flexPack, EFlexPack, &RenderStyle::setFlexPack, EFlexPack, &RenderStyle::initialFlexPack>::createHandler()); diff --git a/Source/WebCore/css/StylePropertySet.cpp b/Source/WebCore/css/StylePropertySet.cpp index 4ec31996a..cbe92c4b5 100644 --- a/Source/WebCore/css/StylePropertySet.cpp +++ b/Source/WebCore/css/StylePropertySet.cpp @@ -50,28 +50,47 @@ static PropertySetCSSOMWrapperMap& propertySetCSSOMWrapperMap() return propertySetCSSOMWrapperMapInstance; } +PassRefPtr<StylePropertySet> StylePropertySet::createImmutable(const CSSProperty* properties, unsigned count, CSSParserMode cssParserMode) +{ + void* slot = WTF::fastMalloc(sizeof(StylePropertySet) - sizeof(void*) + sizeof(CSSProperty) * count); + return adoptRef(new (slot) StylePropertySet(properties, count, cssParserMode, /* makeMutable */ false)); +} + StylePropertySet::StylePropertySet(CSSParserMode cssParserMode) : m_cssParserMode(cssParserMode) , m_ownsCSSOMWrapper(false) + , m_isMutable(true) + , m_arraySize(0) + , m_mutablePropertyVector(new Vector<CSSProperty>) { } -StylePropertySet::StylePropertySet(StylePropertyVector& properties, CSSParserMode cssParserMode) +StylePropertySet::StylePropertySet(const CSSProperty* properties, unsigned count, CSSParserMode cssParserMode, bool makeMutable) : m_cssParserMode(cssParserMode) , m_ownsCSSOMWrapper(false) + , m_isMutable(makeMutable) { - m_properties.swap(properties); - - // This shrinkToFit() will be a no-op in the typical case (no duplicate properties were eliminated after parsing.) - m_properties.shrinkToFit(); + if (makeMutable) { + m_mutablePropertyVector = new Vector<CSSProperty>; + m_mutablePropertyVector->reserveInitialCapacity(count); + for (unsigned i = 0; i < count; ++i) + m_mutablePropertyVector->uncheckedAppend(properties[i]); + } else { + m_arraySize = count; + for (unsigned i = 0; i < m_arraySize; ++i) + new (&array()[i]) CSSProperty(properties[i]); + } } StylePropertySet::StylePropertySet(const StylePropertySet& o) : RefCounted<StylePropertySet>() - , m_properties(o.m_properties) , m_cssParserMode(o.m_cssParserMode) , m_ownsCSSOMWrapper(false) + , m_isMutable(true) + , m_arraySize(0) + , m_mutablePropertyVector(new Vector<CSSProperty>) { + copyPropertiesFrom(o); } StylePropertySet::~StylePropertySet() @@ -79,11 +98,33 @@ StylePropertySet::~StylePropertySet() ASSERT(!m_ownsCSSOMWrapper || propertySetCSSOMWrapperMap().contains(this)); if (m_ownsCSSOMWrapper) propertySetCSSOMWrapperMap().remove(this); + if (isMutable()) + delete m_mutablePropertyVector; + else { + for (unsigned i = 0; i < m_arraySize; ++i) + array()[i].~CSSProperty(); + } +} + +void StylePropertySet::setCSSParserMode(CSSParserMode cssParserMode) +{ + ASSERT(isMutable()); + m_cssParserMode = cssParserMode; } void StylePropertySet::copyPropertiesFrom(const StylePropertySet& other) { - m_properties = other.m_properties; + ASSERT(isMutable()); + + if (other.isMutable()) { + *m_mutablePropertyVector = *other.m_mutablePropertyVector; + return; + } + + ASSERT(m_mutablePropertyVector->isEmpty()); + m_mutablePropertyVector->reserveInitialCapacity(other.m_arraySize); + for (unsigned i = 0; i < other.m_arraySize; ++i) + m_mutablePropertyVector->uncheckedAppend(other.array()[i]); } String StylePropertySet::getPropertyValue(CSSPropertyID propertyID) const @@ -453,6 +494,7 @@ PassRefPtr<CSSValue> StylePropertySet::getPropertyCSSValue(CSSPropertyID propert bool StylePropertySet::removeShorthandProperty(CSSPropertyID propertyID) { + ASSERT(isMutable()); StylePropertyShorthand shorthand = shorthandForProperty(propertyID); if (!shorthand.length()) return false; @@ -461,6 +503,7 @@ bool StylePropertySet::removeShorthandProperty(CSSPropertyID propertyID) bool StylePropertySet::removeProperty(CSSPropertyID propertyID, String* returnText) { + ASSERT(isMutable()); if (removeShorthandProperty(propertyID)) { // FIXME: Return an equivalent shorthand when possible. if (returnText) @@ -480,7 +523,7 @@ bool StylePropertySet::removeProperty(CSSPropertyID propertyID, String* returnTe // A more efficient removal strategy would involve marking entries as empty // and sweeping them when the vector grows too big. - m_properties.remove(foundProperty - m_properties.data()); + m_mutablePropertyVector->remove(foundProperty - m_mutablePropertyVector->data()); return true; } @@ -516,6 +559,7 @@ bool StylePropertySet::isPropertyImplicit(CSSPropertyID propertyID) const bool StylePropertySet::setProperty(CSSPropertyID propertyID, const String& value, bool important, StyleSheetContents* contextStyleSheet) { + ASSERT(isMutable()); // Setting the value to an empty string just removes the property in both IE and Gecko. // Setting it to null seems to produce less consistent results, but we treat it just the same. if (value.isEmpty()) { @@ -530,6 +574,7 @@ bool StylePropertySet::setProperty(CSSPropertyID propertyID, const String& value void StylePropertySet::setProperty(CSSPropertyID propertyID, PassRefPtr<CSSValue> prpValue, bool important) { + ASSERT(isMutable()); StylePropertyShorthand shorthand = shorthandForProperty(propertyID); if (!shorthand.length()) { setProperty(CSSProperty(propertyID, prpValue, important)); @@ -540,11 +585,12 @@ void StylePropertySet::setProperty(CSSPropertyID propertyID, PassRefPtr<CSSValue RefPtr<CSSValue> value = prpValue; for (unsigned i = 0; i < shorthand.length(); ++i) - m_properties.append(CSSProperty(shorthand.properties()[i], value, important)); + append(CSSProperty(shorthand.properties()[i], value, important)); } void StylePropertySet::setProperty(const CSSProperty& property, CSSProperty* slot) { + ASSERT(isMutable()); if (!removeShorthandProperty(property.id())) { CSSProperty* toReplace = slot ? slot : findPropertyWithId(property.id()); if (toReplace) { @@ -552,18 +598,21 @@ void StylePropertySet::setProperty(const CSSProperty& property, CSSProperty* slo return; } } - m_properties.append(property); + append(property); } bool StylePropertySet::setProperty(CSSPropertyID propertyID, int identifier, bool important) { + ASSERT(isMutable()); setProperty(CSSProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important)); return true; } void StylePropertySet::parseDeclaration(const String& styleDeclaration, StyleSheetContents* contextStyleSheet) { - m_properties.clear(); + ASSERT(isMutable()); + + m_mutablePropertyVector->clear(); CSSParserContext context(cssParserMode()); if (contextStyleSheet) { @@ -576,13 +625,15 @@ void StylePropertySet::parseDeclaration(const String& styleDeclaration, StyleShe void StylePropertySet::addParsedProperties(const Vector<CSSProperty>& properties) { - m_properties.reserveCapacity(m_properties.size() + properties.size()); + ASSERT(isMutable()); + m_mutablePropertyVector->reserveCapacity(m_mutablePropertyVector->size() + properties.size()); for (unsigned i = 0; i < properties.size(); ++i) addParsedProperty(properties[i]); } void StylePropertySet::addParsedProperty(const CSSProperty& property) { + ASSERT(isMutable()); // Only add properties that have no !important counterpart present if (!propertyIsImportant(property.id()) || property.isImportant()) setProperty(property); @@ -600,9 +651,9 @@ String StylePropertySet::asText() const BitArray<numCSSProperties> shorthandPropertyUsed; BitArray<numCSSProperties> shorthandPropertyAppeared; - unsigned size = m_properties.size(); + unsigned size = propertyCount(); for (unsigned n = 0; n < size; ++n) { - const CSSProperty& prop = m_properties[n]; + const CSSProperty& prop = propertyAt(n); CSSPropertyID propertyID = prop.id(); CSSPropertyID shorthandPropertyID = CSSPropertyInvalid; CSSPropertyID borderFallbackShorthandProperty = CSSPropertyInvalid; @@ -812,24 +863,25 @@ String StylePropertySet::asText() const void StylePropertySet::merge(const StylePropertySet* other, bool argOverridesOnConflict) { - unsigned size = other->m_properties.size(); + ASSERT(isMutable()); + unsigned size = other->propertyCount(); for (unsigned n = 0; n < size; ++n) { - const CSSProperty& toMerge = other->m_properties[n]; + const CSSProperty& toMerge = other->propertyAt(n); CSSProperty* old = findPropertyWithId(toMerge.id()); if (old) { if (!argOverridesOnConflict && old->value()) continue; setProperty(toMerge, old); } else - m_properties.append(toMerge); + append(toMerge); } } -void StylePropertySet::addSubresourceStyleURLs(ListHashSet<KURL>& urls, StyleSheetContents* contextStyleSheet) +void StylePropertySet::addSubresourceStyleURLs(ListHashSet<KURL>& urls, StyleSheetContents* contextStyleSheet) const { - size_t size = m_properties.size(); - for (size_t i = 0; i < size; ++i) - m_properties[i].value()->addSubresourceStyleURLs(urls, contextStyleSheet); + unsigned size = propertyCount(); + for (unsigned i = 0; i < size; ++i) + propertyAt(i).value()->addSubresourceStyleURLs(urls, contextStyleSheet); } // This is the list of properties we want to copy in the copyBlockProperties() function. @@ -874,7 +926,8 @@ void StylePropertySet::removeBlockProperties() bool StylePropertySet::removePropertiesInSet(const CSSPropertyID* set, unsigned length) { - if (m_properties.isEmpty()) + ASSERT(isMutable()); + if (m_mutablePropertyVector->isEmpty()) return false; // FIXME: This is always used with static sets and in that case constructing the hash repeatedly is pretty pointless. @@ -882,12 +935,12 @@ bool StylePropertySet::removePropertiesInSet(const CSSPropertyID* set, unsigned for (unsigned i = 0; i < length; ++i) toRemove.add(set[i]); - StylePropertyVector newProperties; - newProperties.reserveInitialCapacity(m_properties.size()); + Vector<CSSProperty> newProperties; + newProperties.reserveInitialCapacity(m_mutablePropertyVector->size()); - unsigned size = m_properties.size(); + unsigned size = m_mutablePropertyVector->size(); for (unsigned n = 0; n < size; ++n) { - const CSSProperty& property = m_properties[n]; + const CSSProperty& property = m_mutablePropertyVector->at(n); // Not quite sure if the isImportant test is needed but it matches the existing behavior. if (!property.isImportant()) { if (toRemove.contains(property.id())) @@ -896,25 +949,26 @@ bool StylePropertySet::removePropertiesInSet(const CSSPropertyID* set, unsigned newProperties.append(property); } - bool changed = newProperties.size() != m_properties.size(); - m_properties = newProperties; + bool changed = newProperties.size() != m_mutablePropertyVector->size(); + *m_mutablePropertyVector = newProperties; return changed; } const CSSProperty* StylePropertySet::findPropertyWithId(CSSPropertyID propertyID) const { - for (int n = m_properties.size() - 1 ; n >= 0; --n) { - if (propertyID == m_properties[n].id()) - return &m_properties[n]; + for (int n = propertyCount() - 1 ; n >= 0; --n) { + if (propertyID == propertyAt(n).id()) + return &propertyAt(n); } return 0; } CSSProperty* StylePropertySet::findPropertyWithId(CSSPropertyID propertyID) { - for (int n = m_properties.size() - 1 ; n >= 0; --n) { - if (propertyID == m_properties[n].id()) - return &m_properties[n]; + ASSERT(isMutable()); + for (int n = propertyCount() - 1 ; n >= 0; --n) { + if (propertyID == propertyAt(n).id()) + return &propertyAt(n); } return 0; } @@ -927,10 +981,11 @@ bool StylePropertySet::propertyMatches(const CSSProperty* property) const void StylePropertySet::removeEquivalentProperties(const StylePropertySet* style) { + ASSERT(isMutable()); Vector<CSSPropertyID> propertiesToRemove; - size_t size = m_properties.size(); - for (size_t i = 0; i < size; ++i) { - const CSSProperty& property = m_properties[i]; + unsigned size = m_mutablePropertyVector->size(); + for (unsigned i = 0; i < size; ++i) { + const CSSProperty& property = m_mutablePropertyVector->at(i); if (style->propertyMatches(&property)) propertiesToRemove.append(property.id()); } @@ -941,10 +996,11 @@ void StylePropertySet::removeEquivalentProperties(const StylePropertySet* style) void StylePropertySet::removeEquivalentProperties(const CSSStyleDeclaration* style) { + ASSERT(isMutable()); Vector<CSSPropertyID> propertiesToRemove; - size_t size = m_properties.size(); - for (size_t i = 0; i < size; ++i) { - const CSSProperty& property = m_properties[i]; + unsigned size = m_mutablePropertyVector->size(); + for (unsigned i = 0; i < size; ++i) { + const CSSProperty& property = m_mutablePropertyVector->at(i); if (style->cssPropertyMatches(&property)) propertiesToRemove.append(property.id()); } @@ -960,14 +1016,14 @@ PassRefPtr<StylePropertySet> StylePropertySet::copy() const PassRefPtr<StylePropertySet> StylePropertySet::copyPropertiesInSet(const CSSPropertyID* set, unsigned length) const { - StylePropertyVector list; + Vector<CSSProperty, 256> list; list.reserveInitialCapacity(length); for (unsigned i = 0; i < length; ++i) { RefPtr<CSSValue> value = getPropertyCSSValue(set[i]); if (value) list.append(CSSProperty(set[i], value.release(), false)); } - return StylePropertySet::adopt(list); + return StylePropertySet::create(list.data(), list.size()); } CSSStyleDeclaration* StylePropertySet::ensureCSSStyleDeclaration() const @@ -1006,13 +1062,13 @@ void StylePropertySet::clearParentElement(StyledElement* element) unsigned StylePropertySet::averageSizeInBytes() { // Please update this if the storage scheme changes so that this longer reflects the actual size. - return sizeof(StylePropertySet); + return sizeof(StylePropertySet) + sizeof(CSSProperty) * 2; } // See the function above if you need to update this. class SameSizeAsStylePropertySet : public RefCounted<SameSizeAsStylePropertySet> { - StylePropertyVector properties; unsigned bitfield; + void* properties; }; COMPILE_ASSERT(sizeof(StylePropertySet) == sizeof(SameSizeAsStylePropertySet), style_property_set_should_stay_small); @@ -1023,4 +1079,10 @@ void StylePropertySet::showStyle() } #endif +inline void StylePropertySet::append(const CSSProperty& property) +{ + ASSERT(isMutable()); + m_mutablePropertyVector->append(property); +} + } // namespace WebCore diff --git a/Source/WebCore/css/StylePropertySet.h b/Source/WebCore/css/StylePropertySet.h index e14f89c3f..e7992ed35 100644 --- a/Source/WebCore/css/StylePropertySet.h +++ b/Source/WebCore/css/StylePropertySet.h @@ -39,8 +39,6 @@ class StyledElement; class StylePropertyShorthand; class StyleSheetContents; -typedef Vector<CSSProperty, 4> StylePropertyVector; - class StylePropertySet : public RefCounted<StylePropertySet> { public: ~StylePropertySet(); @@ -49,16 +47,16 @@ public: { return adoptRef(new StylePropertySet(cssParserMode)); } - static PassRefPtr<StylePropertySet> adopt(StylePropertyVector& properties, CSSParserMode cssParserMode = CSSStrictMode) + static PassRefPtr<StylePropertySet> create(const CSSProperty* properties, unsigned count) { - return adoptRef(new StylePropertySet(properties, cssParserMode)); + return adoptRef(new StylePropertySet(properties, count, CSSStrictMode, /* makeMutable */ true)); } + static PassRefPtr<StylePropertySet> createImmutable(const CSSProperty* properties, unsigned count, CSSParserMode); - unsigned propertyCount() const { return m_properties.size(); } - bool isEmpty() const { return m_properties.isEmpty(); } - const CSSProperty& propertyAt(unsigned index) const { return m_properties[index]; } - - void shrinkToFit() { m_properties.shrinkToFit(); } + unsigned propertyCount() const; + bool isEmpty() const; + const CSSProperty& propertyAt(unsigned index) const; + CSSProperty& propertyAt(unsigned index); PassRefPtr<CSSValue> getPropertyCSSValue(CSSPropertyID) const; String getPropertyValue(CSSPropertyID) const; @@ -87,12 +85,13 @@ public: void merge(const StylePropertySet*, bool argOverridesOnConflict = true); - void setCSSParserMode(CSSParserMode cssParserMode) { m_cssParserMode = cssParserMode; } + void setCSSParserMode(CSSParserMode); CSSParserMode cssParserMode() const { return static_cast<CSSParserMode>(m_cssParserMode); } - void addSubresourceStyleURLs(ListHashSet<KURL>&, StyleSheetContents* contextStyleSheet); + void addSubresourceStyleURLs(ListHashSet<KURL>&, StyleSheetContents* contextStyleSheet) const; PassRefPtr<StylePropertySet> copy() const; + // Used by StyledElement::copyNonAttributeProperties(). void copyPropertiesFrom(const StylePropertySet&); @@ -107,9 +106,8 @@ public: CSSStyleDeclaration* ensureCSSStyleDeclaration() const; CSSStyleDeclaration* ensureInlineCSSStyleDeclaration(const StyledElement* parentElement) const; - - // FIXME: Expand the concept of mutable/immutable StylePropertySet. - bool isMutable() const { return m_ownsCSSOMWrapper; } + + bool isMutable() const { return m_isMutable; } static unsigned averageSizeInBytes(); @@ -119,7 +117,7 @@ public: private: StylePropertySet(CSSParserMode); - StylePropertySet(StylePropertyVector&, CSSParserMode); + StylePropertySet(const CSSProperty* properties, unsigned count, CSSParserMode, bool makeMutable); StylePropertySet(const StylePropertySet&); void setNeedsStyleRecalc(); @@ -140,14 +138,61 @@ private: const CSSProperty* findPropertyWithId(CSSPropertyID) const; CSSProperty* findPropertyWithId(CSSPropertyID); - StylePropertyVector m_properties; + void append(const CSSProperty&); + CSSProperty* array(); + const CSSProperty* array() const; unsigned m_cssParserMode : 2; mutable unsigned m_ownsCSSOMWrapper : 1; + mutable unsigned m_isMutable : 1; + unsigned m_arraySize : 28; + + union { + Vector<CSSProperty>* m_mutablePropertyVector; + void* m_properties; + }; friend class PropertySetCSSStyleDeclaration; }; +inline CSSProperty& StylePropertySet::propertyAt(unsigned index) +{ + if (isMutable()) + return m_mutablePropertyVector->at(index); + return array()[index]; +} + +inline const CSSProperty& StylePropertySet::propertyAt(unsigned index) const +{ + if (isMutable()) + return m_mutablePropertyVector->at(index); + return array()[index]; +} + +inline unsigned StylePropertySet::propertyCount() const +{ + if (isMutable()) + return m_mutablePropertyVector->size(); + return m_arraySize; +} + +inline bool StylePropertySet::isEmpty() const +{ + return !propertyCount(); +} + +inline CSSProperty* StylePropertySet::array() +{ + ASSERT(!isMutable()); + return reinterpret_cast<CSSProperty*>(&m_properties); +} + +inline const CSSProperty* StylePropertySet::array() const +{ + ASSERT(!isMutable()); + return reinterpret_cast<const CSSProperty*>(&m_properties); +} + } // namespace WebCore #endif // StylePropertySet_h diff --git a/Source/WebCore/css/StyleResolver.cpp b/Source/WebCore/css/StyleResolver.cpp index 06b41a8ac..1f023d2bd 100644 --- a/Source/WebCore/css/StyleResolver.cpp +++ b/Source/WebCore/css/StyleResolver.cpp @@ -816,11 +816,11 @@ static void ensureDefaultStyleSheetsForElement(Element* element) ASSERT(mathMLStyleSheet || defaultStyle->features().siblingRules.isEmpty()); } -void StyleResolver::addMatchedProperties(MatchResult& matchResult, StylePropertySet* properties, StyleRule* rule, unsigned linkMatchType, bool inRegionRule) +void StyleResolver::addMatchedProperties(MatchResult& matchResult, const StylePropertySet* properties, StyleRule* rule, unsigned linkMatchType, bool inRegionRule) { matchResult.matchedProperties.grow(matchResult.matchedProperties.size() + 1); MatchedProperties& newProperties = matchResult.matchedProperties.last(); - newProperties.properties = properties; + newProperties.properties = const_cast<StylePropertySet*>(properties); newProperties.linkMatchType = linkMatchType; newProperties.isInRegionRule = inRegionRule; matchResult.matchedRules.append(rule); @@ -1051,7 +1051,7 @@ void StyleResolver::collectMatchingRulesForList(const Vector<RuleData>* rules, i continue; } // If the rule has no properties to apply, then ignore it in the non-debug mode. - StylePropertySet* properties = rule->properties(); + const StylePropertySet* properties = rule->properties(); if (!properties || (properties->isEmpty() && !options.includeEmptyRules)) { InspectorInstrumentation::didMatchRule(cookie, false); continue; @@ -1392,6 +1392,9 @@ bool StyleResolver::canShareStyleWithElement(StyledElement* element) const if (element->hasTagName(optionTag)) return false; + if (element->hasTagName(optgroupTag) && m_element->disabled() != element->disabled()) + return false; + bool isControl = element->isFormControlElement(); if (isControl != m_element->isFormControlElement()) @@ -1957,6 +1960,16 @@ static EDisplay equivalentBlockDisplay(EDisplay display, bool isFloating, bool s return BLOCK; } +// CSS requires text-decoration to be reset at each DOM element for tables, +// inline blocks, inline tables, run-ins, shadow DOM crossings, floating elements, +// and absolute or relatively positioned elements. +static bool doesNotInheritTextDecoration(RenderStyle* style, Element* e) +{ + return style->display() == TABLE || style->display() == INLINE_TABLE || style->display() == RUN_IN + || style->display() == INLINE_BLOCK || style->display() == INLINE_BOX || isAtShadowBoundary(e) + || style->isFloating() || style->isPositioned(); +} + void StyleResolver::adjustRenderStyle(RenderStyle* style, RenderStyle* parentStyle, Element *e) { // Cache our original display. @@ -2069,10 +2082,7 @@ void StyleResolver::adjustRenderStyle(RenderStyle* style, RenderStyle* parentSty style->setOverflowY(style->overflowY() == OVISIBLE ? OAUTO : style->overflowY()); } - // Finally update our text decorations in effect, but don't allow text-decoration to percolate through - // tables, inline blocks, inline tables, run-ins, or shadow DOM. - if (style->display() == TABLE || style->display() == INLINE_TABLE || style->display() == RUN_IN - || style->display() == INLINE_BLOCK || style->display() == INLINE_BOX || isAtShadowBoundary(e)) + if (doesNotInheritTextDecoration(style, e)) style->setTextDecorationsInEffect(style->textDecoration()); else style->addToTextDecorationsInEffect(style->textDecoration()); @@ -2911,7 +2921,7 @@ void StyleResolver::matchPageRulesForList(Vector<StyleRulePage*>& matchedRules, continue; // If the rule has no properties to apply, then ignore it. - StylePropertySet* properties = rule->properties(); + const StylePropertySet* properties = rule->properties(); if (!properties || properties->isEmpty()) continue; @@ -4089,6 +4099,7 @@ void StyleResolver::applyProperty(CSSPropertyID id, CSSValue *value) case CSSPropertyWebkitBorderRadius: case CSSPropertyWebkitBorderVerticalSpacing: case CSSPropertyWebkitBoxAlign: + case CSSPropertyWebkitBoxDecorationBreak: case CSSPropertyWebkitBoxDirection: case CSSPropertyWebkitBoxFlex: case CSSPropertyWebkitBoxFlexGroup: @@ -4110,11 +4121,11 @@ void StyleResolver::applyProperty(CSSPropertyID id, CSSValue *value) case CSSPropertyWebkitColumnSpan: case CSSPropertyWebkitColumnWidth: #if ENABLE(CSS3_FLEXBOX) + case CSSPropertyWebkitAlignItems: + case CSSPropertyWebkitAlignSelf: case CSSPropertyWebkitFlex: - case CSSPropertyWebkitFlexAlign: case CSSPropertyWebkitFlexDirection: case CSSPropertyWebkitFlexFlow: - case CSSPropertyWebkitFlexItemAlign: case CSSPropertyWebkitFlexLinePack: case CSSPropertyWebkitFlexOrder: case CSSPropertyWebkitFlexPack: diff --git a/Source/WebCore/css/StyleResolver.h b/Source/WebCore/css/StyleResolver.h index f382d5f8a..539dd6356 100644 --- a/Source/WebCore/css/StyleResolver.h +++ b/Source/WebCore/css/StyleResolver.h @@ -334,7 +334,7 @@ private: bool includeEmptyRules; }; - static void addMatchedProperties(MatchResult&, StylePropertySet* properties, StyleRule* = 0, unsigned linkMatchType = SelectorChecker::MatchAll, bool inRegionRule = false); + static void addMatchedProperties(MatchResult&, const StylePropertySet* properties, StyleRule* = 0, unsigned linkMatchType = SelectorChecker::MatchAll, bool inRegionRule = false); void addElementStyleProperties(MatchResult&, StylePropertySet*, bool isCacheable = true); void matchAllRules(MatchResult&, bool includeSMILProperties); diff --git a/Source/WebCore/css/StyleRule.cpp b/Source/WebCore/css/StyleRule.cpp index 400f41b23..3387fc964 100644 --- a/Source/WebCore/css/StyleRule.cpp +++ b/Source/WebCore/css/StyleRule.cpp @@ -180,6 +180,13 @@ StyleRule::~StyleRule() { } +StylePropertySet* StyleRule::mutableProperties() +{ + if (!m_properties->isMutable()) + m_properties = m_properties->copy(); + return m_properties.get(); +} + void StyleRule::setProperties(PassRefPtr<StylePropertySet> properties) { m_properties = properties; @@ -201,6 +208,13 @@ StyleRulePage::~StyleRulePage() { } +StylePropertySet* StyleRulePage::mutableProperties() +{ + if (!m_properties->isMutable()) + m_properties = m_properties->copy(); + return m_properties.get(); +} + void StyleRulePage::setProperties(PassRefPtr<StylePropertySet> properties) { m_properties = properties; @@ -221,6 +235,13 @@ StyleRuleFontFace::~StyleRuleFontFace() { } +StylePropertySet* StyleRuleFontFace::mutableProperties() +{ + if (!m_properties->isMutable()) + m_properties = m_properties->copy(); + return m_properties.get(); +} + void StyleRuleFontFace::setProperties(PassRefPtr<StylePropertySet> properties) { m_properties = properties; diff --git a/Source/WebCore/css/StyleRule.h b/Source/WebCore/css/StyleRule.h index f3989e0b2..c7be54902 100644 --- a/Source/WebCore/css/StyleRule.h +++ b/Source/WebCore/css/StyleRule.h @@ -94,7 +94,8 @@ public: ~StyleRule(); const CSSSelectorList& selectorList() const { return m_selectorList; } - StylePropertySet* properties() const { return m_properties.get(); } + const StylePropertySet* properties() const { return m_properties.get(); } + StylePropertySet* mutableProperties(); void parserAdoptSelectorVector(Vector<OwnPtr<CSSParserSelector> >& selectors) { m_selectorList.adoptSelectorVector(selectors); } void wrapperAdoptSelectorList(CSSSelectorList& selectors) { m_selectorList.adopt(selectors); } @@ -118,7 +119,8 @@ public: ~StyleRuleFontFace(); - StylePropertySet* properties() const { return m_properties.get(); } + const StylePropertySet* properties() const { return m_properties.get(); } + StylePropertySet* mutableProperties(); void setProperties(PassRefPtr<StylePropertySet>); @@ -138,7 +140,8 @@ public: ~StyleRulePage(); const CSSSelector* selector() const { return m_selectorList.first(); } - StylePropertySet* properties() const { return m_properties.get(); } + const StylePropertySet* properties() const { return m_properties.get(); } + StylePropertySet* mutableProperties(); void parserAdoptSelectorVector(Vector<OwnPtr<CSSParserSelector> >& selectors) { m_selectorList.adoptSelectorVector(selectors); } void wrapperAdoptSelectorList(CSSSelectorList& selectors) { m_selectorList.adopt(selectors); } diff --git a/Source/WebCore/css/WebKitCSSTransformValue.cpp b/Source/WebCore/css/WebKitCSSTransformValue.cpp index dfdd71e36..f85319015 100644 --- a/Source/WebCore/css/WebKitCSSTransformValue.cpp +++ b/Source/WebCore/css/WebKitCSSTransformValue.cpp @@ -29,9 +29,36 @@ #include "CSSValueList.h" #include "PlatformString.h" #include <wtf/PassRefPtr.h> +#include <wtf/text/StringBuilder.h> namespace WebCore { +// These names must be kept in sync with TransformOperationType. +const char* const transformName[] = { + 0, + "translate", + "translateX", + "translateY", + "rotate", + "scale", + "scaleX", + "scaleY", + "skew", + "skewX", + "skewY", + "matrix", + "translateZ", + "translate3d", + "rotateX", + "rotateY", + "rotateZ", + "rotate3d", + "scaleZ", + "scale3d", + "perspective", + "matrix3d" +}; + WebKitCSSTransformValue::WebKitCSSTransformValue(TransformOperationType op) : CSSValueList(WebKitCSSTransformClass, CommaSeparator) , m_type(op) @@ -40,79 +67,15 @@ WebKitCSSTransformValue::WebKitCSSTransformValue(TransformOperationType op) String WebKitCSSTransformValue::customCssText() const { - String result; - switch (m_type) { - case TranslateTransformOperation: - result += "translate("; - break; - case TranslateXTransformOperation: - result += "translateX("; - break; - case TranslateYTransformOperation: - result += "translateY("; - break; - case RotateTransformOperation: - result += "rotate("; - break; - case ScaleTransformOperation: - result += "scale("; - break; - case ScaleXTransformOperation: - result += "scaleX("; - break; - case ScaleYTransformOperation: - result += "scaleY("; - break; - case SkewTransformOperation: - result += "skew("; - break; - case SkewXTransformOperation: - result += "skewX("; - break; - case SkewYTransformOperation: - result += "skewY("; - break; - case MatrixTransformOperation: - result += "matrix("; - break; - case TranslateZTransformOperation: - result += "translateZ("; - break; - case Translate3DTransformOperation: - result += "translate3d("; - break; - case RotateXTransformOperation: - result += "rotateX("; - break; - case RotateYTransformOperation: - result += "rotateY("; - break; - case RotateZTransformOperation: - result += "rotateZ("; - break; - case Rotate3DTransformOperation: - result += "rotate3d("; - break; - case ScaleZTransformOperation: - result += "scaleZ("; - break; - case Scale3DTransformOperation: - result += "scale3d("; - break; - case PerspectiveTransformOperation: - result += "perspective("; - break; - case Matrix3DTransformOperation: - result += "matrix3d("; - break; - default: - break; + StringBuilder result; + if (m_type != UnknownTransformOperation) { + ASSERT(static_cast<size_t>(m_type) < WTF_ARRAY_LENGTH(transformName)); + result.append(transformName[m_type]); + result.append('('); + result.append(CSSValueList::customCssText()); + result.append(')'); } - - result += CSSValueList::customCssText(); - - result += ")"; - return result; + return result.toString(); } WebKitCSSTransformValue::WebKitCSSTransformValue(const WebKitCSSTransformValue& cloneFrom) diff --git a/Source/WebCore/css/mathml.css b/Source/WebCore/css/mathml.css index cf178e3cf..a96e3fa4b 100644 --- a/Source/WebCore/css/mathml.css +++ b/Source/WebCore/css/mathml.css @@ -170,7 +170,7 @@ mroot > * + mrow, mroot > * + mfenced { /* FIXME: eliminate */ mtable { display: inline-table; text-align: center; - vertical-align: -40%; + vertical-align: middle; } mtr { |