diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-11 09:43:24 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-11 09:43:24 +0200 |
commit | 1b914638db989aaa98631a1c1e02c7b2d44805d8 (patch) | |
tree | 87f4fd2c7b38db320079a5de8877890d2ca3c485 /Source/WebCore/css | |
parent | 2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (diff) | |
download | qtwebkit-1b914638db989aaa98631a1c1e02c7b2d44805d8.tar.gz |
Imported WebKit commit 9a52e27980f47e8b0d8f8b7cc0fd7b5741bceb92 (http://svn.webkit.org/repository/webkit/trunk@116736)
New snapshot to include QDeclarative* -> QQml* build fixes
Diffstat (limited to 'Source/WebCore/css')
35 files changed, 492 insertions, 181 deletions
diff --git a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp index 3ffb7ff5c..ec20807bf 100644 --- a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp +++ b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp @@ -157,6 +157,7 @@ static const CSSPropertyID computedProperties[] = { CSSPropertyRight, CSSPropertySpeak, CSSPropertyTableLayout, + CSSPropertyTabSize, CSSPropertyTextAlign, CSSPropertyTextDecoration, CSSPropertyTextIndent, @@ -1591,6 +1592,8 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert if (style->hasAutoColumnWidth()) return cssValuePool().createIdentifierValue(CSSValueAuto); return zoomAdjustedPixelValue(style->columnWidth(), style.get()); + case CSSPropertyTabSize: + return cssValuePool().createValue(style->tabSize(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitRegionBreakAfter: return cssValuePool().createValue(style->regionBreakAfter()); case CSSPropertyWebkitRegionBreakBefore: @@ -2343,12 +2346,8 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert case CSSPropertyWebkitFilter: return valueForFilter(style.get()); #endif - case CSSPropertyBackground: { - const CSSPropertyID properties[5] = { CSSPropertyBackgroundColor, CSSPropertyBackgroundImage, - CSSPropertyBackgroundRepeat, CSSPropertyBackgroundAttachment, - CSSPropertyBackgroundPosition }; - return getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(properties, WTF_ARRAY_LENGTH(properties))); - } + case CSSPropertyBackground: + return getBackgroundShorthandValue(); case CSSPropertyBorder: { RefPtr<CSSValue> value = getPropertyCSSValue(CSSPropertyBorderTop, DoNotUpdateLayout); const CSSPropertyID properties[3] = { CSSPropertyBorderRight, CSSPropertyBorderBottom, @@ -2695,4 +2694,17 @@ void CSSComputedStyleDeclaration::setPropertyInternal(CSSPropertyID, const Strin ec = NO_MODIFICATION_ALLOWED_ERR; } +PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getBackgroundShorthandValue() const +{ + // CSSPropertyBackgroundPosition should be at the end of the array so that CSSPropertyBackgroundSize can be appended followed by '/'. + static const CSSPropertyID properties[5] = { CSSPropertyBackgroundColor, CSSPropertyBackgroundImage, + CSSPropertyBackgroundRepeat, CSSPropertyBackgroundAttachment, + CSSPropertyBackgroundPosition }; + + RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated(); + list->append(getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(properties, WTF_ARRAY_LENGTH(properties)))); + list->append(getPropertyCSSValue(CSSPropertyBackgroundSize, DoNotUpdateLayout)); + return list.release(); +} + } // namespace WebCore diff --git a/Source/WebCore/css/CSSComputedStyleDeclaration.h b/Source/WebCore/css/CSSComputedStyleDeclaration.h index dcacca87c..a236a7d21 100644 --- a/Source/WebCore/css/CSSComputedStyleDeclaration.h +++ b/Source/WebCore/css/CSSComputedStyleDeclaration.h @@ -111,6 +111,7 @@ private: PassRefPtr<CSSValueList> getCSSPropertyValuesForShorthandProperties(const StylePropertyShorthand&) const; PassRefPtr<CSSValueList> getCSSPropertyValuesForSidesShorthand(const StylePropertyShorthand&) const; + PassRefPtr<CSSValueList> getBackgroundShorthandValue() const; RefPtr<Node> m_node; PseudoId m_pseudoElementSpecifier; diff --git a/Source/WebCore/css/CSSFontFaceRule.cpp b/Source/WebCore/css/CSSFontFaceRule.cpp index 7b611bb56..8bb94db63 100644 --- a/Source/WebCore/css/CSSFontFaceRule.cpp +++ b/Source/WebCore/css/CSSFontFaceRule.cpp @@ -55,4 +55,12 @@ String CSSFontFaceRule::cssText() const return result; } +void CSSFontFaceRule::reattach(StyleRuleFontFace* rule) +{ + ASSERT(rule); + m_fontFaceRule = rule; + if (m_propertiesCSSOMWrapper) + m_propertiesCSSOMWrapper->reattach(m_fontFaceRule->properties()); +} + } // namespace WebCore diff --git a/Source/WebCore/css/CSSFontFaceRule.h b/Source/WebCore/css/CSSFontFaceRule.h index 222fc3133..6414c872c 100644 --- a/Source/WebCore/css/CSSFontFaceRule.h +++ b/Source/WebCore/css/CSSFontFaceRule.h @@ -43,6 +43,8 @@ public: String cssText() const; + void reattach(StyleRuleFontFace*); + private: CSSFontFaceRule(StyleRuleFontFace*, CSSStyleSheet* parent); diff --git a/Source/WebCore/css/CSSImageSetValue.cpp b/Source/WebCore/css/CSSImageSetValue.cpp index 7917e99a7..0f48d010a 100644 --- a/Source/WebCore/css/CSSImageSetValue.cpp +++ b/Source/WebCore/css/CSSImageSetValue.cpp @@ -106,8 +106,8 @@ StyleCachedImageSet* CSSImageSetValue::cachedImageSet(CachedResourceLoader* load // and any CSS transforms. https://bugs.webkit.org/show_bug.cgi?id=81698 ImageWithScale image = bestImageForScaleFactor(); ResourceRequest request(loader->document()->completeURL(image.imageURL)); - if (CachedImage* cachedImage = loader->requestImage(request)) { - m_imageSet = StyleCachedImageSet::create(cachedImage, image.scaleFactor, this); + if (CachedResourceHandle<CachedImage> cachedImage = loader->requestImage(request)) { + m_imageSet = StyleCachedImageSet::create(cachedImage.get(), image.scaleFactor, this); m_accessedBestFitImage = true; } } diff --git a/Source/WebCore/css/CSSImageValue.cpp b/Source/WebCore/css/CSSImageValue.cpp index db56bd428..61964630c 100644 --- a/Source/WebCore/css/CSSImageValue.cpp +++ b/Source/WebCore/css/CSSImageValue.cpp @@ -82,8 +82,8 @@ StyleCachedImage* CSSImageValue::cachedImage(CachedResourceLoader* loader, const m_accessedImage = true; ResourceRequest request(loader->document()->completeURL(url)); - if (CachedImage* cachedImage = loader->requestImage(request)) - m_image = StyleCachedImage::create(cachedImage); + if (CachedResourceHandle<CachedImage> cachedImage = loader->requestImage(request)) + m_image = StyleCachedImage::create(cachedImage.get()); } return (m_image && m_image->isCachedImage()) ? static_cast<StyleCachedImage*>(m_image.get()) : 0; diff --git a/Source/WebCore/css/CSSImportRule.cpp b/Source/WebCore/css/CSSImportRule.cpp index f9d14671b..d150fb935 100644 --- a/Source/WebCore/css/CSSImportRule.cpp +++ b/Source/WebCore/css/CSSImportRule.cpp @@ -22,6 +22,7 @@ #include "config.h" #include "CSSImportRule.h" +#include "CSSStyleSheet.h" #include "CachedCSSStyleSheet.h" #include "CachedResourceLoader.h" #include "Document.h" diff --git a/Source/WebCore/css/CSSMediaRule.cpp b/Source/WebCore/css/CSSMediaRule.cpp index a6ee351f7..e09904209 100644 --- a/Source/WebCore/css/CSSMediaRule.cpp +++ b/Source/WebCore/css/CSSMediaRule.cpp @@ -25,6 +25,7 @@ #include "CSSParser.h" #include "CSSRuleList.h" +#include "CSSStyleSheet.h" #include "ExceptionCode.h" #include "StyleRule.h" #include <wtf/text/StringBuilder.h> @@ -80,13 +81,11 @@ unsigned CSSMediaRule::insertRule(const String& ruleString, unsigned index, Exce ec = HIERARCHY_REQUEST_ERR; return 0; } + CSSStyleSheet::RuleMutationScope mutationScope(this); + m_mediaRule->wrapperInsertRule(index, newRule); m_childRuleCSSOMWrappers.insert(index, RefPtr<CSSRule>()); - - if (CSSStyleSheet* styleSheet = parentStyleSheet()) - styleSheet->styleSheetChanged(); - return index; } @@ -100,14 +99,14 @@ void CSSMediaRule::deleteRule(unsigned index, ExceptionCode& ec) ec = INDEX_SIZE_ERR; return; } + + CSSStyleSheet::RuleMutationScope mutationScope(this); + m_mediaRule->wrapperRemoveRule(index); if (m_childRuleCSSOMWrappers[index]) m_childRuleCSSOMWrappers[index]->setParentRule(0); m_childRuleCSSOMWrappers.remove(index); - - if (CSSStyleSheet* styleSheet = parentStyleSheet()) - styleSheet->styleSheetChanged(); } String CSSMediaRule::cssText() const @@ -163,4 +162,16 @@ CSSRuleList* CSSMediaRule::cssRules() const return m_ruleListCSSOMWrapper.get(); } +void CSSMediaRule::reattach(StyleRuleMedia* rule) +{ + ASSERT(rule); + m_mediaRule = rule; + if (m_mediaCSSOMWrapper) + m_mediaCSSOMWrapper->reattach(m_mediaRule->mediaQueries()); + for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) { + if (m_childRuleCSSOMWrappers[i]) + m_childRuleCSSOMWrappers[i]->reattach(m_mediaRule->childRules()[i].get()); + } +} + } // namespace WebCore diff --git a/Source/WebCore/css/CSSMediaRule.h b/Source/WebCore/css/CSSMediaRule.h index 1aa544252..fda23cae2 100644 --- a/Source/WebCore/css/CSSMediaRule.h +++ b/Source/WebCore/css/CSSMediaRule.h @@ -50,6 +50,8 @@ public: unsigned length() const; CSSRule* item(unsigned index) const; + void reattach(StyleRuleMedia*); + private: CSSMediaRule(StyleRuleMedia*, CSSStyleSheet*); diff --git a/Source/WebCore/css/CSSPageRule.cpp b/Source/WebCore/css/CSSPageRule.cpp index 88a089954..70bbab7ba 100644 --- a/Source/WebCore/css/CSSPageRule.cpp +++ b/Source/WebCore/css/CSSPageRule.cpp @@ -24,6 +24,7 @@ #include "CSSParser.h" #include "CSSSelector.h" +#include "CSSStyleSheet.h" #include "Document.h" #include "PropertySetCSSStyleDeclaration.h" #include "StylePropertySet.h" @@ -65,24 +66,16 @@ String CSSPageRule::selectorText() const void CSSPageRule::setSelectorText(const String& selectorText) { - Document* doc = 0; - if (CSSStyleSheet* styleSheet = parentStyleSheet()) - doc = styleSheet->ownerDocument(); - if (!doc) - return; - CSSParser parser(parserContext()); CSSSelectorList selectorList; parser.parseSelector(selectorText, selectorList); if (!selectorList.first()) return; - + + CSSStyleSheet::RuleMutationScope mutationScope(this); + String oldSelectorText = this->selectorText(); m_pageRule->wrapperAdoptSelectorList(selectorList); - - if (this->selectorText() == oldSelectorText) - return; - doc->styleResolverChanged(DeferRecalcStyle); } String CSSPageRule::cssText() const @@ -94,4 +87,12 @@ String CSSPageRule::cssText() const return result; } +void CSSPageRule::reattach(StyleRulePage* rule) +{ + ASSERT(rule); + m_pageRule = rule; + if (m_propertiesCSSOMWrapper) + m_propertiesCSSOMWrapper->reattach(m_pageRule->properties()); +} + } // namespace WebCore diff --git a/Source/WebCore/css/CSSPageRule.h b/Source/WebCore/css/CSSPageRule.h index 69a578d75..163900cd1 100644 --- a/Source/WebCore/css/CSSPageRule.h +++ b/Source/WebCore/css/CSSPageRule.h @@ -45,7 +45,9 @@ public: void setSelectorText(const String&); String cssText() const; - + + void reattach(StyleRulePage*); + private: CSSPageRule(StyleRulePage*, CSSStyleSheet*); diff --git a/Source/WebCore/css/CSSParser.cpp b/Source/WebCore/css/CSSParser.cpp index 3eef56cf6..6941c126d 100644 --- a/Source/WebCore/css/CSSParser.cpp +++ b/Source/WebCore/css/CSSParser.cpp @@ -439,63 +439,46 @@ static inline bool isSimpleLengthPropertyID(CSSPropertyID propertyId, bool& acce } } +template <typename CharType> +static inline bool parseSimpleLength(const CharType* characters, unsigned& length, CSSPrimitiveValue::UnitTypes& unit, double& number) +{ + if (length > 2 && (characters[length - 2] | 0x20) == 'p' && (characters[length - 1] | 0x20) == 'x') { + length -= 2; + unit = CSSPrimitiveValue::CSS_PX; + } else if (length > 1 && characters[length - 1] == '%') { + length -= 1; + unit = CSSPrimitiveValue::CSS_PERCENTAGE; + } + + // We rely on charactersToDouble for validation as well. The function + // will set "ok" to "false" if the entire passed-in character range does + // not represent a double. + bool ok; + number = charactersToDouble(characters, length, &ok); + return ok; +} + static bool parseSimpleLengthValue(StylePropertySet* declaration, CSSPropertyID propertyId, const String& string, bool important, CSSParserMode cssParserMode) { ASSERT(!string.isEmpty()); bool acceptsNegativeNumbers; - bool strict = isStrictParserMode(cssParserMode); - unsigned length = string.length(); + if (!isSimpleLengthPropertyID(propertyId, acceptsNegativeNumbers)) + return false; + unsigned length = string.length(); double number; - bool ok; CSSPrimitiveValue::UnitTypes unit = CSSPrimitiveValue::CSS_NUMBER; if (string.is8Bit()) { - const LChar* characters8 = string.characters8(); - if (!characters8) - return false; - - if (!isSimpleLengthPropertyID(propertyId, acceptsNegativeNumbers)) + if (!parseSimpleLength(string.characters8(), length, unit, number)) return false; - - if (length > 2 && (characters8[length - 2] | 0x20) == 'p' && (characters8[length - 1] | 0x20) == 'x') { - length -= 2; - unit = CSSPrimitiveValue::CSS_PX; - } else if (length > 1 && characters8[length - 1] == '%') { - length -= 1; - unit = CSSPrimitiveValue::CSS_PERCENTAGE; - } - - // We rely on charactersToDouble for validation as well. The function - // will set "ok" to "false" if the entire passed-in character range does - // not represent a double. - number = charactersToDouble(characters8, length, &ok); } else { - const UChar* characters16 = string.characters16(); - if (!characters16) - return false; - - if (!isSimpleLengthPropertyID(propertyId, acceptsNegativeNumbers)) + if (!parseSimpleLength(string.characters16(), length, unit, number)) return false; - - if (length > 2 && (characters16[length - 2] | 0x20) == 'p' && (characters16[length - 1] | 0x20) == 'x') { - length -= 2; - unit = CSSPrimitiveValue::CSS_PX; - } else if (length > 1 && characters16[length - 1] == '%') { - length -= 1; - unit = CSSPrimitiveValue::CSS_PERCENTAGE; - } - - // We rely on charactersToDouble for validation as well. The function - // will set "ok" to "false" if the entire passed-in character range does - // not represent a double. - number = charactersToDouble(characters16, length, &ok); } - if (!ok) - return false; if (unit == CSSPrimitiveValue::CSS_NUMBER) { - if (number && strict) + if (number && isStrictParserMode(cssParserMode)) return false; unit = CSSPrimitiveValue::CSS_PX; } @@ -1990,6 +1973,9 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) addProperty(propId, val.release(), important); return true; } + case CSSPropertyTabSize: + validPrimitive = validUnit(value, FInteger | FNonNeg); + break; case CSSPropertyWebkitAspectRatio: return parseAspectRatio(important); case CSSPropertyBorderRadius: @@ -2307,11 +2293,10 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) case CSSPropertyBackground: { // Position must come before color in this array because a plain old "0" is a legal color // in quirks mode but it's usually the X coordinate of a position. - // FIXME: Add CSSPropertyBackgroundSize to the shorthand. const CSSPropertyID properties[] = { CSSPropertyBackgroundImage, CSSPropertyBackgroundRepeat, CSSPropertyBackgroundAttachment, CSSPropertyBackgroundPosition, CSSPropertyBackgroundOrigin, - CSSPropertyBackgroundClip, CSSPropertyBackgroundColor }; - return parseFillShorthand(propId, properties, 7, important); + CSSPropertyBackgroundClip, CSSPropertyBackgroundColor, CSSPropertyBackgroundSize }; + return parseFillShorthand(propId, properties, WTF_ARRAY_LENGTH(properties), important); } case CSSPropertyWebkitMask: { const CSSPropertyID properties[] = { CSSPropertyWebkitMaskImage, CSSPropertyWebkitMaskRepeat, @@ -2601,6 +2586,7 @@ bool CSSParser::parseFillShorthand(CSSPropertyID propId, const CSSPropertyID* pr RefPtr<CSSValue> repeatYValue; bool foundClip = false; int i; + bool foundBackgroundPositionCSSProperty = false; while (m_valueList->current()) { CSSParserValue* val = m_valueList->current(); @@ -2630,8 +2616,21 @@ bool CSSParser::parseFillShorthand(CSSPropertyID propId, const CSSPropertyID* pr break; } + bool backgroundSizeCSSPropertyExpected = false; + if ((val->unit == CSSParserValue::Operator && val->iValue == '/') && foundBackgroundPositionCSSProperty) { + backgroundSizeCSSPropertyExpected = true; + m_valueList->next(); + } + + foundBackgroundPositionCSSProperty = false; bool found = false; for (i = 0; !found && i < numProperties; ++i) { + + if (backgroundSizeCSSPropertyExpected && properties[i] != CSSPropertyBackgroundSize) + continue; + if (!backgroundSizeCSSPropertyExpected && properties[i] == CSSPropertyBackgroundSize) + continue; + if (!parsedProperty[i]) { RefPtr<CSSValue> val1; RefPtr<CSSValue> val2; @@ -2656,6 +2655,8 @@ bool CSSParser::parseFillShorthand(CSSPropertyID propId, const CSSPropertyID* pr addFillValue(clipValue, val1.release()); foundClip = true; } + if (properties[i] == CSSPropertyBackgroundPosition) + foundBackgroundPositionCSSProperty = true; } } } diff --git a/Source/WebCore/css/CSSProperty.cpp b/Source/WebCore/css/CSSProperty.cpp index ad8797aec..a00e774ad 100644 --- a/Source/WebCore/css/CSSProperty.cpp +++ b/Source/WebCore/css/CSSProperty.cpp @@ -279,6 +279,7 @@ bool CSSProperty::isInheritedProperty(CSSPropertyID propertyID) case CSSPropertyQuotes: case CSSPropertyResize: case CSSPropertySpeak: + case CSSPropertyTabSize: case CSSPropertyTextAlign: case CSSPropertyTextDecoration: case CSSPropertyTextIndent: diff --git a/Source/WebCore/css/CSSPropertyNames.in b/Source/WebCore/css/CSSPropertyNames.in index aee5c06af..1a22f254d 100644 --- a/Source/WebCore/css/CSSPropertyNames.in +++ b/Source/WebCore/css/CSSPropertyNames.in @@ -150,6 +150,7 @@ size src speak table-layout +tab-size text-align text-decoration text-indent diff --git a/Source/WebCore/css/CSSRule.cpp b/Source/WebCore/css/CSSRule.cpp index 13ad50ad3..09643ea9e 100644 --- a/Source/WebCore/css/CSSRule.cpp +++ b/Source/WebCore/css/CSSRule.cpp @@ -28,11 +28,13 @@ #include "CSSMediaRule.h" #include "CSSPageRule.h" #include "CSSStyleRule.h" +#include "CSSStyleSheet.h" #include "CSSUnknownRule.h" #include "WebKitCSSKeyframeRule.h" #include "WebKitCSSKeyframesRule.h" #include "WebKitCSSRegionRule.h" #include "NotImplemented.h" +#include "StyleRule.h" namespace WebCore { @@ -113,4 +115,48 @@ void CSSRule::destroy() ASSERT_NOT_REACHED(); } +void CSSRule::reattach(StyleRuleBase* rule) +{ + switch (type()) { + case UNKNOWN_RULE: + return; + case STYLE_RULE: + static_cast<CSSStyleRule*>(this)->reattach(static_cast<StyleRule*>(rule)); + return; + case PAGE_RULE: + static_cast<CSSPageRule*>(this)->reattach(static_cast<StyleRulePage*>(rule)); + return; + case CHARSET_RULE: + ASSERT(!rule); + return; + case IMPORT_RULE: + // FIXME: Implement when enabling caching for stylesheets with import rules. + ASSERT_NOT_REACHED(); + return; + case MEDIA_RULE: + static_cast<CSSMediaRule*>(this)->reattach(static_cast<StyleRuleMedia*>(rule)); + return; + case FONT_FACE_RULE: + static_cast<CSSFontFaceRule*>(this)->reattach(static_cast<StyleRuleFontFace*>(rule)); + return; + case WEBKIT_KEYFRAMES_RULE: + static_cast<WebKitCSSKeyframesRule*>(this)->reattach(static_cast<StyleRuleKeyframes*>(rule)); + return; + case WEBKIT_KEYFRAME_RULE: + // No need to reattach, the underlying data is shareable on mutation. + ASSERT_NOT_REACHED(); + return; + case WEBKIT_REGION_RULE: + static_cast<WebKitCSSRegionRule*>(this)->reattach(static_cast<StyleRuleRegion*>(rule)); + return; + } + ASSERT_NOT_REACHED(); +} + +const CSSParserContext& CSSRule::parserContext() const +{ + CSSStyleSheet* styleSheet = parentStyleSheet(); + return styleSheet ? styleSheet->internal()->parserContext() : strictCSSParserContext(); +} + } // namespace WebCore diff --git a/Source/WebCore/css/CSSRule.h b/Source/WebCore/css/CSSRule.h index 5a50645aa..5ec2f7aa8 100644 --- a/Source/WebCore/css/CSSRule.h +++ b/Source/WebCore/css/CSSRule.h @@ -23,12 +23,15 @@ #ifndef CSSRule_h #define CSSRule_h -#include "CSSStyleSheet.h" #include "KURLHash.h" #include <wtf/ListHashSet.h> +#include <wtf/RefCounted.h> namespace WebCore { +class CSSStyleSheet; +class StyleRuleBase; +struct CSSParserContext; typedef int ExceptionCode; class CSSRule : public RefCounted<CSSRule> { @@ -93,6 +96,8 @@ public: String cssText() const; void setCssText(const String&, ExceptionCode&); + void reattach(StyleRuleBase*); + protected: CSSRule(CSSStyleSheet* parent, Type type) : m_hasCachedSelectorText(false) @@ -110,11 +115,7 @@ protected: bool hasCachedSelectorText() const { return m_hasCachedSelectorText; } void setHasCachedSelectorText(bool hasCachedSelectorText) const { m_hasCachedSelectorText = hasCachedSelectorText; } - const CSSParserContext& parserContext() const - { - CSSStyleSheet* styleSheet = parentStyleSheet(); - return styleSheet ? styleSheet->internal()->parserContext() : strictCSSParserContext(); - } + const CSSParserContext& parserContext() const; private: mutable unsigned m_hasCachedSelectorText : 1; diff --git a/Source/WebCore/css/CSSStyleRule.cpp b/Source/WebCore/css/CSSStyleRule.cpp index 7357fcf22..5a780264a 100644 --- a/Source/WebCore/css/CSSStyleRule.cpp +++ b/Source/WebCore/css/CSSStyleRule.cpp @@ -91,18 +91,14 @@ String CSSStyleRule::selectorText() const void CSSStyleRule::setSelectorText(const String& selectorText) { - Document* doc = 0; - if (CSSStyleSheet* styleSheet = parentStyleSheet()) - doc = styleSheet->ownerDocument(); - if (!doc) - return; - CSSParser p(parserContext()); CSSSelectorList selectorList; p.parseSelector(selectorText, selectorList); if (!selectorList.first()) return; + CSSStyleSheet::RuleMutationScope mutationScope(this); + String oldSelectorText = this->selectorText(); m_styleRule->wrapperAdoptSelectorList(selectorList); @@ -110,8 +106,6 @@ void CSSStyleRule::setSelectorText(const String& selectorText) ASSERT(selectorTextCache().contains(this)); selectorTextCache().set(this, generateSelectorText()); } - - doc->styleResolverChanged(DeferRecalcStyle); } String CSSStyleRule::cssText() const @@ -125,4 +119,11 @@ String CSSStyleRule::cssText() const return result; } +void CSSStyleRule::reattach(StyleRule* rule) +{ + m_styleRule = rule; + if (m_propertiesCSSOMWrapper) + m_propertiesCSSOMWrapper->reattach(m_styleRule->properties()); +} + } // namespace WebCore diff --git a/Source/WebCore/css/CSSStyleRule.h b/Source/WebCore/css/CSSStyleRule.h index ae03b5887..d76a802fa 100644 --- a/Source/WebCore/css/CSSStyleRule.h +++ b/Source/WebCore/css/CSSStyleRule.h @@ -48,6 +48,8 @@ public: // FIXME: Not CSSOM. Remove. StyleRule* styleRule() const { return m_styleRule.get(); } + void reattach(StyleRule*); + private: CSSStyleRule(StyleRule*, CSSStyleSheet*); diff --git a/Source/WebCore/css/CSSStyleSheet.cpp b/Source/WebCore/css/CSSStyleSheet.cpp index 3852008db..329fc8d14 100644 --- a/Source/WebCore/css/CSSStyleSheet.cpp +++ b/Source/WebCore/css/CSSStyleSheet.cpp @@ -99,7 +99,8 @@ StyleSheetInternal::StyleSheetInternal(StyleRuleImport* ownerRule, const String& , m_hasSyntacticallyValidCSSHeader(true) , m_didLoadErrorOccur(false) , m_usesRemUnits(false) - , m_hasMutated(false) + , m_isMutable(false) + , m_isInMemoryCache(false) , m_parserContext(context) { } @@ -118,7 +119,8 @@ StyleSheetInternal::StyleSheetInternal(const StyleSheetInternal& o) , m_hasSyntacticallyValidCSSHeader(o.m_hasSyntacticallyValidCSSHeader) , m_didLoadErrorOccur(false) , m_usesRemUnits(o.m_usesRemUnits) - , m_hasMutated(false) + , m_isMutable(false) + , m_isInMemoryCache(false) , m_parserContext(o.m_parserContext) { ASSERT(o.isCacheable()); @@ -140,13 +142,16 @@ bool StyleSheetInternal::isCacheable() const // FIXME: Support copying import rules. if (!m_importRules.isEmpty()) return false; + // FIXME: Support cached stylesheets in import rules. + if (m_ownerRule) + return false; // This would require dealing with multiple clients for load callbacks. if (!m_loadCompleted) return false; if (m_didLoadErrorOccur) return false; // It is not the original sheet anymore. - if (m_hasMutated) + if (m_isMutable) return false; // If the header is valid we are not going to need to check the SecurityOrigin. // FIXME: Valid mime type avoids the check too. @@ -169,21 +174,21 @@ void StyleSheetInternal::parserAppendRule(PassRefPtr<StyleRuleBase> rule) m_childRules.append(rule); } -PassRefPtr<CSSRule> StyleSheetInternal::createChildRuleCSSOMWrapper(unsigned index, CSSStyleSheet* parentWrapper) +StyleRuleBase* StyleSheetInternal::ruleAt(unsigned index) const { ASSERT(index < ruleCount()); unsigned childVectorIndex = index; if (hasCharsetRule()) { if (index == 0) - return CSSCharsetRule::create(parentWrapper, m_encodingFromCharsetRule); + return 0; --childVectorIndex; } if (childVectorIndex < m_importRules.size()) - return m_importRules[childVectorIndex]->createCSSOMWrapper(parentWrapper); - + return m_importRules[childVectorIndex].get(); + childVectorIndex -= m_importRules.size(); - return m_childRules[childVectorIndex]->createCSSOMWrapper(parentWrapper); + return m_childRules[childVectorIndex].get(); } unsigned StyleSheetInternal::ruleCount() const @@ -220,6 +225,7 @@ void StyleSheetInternal::parserSetEncodingFromCharsetRule(const String& encoding bool StyleSheetInternal::wrapperInsertRule(PassRefPtr<StyleRuleBase> rule, unsigned index) { + ASSERT(m_isMutable); ASSERT(index <= ruleCount()); // Parser::parseRule doesn't currently allow @charset so we don't need to deal with it. ASSERT(!rule->isCharsetRule()); @@ -242,7 +248,6 @@ bool StyleSheetInternal::wrapperInsertRule(PassRefPtr<StyleRuleBase> rule, unsig m_importRules[childVectorIndex]->setParentStyleSheet(this); m_importRules[childVectorIndex]->requestStyleSheet(); // FIXME: Stylesheet doesn't actually change meaningfully before the imported sheets are loaded. - styleSheetChanged(); return true; } // Inserting @import rule after a non-import rule is not allowed. @@ -251,20 +256,18 @@ bool StyleSheetInternal::wrapperInsertRule(PassRefPtr<StyleRuleBase> rule, unsig childVectorIndex -= m_importRules.size(); m_childRules.insert(childVectorIndex, rule); - - styleSheetChanged(); return true; } void StyleSheetInternal::wrapperDeleteRule(unsigned index) { + ASSERT(m_isMutable); ASSERT(index < ruleCount()); unsigned childVectorIndex = index; if (hasCharsetRule()) { if (childVectorIndex == 0) { clearCharsetRule(); - styleSheetChanged(); return; } --childVectorIndex; @@ -272,13 +275,11 @@ void StyleSheetInternal::wrapperDeleteRule(unsigned index) if (childVectorIndex < m_importRules.size()) { m_importRules[childVectorIndex]->clearParentStyleSheet(); m_importRules.remove(childVectorIndex); - styleSheetChanged(); return; } childVectorIndex -= m_importRules.size(); m_childRules.remove(childVectorIndex); - styleSheetChanged(); } void StyleSheetInternal::parserAddNamespace(const AtomicString& prefix, const AtomicString& uri) @@ -415,16 +416,6 @@ Document* StyleSheetInternal::singleOwnerDocument() const return ownerNode ? ownerNode->document() : 0; } -void StyleSheetInternal::styleSheetChanged() -{ - m_hasMutated = true; - - Document* ownerDocument = singleOwnerDocument(); - if (!ownerDocument) - return; - ownerDocument->styleResolverChanged(DeferRecalcStyle); -} - KURL StyleSheetInternal::completeURL(const String& url) const { return CSSParser::completeURL(m_parserContext, url); @@ -473,6 +464,20 @@ void StyleSheetInternal::unregisterClient(CSSStyleSheet* sheet) m_clients.remove(position); } +void StyleSheetInternal::addedToMemoryCache() +{ + ASSERT(!m_isInMemoryCache); + ASSERT(isCacheable()); + m_isInMemoryCache = true; +} + +void StyleSheetInternal::removedFromMemoryCache() +{ + ASSERT(m_isInMemoryCache); + ASSERT(isCacheable()); + m_isInMemoryCache = false; +} + PassRefPtr<CSSStyleSheet> CSSStyleSheet::createInline(Node* ownerNode, const KURL& baseURL, const String& encoding) { CSSParserContext parserContext(ownerNode->document(), baseURL, encoding); @@ -514,14 +519,59 @@ CSSStyleSheet::~CSSStyleSheet() m_internal->unregisterClient(this); } +void CSSStyleSheet::willMutateRules() +{ + // If we are the only client it is safe to mutate. + if (m_internal->hasOneClient() && !m_internal->isInMemoryCache()) { + m_internal->setMutable(); + return; + } + // Only cacheable stylesheets should have multiple clients. + ASSERT(m_internal->isCacheable()); + + // Copy-on-write. + m_internal->unregisterClient(this); + m_internal = m_internal->copy(); + m_internal->registerClient(this); + + m_internal->setMutable(); + + // Any existing CSSOM wrappers need to be connected to the copied child rules. + reattachChildRuleCSSOMWrappers(); +} + +void CSSStyleSheet::didMutateRules() +{ + ASSERT(m_internal->isMutable()); + ASSERT(m_internal->hasOneClient()); + + didMutate(); +} + +void CSSStyleSheet::didMutate() +{ + Document* owner = ownerDocument(); + if (!owner) + return; + owner->styleResolverChanged(DeferRecalcStyle); +} + +void CSSStyleSheet::reattachChildRuleCSSOMWrappers() +{ + for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) { + if (!m_childRuleCSSOMWrappers[i]) + continue; + m_childRuleCSSOMWrappers[i]->reattach(m_internal->ruleAt(i)); + } +} + void CSSStyleSheet::setDisabled(bool disabled) { if (disabled == m_isDisabled) return; m_isDisabled = disabled; - Document* owner = ownerDocument(); - if (owner) - owner->styleResolverChanged(DeferRecalcStyle); + + didMutate(); } void CSSStyleSheet::setMediaQueries(PassRefPtr<MediaQuerySet> mediaQueries) @@ -545,8 +595,13 @@ CSSRule* CSSStyleSheet::item(unsigned index) ASSERT(m_childRuleCSSOMWrappers.size() == ruleCount); RefPtr<CSSRule>& cssRule = m_childRuleCSSOMWrappers[index]; - if (!cssRule) - cssRule = m_internal->createChildRuleCSSOMWrapper(index, this); + if (!cssRule) { + if (index == 0 && m_internal->hasCharsetRule()) { + ASSERT(!m_internal->ruleAt(0)); + cssRule = CSSCharsetRule::create(this, m_internal->encodingFromCharsetRule()); + } else + cssRule = m_internal->ruleAt(index)->createCSSOMWrapper(this); + } return cssRule.get(); } @@ -584,6 +639,8 @@ unsigned CSSStyleSheet::insertRule(const String& ruleString, unsigned index, Exc ec = SYNTAX_ERR; return 0; } + RuleMutationScope mutationScope(this); + bool success = m_internal->wrapperInsertRule(rule, index); if (!success) { ec = HIERARCHY_REQUEST_ERR; @@ -591,6 +648,7 @@ unsigned CSSStyleSheet::insertRule(const String& ruleString, unsigned index, Exc } if (!m_childRuleCSSOMWrappers.isEmpty()) m_childRuleCSSOMWrappers.insert(index, RefPtr<CSSRule>()); + return index; } @@ -603,6 +661,8 @@ void CSSStyleSheet::deleteRule(unsigned index, ExceptionCode& ec) ec = INDEX_SIZE_ERR; return; } + RuleMutationScope mutationScope(this); + m_internal->wrapperDeleteRule(index); if (!m_childRuleCSSOMWrappers.isEmpty()) { diff --git a/Source/WebCore/css/CSSStyleSheet.h b/Source/WebCore/css/CSSStyleSheet.h index 9bd30578b..425f675ba 100644 --- a/Source/WebCore/css/CSSStyleSheet.h +++ b/Source/WebCore/css/CSSStyleSheet.h @@ -22,8 +22,10 @@ #define CSSStyleSheet_h #include "CSSParserMode.h" +#include "CSSRule.h" #include "StyleSheet.h" #include <wtf/HashMap.h> +#include <wtf/Noncopyable.h> #include <wtf/text/AtomicStringHash.h> namespace WebCore { @@ -65,8 +67,6 @@ public: const AtomicString& determineNamespace(const AtomicString& prefix); - void styleSheetChanged(); - void parseAuthorStyleSheet(const CachedCSSStyleSheet*, const SecurityOrigin*); bool parseString(const String&); bool parseStringAtLine(const String&, int startLineNumber); @@ -101,6 +101,8 @@ public: void clearRules(); + bool hasCharsetRule() const { return !m_encodingFromCharsetRule.isNull(); } + String encodingFromCharsetRule() const { return m_encodingFromCharsetRule; } // Rules other than @charset and @import. const Vector<RefPtr<StyleRuleBase> >& childRules() const { return m_childRules; } const Vector<RefPtr<StyleRuleImport> >& importRules() const { return m_importRules; } @@ -120,7 +122,8 @@ public: const KURL& baseURL() const { return m_parserContext.baseURL; } unsigned ruleCount() const; - + StyleRuleBase* ruleAt(unsigned index) const; + bool usesRemUnits() const { return m_usesRemUnits; } unsigned estimatedSizeInBytes() const; @@ -128,19 +131,24 @@ public: bool wrapperInsertRule(PassRefPtr<StyleRuleBase>, unsigned index); void wrapperDeleteRule(unsigned index); - PassRefPtr<CSSRule> createChildRuleCSSOMWrapper(unsigned index, CSSStyleSheet* parentWrapper); - PassRefPtr<StyleSheetInternal> copy() const { return adoptRef(new StyleSheetInternal(*this)); } void registerClient(CSSStyleSheet*); void unregisterClient(CSSStyleSheet*); + bool hasOneClient() { return m_clients.size() == 1; } + + bool isMutable() const { return m_isMutable; } + void setMutable() { m_isMutable = true; } + + bool isInMemoryCache() const { return m_isInMemoryCache; } + void addedToMemoryCache(); + void removedFromMemoryCache(); private: StyleSheetInternal(StyleRuleImport* ownerRule, const String& originalURL, const KURL& baseURL, const CSSParserContext&); StyleSheetInternal(const StyleSheetInternal&); void clearCharsetRule(); - bool hasCharsetRule() const { return !m_encodingFromCharsetRule.isNull(); } StyleRuleImport* m_ownerRule; @@ -158,7 +166,8 @@ private: bool m_hasSyntacticallyValidCSSHeader : 1; bool m_didLoadErrorOccur : 1; bool m_usesRemUnits : 1; - bool m_hasMutated : 1; + bool m_isMutable : 1; + bool m_isInMemoryCache : 1; CSSParserContext m_parserContext; @@ -207,13 +216,28 @@ public: virtual bool isLoading() const OVERRIDE { return m_internal->isLoading(); } void clearOwnerRule() { m_ownerRule = 0; } - void styleSheetChanged() { m_internal->styleSheetChanged(); } Document* ownerDocument() const; MediaQuerySet* mediaQueries() const { return m_mediaQueries.get(); } void setMediaQueries(PassRefPtr<MediaQuerySet>); void setTitle(const String& title) { m_title = title; } + + class RuleMutationScope { + WTF_MAKE_NONCOPYABLE(RuleMutationScope); + public: + RuleMutationScope(CSSStyleSheet*); + RuleMutationScope(CSSRule*); + ~RuleMutationScope(); + + private: + CSSStyleSheet* m_styleSheet; + }; + + void willMutateRules(); + void didMutateRules(); + void didMutate(); void clearChildRuleCSSOMWrappers(); + void reattachChildRuleCSSOMWrappers(); StyleSheetInternal* internal() const { return m_internal.get(); } @@ -237,6 +261,26 @@ private: mutable OwnPtr<CSSRuleList> m_ruleListCSSOMWrapper; }; +inline CSSStyleSheet::RuleMutationScope::RuleMutationScope(CSSStyleSheet* sheet) + : m_styleSheet(sheet) +{ + if (m_styleSheet) + m_styleSheet->willMutateRules(); +} + +inline CSSStyleSheet::RuleMutationScope::RuleMutationScope(CSSRule* rule) + : m_styleSheet(rule ? rule->parentStyleSheet() : 0) +{ + if (m_styleSheet) + m_styleSheet->willMutateRules(); +} + +inline CSSStyleSheet::RuleMutationScope::~RuleMutationScope() +{ + if (m_styleSheet) + m_styleSheet->didMutateRules(); +} + } // namespace #endif diff --git a/Source/WebCore/css/MediaList.cpp b/Source/WebCore/css/MediaList.cpp index 57c6eaa1a..5fc793e31 100644 --- a/Source/WebCore/css/MediaList.cpp +++ b/Source/WebCore/css/MediaList.cpp @@ -230,12 +230,15 @@ MediaList::~MediaList() void MediaList::setMediaText(const String& value, ExceptionCode& ec) { + CSSStyleSheet::RuleMutationScope mutationScope(m_parentRule); + bool success = m_mediaQueries->parse(value); if (!success) { ec = SYNTAX_ERR; return; } - notifyChanged(); + if (m_parentStyleSheet) + m_parentStyleSheet->didMutate(); } String MediaList::item(unsigned index) const @@ -248,31 +251,35 @@ String MediaList::item(unsigned index) const void MediaList::deleteMedium(const String& medium, ExceptionCode& ec) { + CSSStyleSheet::RuleMutationScope mutationScope(m_parentRule); + bool success = m_mediaQueries->remove(medium); if (!success) { ec = NOT_FOUND_ERR; return; } - notifyChanged(); + if (m_parentStyleSheet) + m_parentStyleSheet->didMutate(); } void MediaList::appendMedium(const String& medium, ExceptionCode& ec) { + CSSStyleSheet::RuleMutationScope mutationScope(m_parentRule); + bool success = m_mediaQueries->add(medium); if (!success) { // FIXME: Should this really be INVALID_CHARACTER_ERR? ec = INVALID_CHARACTER_ERR; return; } - notifyChanged(); + if (m_parentStyleSheet) + m_parentStyleSheet->didMutate(); } -void MediaList::notifyChanged() +void MediaList::reattach(MediaQuerySet* mediaQueries) { - CSSStyleSheet* parentStyleSheet = m_parentRule ? m_parentRule->parentStyleSheet() : m_parentStyleSheet; - if (!parentStyleSheet) - return; - parentStyleSheet->styleSheetChanged(); + ASSERT(mediaQueries); + m_mediaQueries = mediaQueries; } } diff --git a/Source/WebCore/css/MediaList.h b/Source/WebCore/css/MediaList.h index 88bdca242..32d0ec37d 100644 --- a/Source/WebCore/css/MediaList.h +++ b/Source/WebCore/css/MediaList.h @@ -104,13 +104,13 @@ public: void clearParentRule() { ASSERT(m_parentRule); m_parentRule = 0; } const MediaQuerySet* queries() const { return m_mediaQueries.get(); } + void reattach(MediaQuerySet*); + private: MediaList(); MediaList(MediaQuerySet*, CSSStyleSheet* parentSheet); MediaList(MediaQuerySet*, CSSRule* parentRule); - void notifyChanged(); - RefPtr<MediaQuerySet> m_mediaQueries; CSSStyleSheet* m_parentStyleSheet; CSSRule* m_parentRule; diff --git a/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp b/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp index b3e6f1d93..33f21a10a 100644 --- a/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp +++ b/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp @@ -152,11 +152,14 @@ void PropertySetCSSStyleDeclaration::setCssText(const String& text, ExceptionCod #if ENABLE(MUTATION_OBSERVERS) StyleAttributeMutationScope mutationScope(this); #endif + willMutate(); + ec = 0; // FIXME: Detect syntax errors and set ec. m_propertySet->parseDeclaration(text, contextStyleSheet()); - didMutate(); + didMutate(PropertyChanged); + #if ENABLE(MUTATION_OBSERVERS) mutationScope.enqueueMutationRecord(); #endif @@ -213,13 +216,19 @@ void PropertySetCSSStyleDeclaration::setProperty(const String& propertyName, con CSSPropertyID propertyID = cssPropertyID(propertyName); if (!propertyID) return; + bool important = priority.find("important", 0, false) != notFound; + + willMutate(); + ec = 0; bool changed = m_propertySet->setProperty(propertyID, value, important, contextStyleSheet()); + + didMutate(changed ? PropertyChanged : NoChanges); + if (changed) { // CSS DOM requires raising SYNTAX_ERR of parsing failed, but this is too dangerous for compatibility, // see <http://bugs.webkit.org/show_bug.cgi?id=7296>. - didMutate(); #if ENABLE(MUTATION_OBSERVERS) mutationScope.enqueueMutationRecord(); #endif @@ -234,11 +243,16 @@ String PropertySetCSSStyleDeclaration::removeProperty(const String& propertyName CSSPropertyID propertyID = cssPropertyID(propertyName); if (!propertyID) return String(); + + willMutate(); + ec = 0; String result; - bool changes = m_propertySet->removeProperty(propertyID, &result); - if (changes) { - didMutate(); + bool changed = m_propertySet->removeProperty(propertyID, &result); + + didMutate(changed ? PropertyChanged : NoChanges); + + if (changed) { #if ENABLE(MUTATION_OBSERVERS) mutationScope.enqueueMutationRecord(); #endif @@ -261,22 +275,20 @@ void PropertySetCSSStyleDeclaration::setPropertyInternal(CSSPropertyID propertyI #if ENABLE(MUTATION_OBSERVERS) StyleAttributeMutationScope mutationScope(this); #endif + willMutate(); + ec = 0; bool changed = m_propertySet->setProperty(propertyID, value, important, contextStyleSheet()); + + didMutate(changed ? PropertyChanged : NoChanges); + if (changed) { - didMutate(); #if ENABLE(MUTATION_OBSERVERS) mutationScope.enqueueMutationRecord(); #endif } } -void PropertySetCSSStyleDeclaration::didMutate() -{ - m_cssomCSSValueClones.clear(); - setNeedsStyleRecalc(); -} - CSSValue* PropertySetCSSStyleDeclaration::cloneAndCacheForCSSOM(CSSValue* internalValue) { if (!internalValue) @@ -339,12 +351,20 @@ void StyleRuleCSSStyleDeclaration::deref() delete this; } -void StyleRuleCSSStyleDeclaration::setNeedsStyleRecalc() +void StyleRuleCSSStyleDeclaration::willMutate() { - if (CSSStyleSheet* styleSheet = parentStyleSheet()) { - if (Document* document = styleSheet->ownerDocument()) - document->styleResolverChanged(DeferRecalcStyle); - } + if (m_parentRule && m_parentRule->parentStyleSheet()) + m_parentRule->parentStyleSheet()->willMutateRules(); +} + +void StyleRuleCSSStyleDeclaration::didMutate(MutationType type) +{ + if (type == PropertyChanged) + m_cssomCSSValueClones.clear(); + + // Style sheet mutation needs to be signaled even if the change failed. willMutateRules/didMutateRules must pair. + if (m_parentRule && m_parentRule->parentStyleSheet()) + m_parentRule->parentStyleSheet()->didMutateRules(); } CSSStyleSheet* StyleRuleCSSStyleDeclaration::parentStyleSheet() const @@ -352,14 +372,26 @@ CSSStyleSheet* StyleRuleCSSStyleDeclaration::parentStyleSheet() const return m_parentRule ? m_parentRule->parentStyleSheet() : 0; } -void InlineCSSStyleDeclaration::setNeedsStyleRecalc() +void StyleRuleCSSStyleDeclaration::reattach(StylePropertySet* propertySet) +{ + ASSERT(propertySet); + m_propertySet->deref(); + m_propertySet = propertySet; + m_propertySet->ref(); +} + +void InlineCSSStyleDeclaration::didMutate(MutationType type) { + if (type == NoChanges) + return; + + m_cssomCSSValueClones.clear(); + if (!m_parentElement) return; m_parentElement->setNeedsStyleRecalc(InlineStyleChange); m_parentElement->invalidateStyleAttribute(); StyleAttributeMutationScope(this).didInvalidateStyleAttr(); - return; } CSSStyleSheet* InlineCSSStyleDeclaration::parentStyleSheet() const diff --git a/Source/WebCore/css/PropertySetCSSStyleDeclaration.h b/Source/WebCore/css/PropertySetCSSStyleDeclaration.h index 2b8f41295..bf9694c2d 100644 --- a/Source/WebCore/css/PropertySetCSSStyleDeclaration.h +++ b/Source/WebCore/css/PropertySetCSSStyleDeclaration.h @@ -68,12 +68,14 @@ private: virtual bool cssPropertyMatches(const CSSProperty*) const OVERRIDE; virtual PassRefPtr<StylePropertySet> copy() const OVERRIDE; virtual PassRefPtr<StylePropertySet> makeMutable() OVERRIDE; - virtual void setNeedsStyleRecalc() { } - - void didMutate(); + CSSValue* cloneAndCacheForCSSOM(CSSValue*); protected: + enum MutationType { NoChanges, PropertyChanged }; + virtual void willMutate() { } + virtual void didMutate(MutationType) { } + StylePropertySet* m_propertySet; OwnPtr<HashMap<CSSValue*, RefPtr<CSSValue> > > m_cssomCSSValueClones; }; @@ -91,6 +93,8 @@ public: virtual void ref() OVERRIDE; virtual void deref() OVERRIDE; + void reattach(StylePropertySet*); + private: StyleRuleCSSStyleDeclaration(StylePropertySet*, CSSRule*); virtual ~StyleRuleCSSStyleDeclaration(); @@ -98,8 +102,10 @@ private: virtual CSSStyleSheet* parentStyleSheet() const OVERRIDE; virtual CSSRule* parentRule() const OVERRIDE { return m_parentRule; } - virtual void setNeedsStyleRecalc() OVERRIDE; - + + virtual void willMutate() OVERRIDE; + virtual void didMutate(MutationType) OVERRIDE; + unsigned m_refCount; CSSRule* m_parentRule; }; @@ -117,7 +123,8 @@ private: virtual CSSStyleSheet* parentStyleSheet() const OVERRIDE; virtual StyledElement* parentElement() const OVERRIDE { return m_parentElement; } virtual void clearParentElement() OVERRIDE { m_parentElement = 0; } - virtual void setNeedsStyleRecalc() OVERRIDE; + + virtual void didMutate(MutationType) OVERRIDE; StyledElement* m_parentElement; }; diff --git a/Source/WebCore/css/StyleBuilder.cpp b/Source/WebCore/css/StyleBuilder.cpp index 6a5e1632a..7f6884cf9 100644 --- a/Source/WebCore/css/StyleBuilder.cpp +++ b/Source/WebCore/css/StyleBuilder.cpp @@ -1879,6 +1879,7 @@ StyleBuilder::StyleBuilder() setPropertyHandler(CSSPropertySize, ApplyPropertyPageSize::createHandler()); setPropertyHandler(CSSPropertySpeak, ApplyPropertyDefault<ESpeak, &RenderStyle::speak, ESpeak, &RenderStyle::setSpeak, ESpeak, &RenderStyle::initialSpeak>::createHandler()); setPropertyHandler(CSSPropertyTableLayout, ApplyPropertyDefault<ETableLayout, &RenderStyle::tableLayout, ETableLayout, &RenderStyle::setTableLayout, ETableLayout, &RenderStyle::initialTableLayout>::createHandler()); + setPropertyHandler(CSSPropertyTabSize, ApplyPropertyDefault<unsigned, &RenderStyle::tabSize, unsigned, &RenderStyle::setTabSize, unsigned, &RenderStyle::initialTabSize>::createHandler()); setPropertyHandler(CSSPropertyTextAlign, ApplyPropertyTextAlign::createHandler()); setPropertyHandler(CSSPropertyTextDecoration, ApplyPropertyTextDecoration::createHandler()); setPropertyHandler(CSSPropertyTextIndent, ApplyPropertyLength<&RenderStyle::textIndent, &RenderStyle::setTextIndent, &RenderStyle::initialTextIndent>::createHandler()); diff --git a/Source/WebCore/css/StylePropertySet.cpp b/Source/WebCore/css/StylePropertySet.cpp index a5c8806ba..caeda8896 100644 --- a/Source/WebCore/css/StylePropertySet.cpp +++ b/Source/WebCore/css/StylePropertySet.cpp @@ -23,6 +23,7 @@ #include "StylePropertySet.h" #include "CSSParser.h" +#include "CSSStyleSheet.h" #include "CSSValueKeywords.h" #include "CSSValueList.h" #include "CSSValuePool.h" @@ -308,6 +309,7 @@ String StylePropertySet::getLayeredShorthandValue(const StylePropertyShorthand& bool useRepeatXShorthand = false; bool useRepeatYShorthand = false; bool useSingleWordShorthand = false; + bool foundBackgroundPositionYCSSProperty = false; for (unsigned j = 0; j < size; j++) { RefPtr<CSSValue> value; if (values[j]) { @@ -359,6 +361,11 @@ String StylePropertySet::getLayeredShorthandValue(const StylePropertyShorthand& if (value && !value->isImplicitInitialValue()) { if (!layerRes.isNull()) layerRes += " "; + if (foundBackgroundPositionYCSSProperty && shorthand.properties()[j] == CSSPropertyBackgroundSize) + layerRes += "/ "; + if (!foundBackgroundPositionYCSSProperty && shorthand.properties()[j] == CSSPropertyBackgroundSize) + continue; + if (useRepeatXShorthand) { useRepeatXShorthand = false; layerRes += getValueName(CSSValueRepeatX); @@ -370,6 +377,9 @@ String StylePropertySet::getLayeredShorthandValue(const StylePropertyShorthand& layerRes += value->cssText(); } else layerRes += value->cssText(); + + if (shorthand.properties()[j] == CSSPropertyBackgroundPositionY) + foundBackgroundPositionYCSSProperty = true; } } diff --git a/Source/WebCore/css/StylePropertyShorthand.cpp b/Source/WebCore/css/StylePropertyShorthand.cpp index 1aae48d95..6bd0780d4 100644 --- a/Source/WebCore/css/StylePropertyShorthand.cpp +++ b/Source/WebCore/css/StylePropertyShorthand.cpp @@ -25,7 +25,6 @@ namespace WebCore { -// FIXME: Add CSSPropertyBackgroundSize to the shorthand. const StylePropertyShorthand& backgroundShorthand() { static const CSSPropertyID backgroundProperties[] = { @@ -34,10 +33,11 @@ const StylePropertyShorthand& backgroundShorthand() CSSPropertyBackgroundRepeatX, CSSPropertyBackgroundRepeatY, CSSPropertyBackgroundAttachment, + CSSPropertyBackgroundClip, + CSSPropertyBackgroundOrigin, CSSPropertyBackgroundPositionX, CSSPropertyBackgroundPositionY, - CSSPropertyBackgroundClip, - CSSPropertyBackgroundOrigin + CSSPropertyBackgroundSize }; DEFINE_STATIC_LOCAL(StylePropertyShorthand, backgroundShorthand, (backgroundProperties, WTF_ARRAY_LENGTH(backgroundProperties))); return backgroundShorthand; diff --git a/Source/WebCore/css/StyleResolver.cpp b/Source/WebCore/css/StyleResolver.cpp index 2d9933481..24a180f10 100644 --- a/Source/WebCore/css/StyleResolver.cpp +++ b/Source/WebCore/css/StyleResolver.cpp @@ -61,7 +61,7 @@ #include "FrameSelection.h" #include "FrameView.h" #include "HTMLDocument.h" -#include "HTMLElement.h" +#include "HTMLIFrameElement.h" #include "HTMLInputElement.h" #include "HTMLNames.h" #include "HTMLOptionElement.h" @@ -418,9 +418,25 @@ StyleResolver::StyleResolver(Document* document, bool matchAuthorAndUserStyles) } #endif + addStylesheetsFromSeamlessParents(); appendAuthorStylesheets(0, document->styleSheets()->vector()); } +void StyleResolver::addStylesheetsFromSeamlessParents() +{ + // Build a list of stylesheet lists from our ancestors, and walk that + // list in reverse order so that the root-most sheets are appended first. + Document* childDocument = document(); + Vector<StyleSheetList*> ancestorSheets; + while (HTMLIFrameElement* parentIFrame = childDocument->seamlessParentIFrame()) { + Document* parentDocument = parentIFrame->document(); + ancestorSheets.append(parentDocument->styleSheets()); + childDocument = parentDocument; + } + for (int i = ancestorSheets.size() - 1; i >= 0; i--) + appendAuthorStylesheets(0, ancestorSheets.at(i)->vector()); +} + void StyleResolver::addAuthorRulesAndCollectUserRulesFromSheets(const Vector<RefPtr<CSSStyleSheet> >* userSheets, RuleSet& userStyle) { if (!userSheets) @@ -467,14 +483,14 @@ void StyleResolver::collectFeatures() } #if ENABLE(STYLE_SCOPED) -const ContainerNode* StyleResolver::determineScope(const StyleSheetInternal* sheet) +const ContainerNode* StyleResolver::determineScope(const CSSStyleSheet* sheet) { ASSERT(sheet); if (!RuntimeEnabledFeatures::styleScopedEnabled()) return 0; - Node* ownerNode = sheet->singleOwnerNode(); + Node* ownerNode = sheet->ownerNode(); if (!ownerNode || !ownerNode->isHTMLElement() || !ownerNode->hasTagName(HTMLNames::styleTag)) return 0; @@ -513,7 +529,7 @@ void StyleResolver::appendAuthorStylesheets(unsigned firstNew, const Vector<RefP continue; StyleSheetInternal* sheet = cssSheet->internal(); #if ENABLE(STYLE_SCOPED) - const ContainerNode* scope = determineScope(sheet); + const ContainerNode* scope = determineScope(cssSheet); if (scope) { ScopedRuleSetMap::AddResult addResult = m_scopedAuthorStyles.add(scope, nullptr); if (addResult.isNewEntry) @@ -1022,7 +1038,7 @@ void StyleResolver::collectMatchingRulesForList(const Vector<RuleData>* rules, i // d) the rule contains shadow-ID pseudo elements TreeScope* treeScope = m_element->treeScope(); if (!MatchingUARulesScope::isMatchingUARules() - && !treeScope->applyAuthorSheets() + && !treeScope->applyAuthorStyles() #if ENABLE(STYLE_SCOPED) && (!options.scope || options.scope->treeScope() != treeScope) #endif @@ -1511,13 +1527,28 @@ PassRefPtr<RenderStyle> StyleResolver::styleForDocument(Document* document, CSSF { Frame* frame = document->frame(); + // HTML5 states that seamless iframes should replace default CSS values + // with values inherited from the containing iframe element. However, + // some values (such as the case of designMode = "on") still need to + // be set by this "document style". RefPtr<RenderStyle> documentStyle = RenderStyle::create(); + bool seamlessWithParent = document->shouldDisplaySeamlesslyWithParent(); + if (seamlessWithParent) { + RenderStyle* iframeStyle = document->seamlessParentIFrame()->renderStyle(); + if (iframeStyle) + documentStyle->inheritFrom(iframeStyle); + } + + // FIXME: It's not clear which values below we want to override in the seamless case! documentStyle->setDisplay(BLOCK); - documentStyle->setRTLOrdering(document->visuallyOrdered() ? VisualOrder : LogicalOrder); - documentStyle->setZoom(frame && !document->printing() ? frame->pageZoomFactor() : 1); - documentStyle->setPageScaleTransform(frame ? frame->frameScaleFactor() : 1); + if (!seamlessWithParent) { + documentStyle->setRTLOrdering(document->visuallyOrdered() ? VisualOrder : LogicalOrder); + documentStyle->setZoom(frame && !document->printing() ? frame->pageZoomFactor() : 1); + documentStyle->setPageScaleTransform(frame ? frame->frameScaleFactor() : 1); + documentStyle->setLocale(document->contentLanguage()); + } + // FIXME: This overrides any -webkit-user-modify inherited from the parent iframe. documentStyle->setUserModify(document->inDesignMode() ? READ_WRITE : READ_ONLY); - documentStyle->setLocale(document->contentLanguage()); Element* docElement = document->documentElement(); RenderObject* docElementRenderer = docElement ? docElement->renderer() : 0; @@ -1546,6 +1577,10 @@ PassRefPtr<RenderStyle> StyleResolver::styleForDocument(Document* document, CSSF } } + // Seamless iframes want to inherit their font from their parent iframe, so early return before setting the font. + if (seamlessWithParent) + return documentStyle.release(); + FontDescription fontDescription; fontDescription.setUsePrinterFont(document->printing()); fontDescription.setScript(localeToScriptCodeForFontSelection(documentStyle->locale())); diff --git a/Source/WebCore/css/StyleResolver.h b/Source/WebCore/css/StyleResolver.h index 3916a7323..2a261448d 100644 --- a/Source/WebCore/css/StyleResolver.h +++ b/Source/WebCore/css/StyleResolver.h @@ -401,6 +401,7 @@ public: private: static RenderStyle* s_styleNotYetAvailable; + void addStylesheetsFromSeamlessParents(); void addAuthorRulesAndCollectUserRulesFromSheets(const Vector<RefPtr<CSSStyleSheet> >*, RuleSet& userStyle); void cacheBorderAndBackground(); @@ -505,7 +506,7 @@ private: #endif #if ENABLE(STYLE_SCOPED) - static const ContainerNode* determineScope(const StyleSheetInternal*); + static const ContainerNode* determineScope(const CSSStyleSheet*); typedef HashMap<const ContainerNode*, OwnPtr<RuleSet> > ScopedRuleSetMap; diff --git a/Source/WebCore/css/WebKitCSSKeyframesRule.cpp b/Source/WebCore/css/WebKitCSSKeyframesRule.cpp index cbf97d5fa..dcd79034f 100644 --- a/Source/WebCore/css/WebKitCSSKeyframesRule.cpp +++ b/Source/WebCore/css/WebKitCSSKeyframesRule.cpp @@ -28,6 +28,7 @@ #include "CSSParser.h" #include "CSSRuleList.h" +#include "CSSStyleSheet.h" #include "StylePropertySet.h" #include "StyleSheet.h" #include "WebKitCSSKeyframeRule.h" @@ -104,12 +105,9 @@ WebKitCSSKeyframesRule::~WebKitCSSKeyframesRule() void WebKitCSSKeyframesRule::setName(const String& name) { - m_keyframesRule->setName(name); + CSSStyleSheet::RuleMutationScope mutationScope(this); - // Since the name is used in the keyframe map list in StyleResolver, we need - // to recompute the style sheet to get the updated name. - if (CSSStyleSheet* styleSheet = parentStyleSheet()) - styleSheet->styleSheetChanged(); + m_keyframesRule->setName(name); } void WebKitCSSKeyframesRule::insertRule(const String& ruleText) @@ -122,6 +120,8 @@ void WebKitCSSKeyframesRule::insertRule(const String& ruleText) if (!keyframe) return; + CSSStyleSheet::RuleMutationScope mutationScope(this); + m_keyframesRule->wrapperAppendKeyframe(keyframe); m_childRuleCSSOMWrappers.grow(length()); @@ -135,6 +135,8 @@ void WebKitCSSKeyframesRule::deleteRule(const String& s) if (i < 0) return; + CSSStyleSheet::RuleMutationScope mutationScope(this); + m_keyframesRule->wrapperRemoveKeyframe(i); if (m_childRuleCSSOMWrappers[i]) @@ -190,4 +192,10 @@ CSSRuleList* WebKitCSSKeyframesRule::cssRules() return m_ruleListCSSOMWrapper.get(); } +void WebKitCSSKeyframesRule::reattach(StyleRuleKeyframes* rule) +{ + ASSERT(rule); + m_keyframesRule = rule; +} + } // namespace WebCore diff --git a/Source/WebCore/css/WebKitCSSKeyframesRule.h b/Source/WebCore/css/WebKitCSSKeyframesRule.h index 81abf879a..2f9365c80 100644 --- a/Source/WebCore/css/WebKitCSSKeyframesRule.h +++ b/Source/WebCore/css/WebKitCSSKeyframesRule.h @@ -87,6 +87,8 @@ public: unsigned length() const; WebKitCSSKeyframeRule* item(unsigned index) const; + void reattach(StyleRuleKeyframes*); + private: WebKitCSSKeyframesRule(StyleRuleKeyframes*, CSSStyleSheet* parent); diff --git a/Source/WebCore/css/WebKitCSSRegionRule.cpp b/Source/WebCore/css/WebKitCSSRegionRule.cpp index df1c9b079..677a9f81c 100644 --- a/Source/WebCore/css/WebKitCSSRegionRule.cpp +++ b/Source/WebCore/css/WebKitCSSRegionRule.cpp @@ -96,5 +96,14 @@ CSSRuleList* WebKitCSSRegionRule::cssRules() const return m_ruleListCSSOMWrapper.get(); } +void WebKitCSSRegionRule::reattach(StyleRuleRegion* rule) +{ + ASSERT(rule); + m_regionRule = rule; + for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) { + if (m_childRuleCSSOMWrappers[i]) + m_childRuleCSSOMWrappers[i]->reattach(m_regionRule->childRules()[i].get()); + } +} } // namespace WebCore diff --git a/Source/WebCore/css/WebKitCSSRegionRule.h b/Source/WebCore/css/WebKitCSSRegionRule.h index ff5762384..1987ef2ca 100644 --- a/Source/WebCore/css/WebKitCSSRegionRule.h +++ b/Source/WebCore/css/WebKitCSSRegionRule.h @@ -53,6 +53,8 @@ public: unsigned length() const; CSSRule* item(unsigned index) const; + void reattach(StyleRuleRegion*); + private: WebKitCSSRegionRule(StyleRuleRegion*, CSSStyleSheet* parent); diff --git a/Source/WebCore/css/WebKitCSSShaderValue.cpp b/Source/WebCore/css/WebKitCSSShaderValue.cpp index 698f170bc..8651758ed 100644 --- a/Source/WebCore/css/WebKitCSSShaderValue.cpp +++ b/Source/WebCore/css/WebKitCSSShaderValue.cpp @@ -59,8 +59,8 @@ StyleCachedShader* WebKitCSSShaderValue::cachedShader(CachedResourceLoader* load m_accessedShader = true; ResourceRequest request(loader->document()->completeURL(m_url)); - if (CachedShader* cachedShader = loader->requestShader(request)) - m_shader = StyleCachedShader::create(cachedShader); + if (CachedResourceHandle<CachedShader> cachedShader = loader->requestShader(request)) + m_shader = StyleCachedShader::create(cachedShader.get()); } return (m_shader && m_shader->isCachedShader()) ? static_cast<StyleCachedShader*>(m_shader.get()) : 0; diff --git a/Source/WebCore/css/mediaControlsEfl.css b/Source/WebCore/css/mediaControlsEfl.css index 3a5a95441..55f58d994 100644 --- a/Source/WebCore/css/mediaControlsEfl.css +++ b/Source/WebCore/css/mediaControlsEfl.css @@ -35,7 +35,7 @@ audio::-webkit-media-controls-panel, video::-webkit-media-controls-panel { -webkit-box-orient: horizontal; -webkit-box-align: center; -webkit-user-select: none; - position: absolute; + position: relative; bottom: 0; width: 100%; z-index: 0; |