[CSSRegions]Add back region style code removed in r104036
authormihnea@adobe.com <mihnea@adobe.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 Jan 2012 19:42:53 +0000 (19:42 +0000)
committermihnea@adobe.com <mihnea@adobe.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 Jan 2012 19:42:53 +0000 (19:42 +0000)
https://bugs.webkit.org/show_bug.cgi?id=76064

Reviewed by David Hyatt.

No new tests. The region style tests are still skipped. A follow up patch will enable
both region style for background-color and region style tests.

* WebCore.exp.in:
* css/CSSStyleSelector.cpp:
(WebCore::RuleData::useInRegionStyle):
(WebCore::CSSStyleSelector::CSSStyleSelector):
(WebCore::CSSStyleSelector::addMatchedDeclaration):
(WebCore::CSSStyleSelector::matchRules):
(WebCore::CSSStyleSelector::matchAllRules):
(WebCore::CSSStyleSelector::initForRegionStyling):
(WebCore::CSSStyleSelector::initRegionRules):
(WebCore::CSSStyleSelector::styleForElement):
(WebCore::CSSStyleSelector::pseudoStyleForElement):
(WebCore::RuleData::RuleData):
(WebCore::RuleSet::RuleSet):
(WebCore::RuleSet::addToRuleSet):
(WebCore::CSSStyleSelector::applyDeclarations):
(WebCore::isValidRegionStyleProperty):
(WebCore::CSSStyleSelector::applyProperty):
* css/CSSStyleSelector.h:
(WebCore::CSSStyleSelector::setRegionForStyling):
(WebCore::CSSStyleSelector::regionForStyling):
(WebCore::CSSStyleSelector::applyPropertyToRegionStyle):
* rendering/RenderFlowThread.cpp:
(WebCore::RenderFlowThread::clearRenderObjectCustomStyle):
(WebCore::RenderFlowThread::setRegionRangeForBox):
* rendering/RenderFlowThread.h:
* rendering/RenderLayer.cpp:
(WebCore::CurrentRenderRegionMaintainer::CurrentRenderRegionMaintainer):
(WebCore::CurrentRenderRegionMaintainer::~CurrentRenderRegionMaintainer):
(WebCore::RenderLayer::paint):
(WebCore::RenderLayer::hitTest):
* rendering/RenderObject.cpp:
(WebCore::RenderObject::styleInRegion):
* rendering/RenderObject.h:
(WebCore::RenderObject::canHaveRegionStyle):
* rendering/RenderObjectChildList.cpp:
(WebCore::RenderObjectChildList::removeChildNode):
* rendering/RenderRegion.cpp:
(WebCore::RenderRegion::renderObjectRegionStyle):
(WebCore::RenderRegion::computeStyleInRegion):
(WebCore::RenderRegion::clearObjectStyleInRegion):
* rendering/RenderRegion.h:
* rendering/RenderView.cpp:
(WebCore::RenderView::RenderView):
* rendering/RenderView.h:
(WebCore::RenderView::currentRenderRegion):
(WebCore::RenderView::setCurrentRenderRegion):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@104965 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/css/CSSStyleSelector.cpp
Source/WebCore/css/CSSStyleSelector.h
Source/WebCore/rendering/RenderFlowThread.cpp
Source/WebCore/rendering/RenderFlowThread.h
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderObject.cpp
Source/WebCore/rendering/RenderObject.h
Source/WebCore/rendering/RenderObjectChildList.cpp
Source/WebCore/rendering/RenderRegion.cpp
Source/WebCore/rendering/RenderRegion.h
Source/WebCore/rendering/RenderView.cpp
Source/WebCore/rendering/RenderView.h

index 866bd0d..110d524 100644 (file)
@@ -1,3 +1,60 @@
+2012-01-13  Mihnea Ovidenie  <mihnea@adobe.com>
+
+        [CSSRegions]Add back region style code removed in r104036
+        https://bugs.webkit.org/show_bug.cgi?id=76064
+
+        Reviewed by David Hyatt.
+
+        No new tests. The region style tests are still skipped. A follow up patch will enable
+        both region style for background-color and region style tests.
+
+        * WebCore.exp.in:
+        * css/CSSStyleSelector.cpp:
+        (WebCore::RuleData::useInRegionStyle):
+        (WebCore::CSSStyleSelector::CSSStyleSelector):
+        (WebCore::CSSStyleSelector::addMatchedDeclaration):
+        (WebCore::CSSStyleSelector::matchRules):
+        (WebCore::CSSStyleSelector::matchAllRules):
+        (WebCore::CSSStyleSelector::initForRegionStyling):
+        (WebCore::CSSStyleSelector::initRegionRules):
+        (WebCore::CSSStyleSelector::styleForElement):
+        (WebCore::CSSStyleSelector::pseudoStyleForElement):
+        (WebCore::RuleData::RuleData):
+        (WebCore::RuleSet::RuleSet):
+        (WebCore::RuleSet::addToRuleSet):
+        (WebCore::CSSStyleSelector::applyDeclarations):
+        (WebCore::isValidRegionStyleProperty):
+        (WebCore::CSSStyleSelector::applyProperty):
+        * css/CSSStyleSelector.h:
+        (WebCore::CSSStyleSelector::setRegionForStyling):
+        (WebCore::CSSStyleSelector::regionForStyling):
+        (WebCore::CSSStyleSelector::applyPropertyToRegionStyle):
+        * rendering/RenderFlowThread.cpp:
+        (WebCore::RenderFlowThread::clearRenderObjectCustomStyle):
+        (WebCore::RenderFlowThread::setRegionRangeForBox):
+        * rendering/RenderFlowThread.h:
+        * rendering/RenderLayer.cpp:
+        (WebCore::CurrentRenderRegionMaintainer::CurrentRenderRegionMaintainer):
+        (WebCore::CurrentRenderRegionMaintainer::~CurrentRenderRegionMaintainer):
+        (WebCore::RenderLayer::paint):
+        (WebCore::RenderLayer::hitTest):
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::styleInRegion):
+        * rendering/RenderObject.h:
+        (WebCore::RenderObject::canHaveRegionStyle):
+        * rendering/RenderObjectChildList.cpp:
+        (WebCore::RenderObjectChildList::removeChildNode):
+        * rendering/RenderRegion.cpp:
+        (WebCore::RenderRegion::renderObjectRegionStyle):
+        (WebCore::RenderRegion::computeStyleInRegion):
+        (WebCore::RenderRegion::clearObjectStyleInRegion):
+        * rendering/RenderRegion.h:
+        * rendering/RenderView.cpp:
+        (WebCore::RenderView::RenderView):
+        * rendering/RenderView.h:
+        (WebCore::RenderView::currentRenderRegion):
+        (WebCore::RenderView::setCurrentRenderRegion):
+
 2012-01-13  Kenneth Russell  <kbr@google.com>
 
         Unreviewed build fix; added project.pbxproj changes lost in r104954.
index 5db37bb..27a8099 100644 (file)
@@ -280,6 +280,7 @@ __ZN7WebCore12PrintContext9spoolPageERNS_15GraphicsContextEif
 __ZN7WebCore12PrintContext9spoolRectERNS_15GraphicsContextERKNS_7IntRectE
 __ZN7WebCore12PrintContextC1EPNS_5FrameE
 __ZN7WebCore12PrintContextD1Ev
+__ZNK7WebCore12RenderObject13styleInRegionEv
 __ZN7WebCore12RenderObject16repaintRectangleERKNS_7IntRectEb
 __ZN7WebCore12RenderWidget28resumeWidgetHierarchyUpdatesEv
 __ZN7WebCore12RenderWidget29suspendWidgetHierarchyUpdatesEv
index 6b3a691..a94adb8 100644 (file)
@@ -81,6 +81,7 @@
 #include "PerspectiveTransformOperation.h"
 #include "QuotesData.h"
 #include "Rect.h"
+#include "RenderRegion.h"
 #include "RenderScrollbar.h"
 #include "RenderScrollbarTheme.h"
 #include "RenderStyleConstants.h"
@@ -169,7 +170,7 @@ if (primitiveValue) \
 
 class RuleData {
 public:
-    RuleData(CSSStyleRule*, CSSSelector*, unsigned position);
+    RuleData(CSSStyleRule*, CSSSelector*, unsigned position, ERegionStyleEnabled useInRegionStyle = DoNotUseInRegionStyle);
 
     unsigned position() const { return m_position; }
     CSSStyleRule* rule() const { return m_rule; }
@@ -181,6 +182,7 @@ public:
     bool containsUncommonAttributeSelector() const { return m_containsUncommonAttributeSelector; }
     unsigned specificity() const { return m_specificity; }
     unsigned linkMatchType() const { return m_linkMatchType; }
+    ERegionStyleEnabled useInRegionStyle() const { return static_cast<ERegionStyleEnabled>(m_useInRegionStyle); }
 
     // Try to balance between memory usage (there can be lots of RuleData objects) and good filtering performance.
     static const unsigned maximumIdentifierCount = 4;
@@ -192,12 +194,13 @@ private:
     unsigned m_specificity;
     // This number was picked fairly arbitrarily. We can probably lower it if we need to.
     // Some simple testing showed <100,000 RuleData's on large sites.
-    unsigned m_position : 26;
+    unsigned m_position : 25;
     unsigned m_hasFastCheckableSelector : 1;
     unsigned m_hasMultipartSelector : 1;
     unsigned m_hasRightmostSelectorMatchingHTMLBasedOnRuleHash : 1;
     unsigned m_containsUncommonAttributeSelector : 1;
     unsigned m_linkMatchType : 2; //  SelectorChecker::LinkMatchMask
+    unsigned m_useInRegionStyle : 1; // ERegionStyleEnabled
     // Use plain array instead of a Vector to minimize memory overhead.
     unsigned m_descendantSelectorIdentifierHashes[maximumIdentifierCount];
 };
@@ -215,7 +218,7 @@ COMPILE_ASSERT(sizeof(RuleData) == sizeof(SameSizeAsRuleData), RuleData_should_s
 class RuleSet {
     WTF_MAKE_NONCOPYABLE(RuleSet);
 public:
-    RuleSet();
+    RuleSet(ERegionStyleEnabled useInRegionStyle = DoNotUseInRegionStyle);
 
     typedef HashMap<AtomicStringImpl*, OwnPtr<Vector<RuleData> > > AtomRuleMap;
 
@@ -250,6 +253,7 @@ public:
     Vector<RuleData> m_pageRules;
     unsigned m_ruleCount;
     bool m_autoShrinkToFitEnabled;
+    ERegionStyleEnabled m_useInRegionStyle;
 };
 
 static RuleSet* defaultStyle;
@@ -337,6 +341,7 @@ CSSStyleSelector::CSSStyleSelector(Document* document, StyleSheetList* styleShee
     , m_rootElementStyle(0)
     , m_element(0)
     , m_styledElement(0)
+    , m_regionForStyling(0)
     , m_elementLinkState(NotInsideLink)
     , m_parentNode(0)
     , m_lineHeightValue(0)
@@ -346,6 +351,7 @@ CSSStyleSelector::CSSStyleSelector(Document* document, StyleSheetList* styleShee
     , m_fontSelector(CSSFontSelector::create(document))
     , m_applyPropertyToRegularStyle(true)
     , m_applyPropertyToVisitedLinkStyle(false)
+    , m_applyPropertyToRegionStyle(false)
     , m_applyProperty(CSSStyleApplyProperty::sharedCSSStyleApplyProperty())
 #if ENABLE(CSS_SHADERS)
     , m_hasPendingShaders(false)
@@ -649,12 +655,13 @@ static void ensureDefaultStyleSheetsForElement(Element* element)
 #endif
 }
 
-void CSSStyleSelector::addMatchedDeclaration(CSSMutableStyleDeclaration* styleDeclaration, unsigned linkMatchType)
+void CSSStyleSelector::addMatchedDeclaration(CSSMutableStyleDeclaration* styleDeclaration, unsigned linkMatchType, ERegionStyleEnabled useInRegionStyle)
 {
     m_matchedDecls.grow(m_matchedDecls.size() + 1);
     MatchedStyleDeclaration& newDeclaration = m_matchedDecls.last();
     newDeclaration.styleDeclaration = styleDeclaration;
     newDeclaration.linkMatchType = linkMatchType;
+    newDeclaration.useInRegionStyle = useInRegionStyle;
 }
 
 void CSSStyleSelector::matchRules(RuleSet* rules, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules)
@@ -709,7 +716,7 @@ void CSSStyleSelector::matchRules(RuleSet* rules, int& firstRuleIndex, int& last
         unsigned linkMatchType = m_matchedRules[i]->linkMatchType();
         if (swapVisitedUnvisited && linkMatchType && linkMatchType != SelectorChecker::MatchAll)
             linkMatchType = (linkMatchType == SelectorChecker::MatchVisited) ? SelectorChecker::MatchLink : SelectorChecker::MatchVisited;
-        addMatchedDeclaration(m_matchedRules[i]->rule()->declaration(), linkMatchType);
+        addMatchedDeclaration(m_matchedRules[i]->rule()->declaration(), linkMatchType, m_matchedRules[i]->useInRegionStyle());
     }
 }
 
@@ -869,6 +876,9 @@ void CSSStyleSelector::matchAllRules(MatchResult& result)
     if (m_matchAuthorAndUserStyles)
         matchRules(m_authorStyle.get(), result.firstAuthorRule, result.lastAuthorRule, false);
 
+    if (m_regionForStyling)
+        matchRules(m_regionRules.get(), result.firstAuthorRule, result.lastAuthorRule, false);
+
     // Now check our inline style attribute.
     if (m_matchAuthorAndUserStyles && m_styledElement) {
         CSSMutableStyleDeclaration* inlineDecl = m_styledElement->inlineStyleDecl();
@@ -921,6 +931,37 @@ inline void CSSStyleSelector::initForStyleResolve(Element* e, RenderStyle* paren
     m_fontDirty = false;
 }
 
+inline void CSSStyleSelector::initForRegionStyling(RenderRegion* region)
+{
+    setRegionForStyling(region);
+
+    if (region)
+        initRegionRules(region);
+}
+
+void CSSStyleSelector::initRegionRules(RenderRegion* region)
+{
+    ASSERT(region);
+    // Mark that the set of rules comes from region styling since we need to filter
+    // the properties that can be applied.
+    m_regionRules = adoptPtr(new RuleSet(UseInRegionStyle));
+
+    // From all the region style rules, select those that apply to the specified region.
+    for (Vector<RefPtr<WebKitCSSRegionRule> >::iterator it = m_regionStyleRules.begin(); it != m_regionStyleRules.end(); ++it) {
+        const CSSSelectorList& regionSelectorList = (*it)->selectorList();
+        for (CSSSelector* s = regionSelectorList.first(); s; s = regionSelectorList.next(s)) {
+            if (!m_checker.checkSelector(s, static_cast<Element*>(region->node())))
+                continue;
+            CSSRuleList* regionStylingRules = (*it)->cssRules();
+            for (unsigned index = 0; index < regionStylingRules->length(); ++index) {
+                CSSRule* regionStylingRule = regionStylingRules->item(index);
+                if (regionStylingRule->isStyleRule())
+                    m_regionRules->addStyleRule(static_cast<CSSStyleRule*>(regionStylingRule));
+            }
+        }
+    }
+}
+
 static const unsigned cStyleSearchThreshold = 10;
 static const unsigned cStyleSearchLevelThreshold = 10;
 
@@ -1271,7 +1312,7 @@ static inline bool isAtShadowBoundary(Element* element)
 // If resolveForRootDefault is true, style based on user agent style sheet only. This is used in media queries, where
 // relative units are interpreted according to document root element style, styled only with UA stylesheet
 
-PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* element, RenderStyle* defaultParent, bool allowSharing, bool resolveForRootDefault)
+PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* element, RenderStyle* defaultParent, bool allowSharing, bool resolveForRootDefault, RenderRegion* regionForStyling)
 {
     // Once an element has a renderer, we don't try to destroy it, since otherwise the renderer
     // will vanish if a style recalc happens during loading.
@@ -1287,6 +1328,7 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* element, Rend
 
     initElement(element);
     initForStyleResolve(element, defaultParent);
+    initForRegionStyling(regionForStyling);
     if (allowSharing) {
         RenderStyle* sharedStyle = locateSharedStyle();
         if (sharedStyle)
@@ -1443,7 +1485,7 @@ void CSSStyleSelector::keyframeStylesForAnimation(Element* e, const RenderStyle*
     }
 }
 
-PassRefPtr<RenderStyle> CSSStyleSelector::pseudoStyleForElement(PseudoId pseudo, Element* e, RenderStyle* parentStyle)
+PassRefPtr<RenderStyle> CSSStyleSelector::pseudoStyleForElement(PseudoId pseudo, Element* e, RenderStyle* parentStyle, RenderRegion* regionForStyling)
 {
     if (!e)
         return 0;
@@ -1451,6 +1493,7 @@ PassRefPtr<RenderStyle> CSSStyleSelector::pseudoStyleForElement(PseudoId pseudo,
     initElement(e);
 
     initForStyleResolve(e, parentStyle, pseudo);
+    initForRegionStyling(regionForStyling);
     m_style = RenderStyle::create();
 
     if (m_parentStyle)
@@ -1934,7 +1977,7 @@ static inline bool containsUncommonAttributeSelector(const CSSSelector* selector
     return false;
 }
 
-RuleData::RuleData(CSSStyleRule* rule, CSSSelector* selector, unsigned position)
+RuleData::RuleData(CSSStyleRule* rule, CSSSelector* selector, unsigned position, ERegionStyleEnabled useInRegionStyle)
     : m_rule(rule)
     , m_selector(selector)
     , m_specificity(selector->specificity())
@@ -1944,13 +1987,15 @@ RuleData::RuleData(CSSStyleRule* rule, CSSSelector* selector, unsigned position)
     , m_hasRightmostSelectorMatchingHTMLBasedOnRuleHash(isSelectorMatchingHTMLBasedOnRuleHash(selector))
     , m_containsUncommonAttributeSelector(WebCore::containsUncommonAttributeSelector(selector))
     , m_linkMatchType(SelectorChecker::determineLinkMatchType(selector))
+    , m_useInRegionStyle(useInRegionStyle)
 {
     SelectorChecker::collectIdentifierHashes(m_selector, m_descendantSelectorIdentifierHashes, maximumIdentifierCount);
 }
 
-RuleSet::RuleSet()
+RuleSet::RuleSet(ERegionStyleEnabled useInRegionStyle)
     : m_ruleCount(0)
     , m_autoShrinkToFitEnabled(true)
+    , m_useInRegionStyle(useInRegionStyle)
 {
 }
 
@@ -1961,7 +2006,7 @@ void RuleSet::addToRuleSet(AtomicStringImpl* key, AtomRuleMap& map, CSSStyleRule
     OwnPtr<Vector<RuleData> >& rules = map.add(key, nullptr).first->second;
     if (!rules)
         rules = adoptPtr(new Vector<RuleData>);
-    rules->append(RuleData(rule, selector, m_ruleCount++));
+    rules->append(RuleData(rule, selector, m_ruleCount++, m_useInRegionStyle));
 }
 
 void RuleSet::addRule(CSSStyleRule* rule, CSSSelector* sel)
@@ -2267,8 +2312,11 @@ void CSSStyleSelector::applyDeclarations(bool isImportant, int startIndex, int e
         m_applyPropertyToVisitedLinkStyle = false;
         return;
     }
-    for (int i = startIndex; i <= endIndex; ++i)
+    for (int i = startIndex; i <= endIndex; ++i) {
+        m_applyPropertyToRegionStyle = m_matchedDecls[i].useInRegionStyle;
         applyDeclaration<applyFirst>(m_matchedDecls[i].styleDeclaration.get(), isImportant, inheritedOnly);
+        m_applyPropertyToRegionStyle = false;
+    }
 }
 
 unsigned CSSStyleSelector::computeDeclarationHash(MatchedStyleDeclaration* declarations, unsigned size)
@@ -2554,6 +2602,20 @@ inline bool isValidVisitedLinkProperty(int id)
     return false;
 }
 
+// http://dev.w3.org/csswg/css3-regions/#the-at-region-style-rule
+// FIXME: add incremental support for other region styling properties.
+inline bool isValidRegionStyleProperty(int id)
+{
+    switch (static_cast<CSSPropertyID>(id)) {
+    case CSSPropertyBackgroundColor:
+        return true;
+    default:
+        break;
+    }
+
+    return false;
+}
+
 // SVG handles zooming in a different way compared to CSS. The whole document is scaled instead
 // of each individual length value in the render style / tree. CSSPrimitiveValue::computeLength*()
 // multiplies each resolved length with the zoom multiplier - so for SVG we need to disable that.
@@ -2634,6 +2696,10 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
         return;
     }
 
+    // Filter region style property
+    if (applyPropertyToRegionStyle() && !isValidRegionStyleProperty(id))
+        return;
+
     CSSPropertyID property = static_cast<CSSPropertyID>(id);
 
     if (isInherit && m_parentStyle && !m_parentStyle->hasExplicitlyInheritedProperties() && !CSSProperty::isInheritedProperty(property))
index 856193f..d6bb414 100644 (file)
@@ -36,6 +36,7 @@
 namespace WebCore {
 
 enum ESmartMinimumForFontSize { DoNotUseSmartMinimumForFontSize, UseSmartMinimumForFontFize };
+enum ERegionStyleEnabled { DoNotUseInRegionStyle, UseInRegionStyle };
 
 class CSSFontSelector;
 class CSSMutableStyleDeclaration;
@@ -63,6 +64,7 @@ class KeyframeList;
 class KeyframeValue;
 class MediaQueryEvaluator;
 class Node;
+class RenderRegion;
 class RuleData;
 class RuleSet;
 class Settings;
@@ -104,11 +106,11 @@ public:
     void pushParent(Element* parent) { m_checker.pushParent(parent); }
     void popParent(Element* parent) { m_checker.popParent(parent); }
 
-    PassRefPtr<RenderStyle> styleForElement(Element*, RenderStyle* parentStyle = 0, bool allowSharing = true, bool resolveForRootDefault = false);
+    PassRefPtr<RenderStyle> styleForElement(Element*, RenderStyle* parentStyle = 0, bool allowSharing = true, bool resolveForRootDefault = false, RenderRegion* regionForStyling = 0);
 
     void keyframeStylesForAnimation(Element*, const RenderStyle*, KeyframeList&);
 
-    PassRefPtr<RenderStyle> pseudoStyleForElement(PseudoId, Element*, RenderStyle* parentStyle = 0);
+    PassRefPtr<RenderStyle> pseudoStyleForElement(PseudoId, Element*, RenderStyle* parentStyle = 0, RenderRegion* regionForStyling = 0);
 
     PassRefPtr<RenderStyle> styleForPage(int pageIndex);
 
@@ -135,6 +137,8 @@ public:
 private:
     void initForStyleResolve(Element*, RenderStyle* parentStyle = 0, PseudoId = NOPSEUDO);
     void initElement(Element*);
+    void initForRegionStyling(RenderRegion*);
+    void initRegionRules(RenderRegion*);
     void collectFeatures();
     RenderStyle* locateSharedStyle();
     bool matchesRuleSet(RuleSet*);
@@ -143,6 +147,8 @@ private:
     bool canShareStyleWithElement(StyledElement*) const;
 
     PassRefPtr<RenderStyle> styleForKeyframe(const RenderStyle*, const WebKitCSSKeyframeRule*, KeyframeValue&);
+    void setRegionForStyling(RenderRegion* region) { m_regionForStyling = region; }
+    RenderRegion* regionForStyling() const { return m_regionForStyling; }
 
 public:
     // These methods will give back the set of rules that matched for a given element (or a pseudo-element).
@@ -243,7 +249,7 @@ private:
     void adjustRenderStyle(RenderStyle* styleToAdjust, RenderStyle* parentStyle, Element*);
 
     void addMatchedRule(const RuleData* rule) { m_matchedRules.append(rule); }
-    void addMatchedDeclaration(CSSMutableStyleDeclaration*, unsigned linkMatchType = SelectorChecker::MatchAll);
+    void addMatchedDeclaration(CSSMutableStyleDeclaration*, unsigned linkMatchType = SelectorChecker::MatchAll, ERegionStyleEnabled useInRegionStyle = DoNotUseInRegionStyle);
 
     struct MatchResult {
         MatchResult() : firstUARule(-1), lastUARule(-1), firstAuthorRule(-1), lastAuthorRule(-1), firstUserRule(-1), lastUserRule(-1), isCacheable(true) { }
@@ -279,6 +285,7 @@ private:
 
     OwnPtr<RuleSet> m_authorStyle;
     OwnPtr<RuleSet> m_userStyle;
+    OwnPtr<RuleSet> m_regionRules;
 
     Features m_features;
 
@@ -302,6 +309,7 @@ public:
 
     bool applyPropertyToRegularStyle() const { return m_applyPropertyToRegularStyle; }
     bool applyPropertyToVisitedLinkStyle() const { return m_applyPropertyToVisitedLinkStyle; }
+    bool applyPropertyToRegionStyle() const { return m_applyPropertyToRegionStyle; }
 
 private:
     static RenderStyle* s_styleNotYetAvailable;
@@ -350,7 +358,10 @@ private:
 
         RefPtr<CSSMutableStyleDeclaration> styleDeclaration;
         union {
-            unsigned linkMatchType;
+            struct {
+                unsigned linkMatchType : 31;
+                unsigned useInRegionStyle : 1; // ERegionStyleEnabled
+            };
             // Used to make sure all memory is zero-initialized since we compute the hash over the bytes of this object.
             void* possiblyPaddedMember;
         };
@@ -399,6 +410,7 @@ private:
     RenderStyle* m_rootElementStyle;
     Element* m_element;
     StyledElement* m_styledElement;
+    RenderRegion* m_regionForStyling;
     EInsideLink m_elementLinkState;
     ContainerNode* m_parentNode;
     CSSValue* m_lineHeightValue;
@@ -411,6 +423,7 @@ private:
 
     bool m_applyPropertyToRegularStyle;
     bool m_applyPropertyToVisitedLinkStyle;
+    bool m_applyPropertyToRegionStyle;
     const CSSStyleApplyProperty& m_applyProperty;
     
 #if ENABLE(CSS_SHADERS)
index dfdc966..4ddee97 100644 (file)
@@ -734,6 +734,32 @@ RenderRegion* RenderFlowThread::lastRegion() const
     return 0;
 }
 
+void RenderFlowThread::clearRenderObjectCustomStyle(const RenderObject* object,
+    const RenderRegion* oldStartRegion, const RenderRegion* oldEndRegion,
+    const RenderRegion* newStartRegion, const RenderRegion* newEndRegion)
+{
+    // Clear the styles for the object in the regions.
+    // The styles are not cleared for the regions that are contained in both ranges.
+    bool insideOldRegionRange = false;
+    bool insideNewRegionRange = false;
+    for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
+        RenderRegion* region = *iter;
+
+        if (oldStartRegion == region)
+            insideOldRegionRange = true;
+        if (newStartRegion == region)
+            insideNewRegionRange = true;
+
+        if (!(insideOldRegionRange && insideNewRegionRange))
+            region->clearObjectStyleInRegion(object);
+
+        if (oldEndRegion == region)
+            insideOldRegionRange = false;
+        if (newEndRegion == region)
+            insideNewRegionRange = false;
+    }
+}
+
 void RenderFlowThread::setRegionRangeForBox(const RenderBox* box, LayoutUnit offsetFromLogicalTopOfFirstPage)
 {
     // FIXME: Not right for differing writing-modes.
@@ -764,6 +790,7 @@ void RenderFlowThread::setRegionRangeForBox(const RenderBox* box, LayoutUnit off
             break;
     }
 
+    clearRenderObjectCustomStyle(box, range.startRegion(), range.endRegion(), startRegion, endRegion);
     range.setRange(startRegion, endRegion);
 }
 
index e10c5fc..5ababf8 100644 (file)
@@ -123,6 +123,9 @@ public:
     void setRegionRangeForBox(const RenderBox*, LayoutUnit offsetFromLogicalTopOfFirstPage);
     void getRegionRangeForBox(const RenderBox*, RenderRegion*& startRegion, RenderRegion*& endRegion) const;
 
+    void clearRenderObjectCustomStyle(const RenderObject*,
+                                      const RenderRegion* oldStartRegion = 0, const RenderRegion* oldEndRegion = 0,
+                                      const RenderRegion* newStartRegion = 0, const RenderRegion* newEndRegion = 0);
     WebKitNamedFlow* ensureNamedFlow();
 
 private:
index 26cb080..7e2db67 100644 (file)
@@ -2583,9 +2583,28 @@ bool RenderLayer::scroll(ScrollDirection direction, ScrollGranularity granularit
     return ScrollableArea::scroll(direction, granularity, multiplier);
 }
 
+class CurrentRenderRegionMaintainer {
+    WTF_MAKE_NONCOPYABLE(CurrentRenderRegionMaintainer);
+public:
+    CurrentRenderRegionMaintainer(RenderView* view, RenderRegion* renderRegion)
+    : m_view(view)
+    , m_renderRegion(view->currentRenderRegion())
+    {
+        m_view->setCurrentRenderRegion(renderRegion);
+    }
+    ~CurrentRenderRegionMaintainer()
+    {
+        m_view->setCurrentRenderRegion(m_renderRegion);
+    }
+private:
+    RenderView* m_view;
+    RenderRegion* m_renderRegion;
+};
+
 void RenderLayer::paint(GraphicsContext* p, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject *paintingRoot,
     RenderRegion* region, PaintLayerFlags paintFlags)
 {
+    CurrentRenderRegionMaintainer renderRegionMaintainer(renderer()->view(), region);
     OverlapTestRequestMap overlapTestRequests;
     paintLayer(this, p, damageRect, paintBehavior, paintingRoot, region, &overlapTestRequests, paintFlags);
     OverlapTestRequestMap::iterator end = overlapTestRequests.end();
@@ -3087,6 +3106,7 @@ static inline LayoutRect frameVisibleRect(RenderObject* renderer)
 
 bool RenderLayer::hitTest(const HitTestRequest& request, HitTestResult& result)
 {
+    CurrentRenderRegionMaintainer renderRegionMaintainer(renderer()->view(), result.region());
     renderer()->document()->updateLayout();
     
     LayoutRect hitTestArea = renderer()->view()->documentRect();
index 73d8744..f4bd2a1 100755 (executable)
@@ -1713,6 +1713,20 @@ StyleDifference RenderObject::adjustStyleDifference(StyleDifference diff, unsign
     return diff;
 }
 
+RenderStyle* RenderObject::styleInRegion() const
+{
+    ASSERT(inRenderFlowThread());
+
+    if (!canHaveRegionStyle()
+        || !((view() && view()->currentRenderRegion() && view()->currentRenderRegion()->hasCustomRegionStyle())))
+        return m_style.get();
+
+    RenderStyle* regionStyle = view()->currentRenderRegion()->renderObjectRegionStyle(this);
+    if (!regionStyle)
+        view()->currentRenderRegion()->computeStyleInRegion(this);
+    return view()->currentRenderRegion()->renderObjectRegionStyle(this);
+}
+
 void RenderObject::setStyle(PassRefPtr<RenderStyle> style)
 {
     if (m_style == style) {
index ac3339e..0b26ea3 100644 (file)
@@ -343,6 +343,7 @@ public:
 #endif
 
     virtual bool isRenderFlowThread() const { return false; }
+    bool canHaveRegionStyle() const { return isRenderBlock() && !isAnonymous() && !isRenderFlowThread(); }
 
     bool isRoot() const { return document()->documentElement() == m_node; }
     bool isBody() const;
@@ -878,6 +879,7 @@ protected:
     virtual LayoutRect outlineBoundsForRepaint(RenderBoxModelObject* /*repaintContainer*/, LayoutPoint* /*cachedOffsetToRepaintContainer*/ = 0) const { return LayoutRect(); }
 
 private:
+    RenderStyle* styleInRegion() const;
     RenderStyle* firstLineStyleSlowCase() const;
     StyleDifference adjustStyleDifference(StyleDifference, unsigned contextSensitiveProperties) const;
 
index ce611a7..1f176b5 100644 (file)
@@ -114,8 +114,11 @@ RenderObject* RenderObjectChildList::removeChildNode(RenderObject* owner, Render
         if (oldChild->isRenderRegion())
             toRenderRegion(oldChild)->detachRegion();
 
-        if (oldChild->inRenderFlowThread() && oldChild->isBox())
+        if (oldChild->inRenderFlowThread() && oldChild->isBox()) {
             oldChild->enclosingRenderFlowThread()->removeRenderBoxRegionInfo(toRenderBox(oldChild));
+            if (oldChild->canHaveRegionStyle())
+                oldChild->enclosingRenderFlowThread()->clearRenderObjectCustomStyle(oldChild);
+        }
 
         if (RenderFlowThread* containerFlowThread = renderFlowThreadContainer(owner))
             containerFlowThread->removeFlowChild(oldChild);
index 327f82b..63fec0a 100644 (file)
@@ -234,4 +234,38 @@ LayoutUnit RenderRegion::offsetFromLogicalTopOfFirstPage() const
     return regionRect().x();
 }
 
+RenderStyle* RenderRegion::renderObjectRegionStyle(const RenderObject* renderObject) const
+{
+    RenderObjectRegionStyleMap::const_iterator it = m_renderObjectRegionStyle.find(renderObject);
+    return (it != m_renderObjectRegionStyle.end()) ? it->second.get() : 0;
+}
+
+void RenderRegion::computeStyleInRegion(const RenderObject* object)
+{
+    ASSERT(object);
+    ASSERT(object->view());
+    ASSERT(object->view()->document());
+    ASSERT(!object->isAnonymous());
+    ASSERT(object->node() && object->node()->isElementNode());
+
+    Element* element = toElement(object->node());
+    RefPtr<RenderStyle> renderObjectStyle = object->view()->document()->styleSelector()->styleForElement(element, 0, false, false, this);
+    m_renderObjectRegionStyle.set(object, renderObjectStyle);
+
+    if (!object->hasBoxDecorations()) {
+        RenderBox* box = const_cast<RenderBox*>(toRenderBox(object));
+        RenderStyle* styleInRegion = renderObjectRegionStyle(object);
+        ASSERT(styleInRegion);
+
+        bool hasBoxDecorations = object->isTableCell() || styleInRegion->hasBackground() || styleInRegion->hasBorder() || styleInRegion->hasAppearance() || styleInRegion->boxShadow();
+        box->setHasBoxDecorations(hasBoxDecorations);
+    }
+}
+
+void RenderRegion::clearObjectStyleInRegion(const RenderObject* object)
+{
+    ASSERT(object);
+    m_renderObjectRegionStyle.remove(object);
+}
+
 } // namespace WebCore
index 61cf1f5..b6483f1 100644 (file)
@@ -80,6 +80,9 @@ public:
     bool isFirstRegion() const;
     bool isLastRegion() const;
 
+    RenderStyle* renderObjectRegionStyle(const RenderObject*) const;
+    void computeStyleInRegion(const RenderObject*);
+    void clearObjectStyleInRegion(const RenderObject*);
 private:
     virtual const char* renderName() const { return "RenderRegion"; }
 
@@ -97,6 +100,11 @@ private:
     // it will also hold a custom style for any box (for region styling).
     HashMap<const RenderBox*, OwnPtr<RenderBoxRegionInfo> > m_renderBoxRegionInfo;
 
+    // This map holds information about the region style associated with the render objects that
+    // are displayed into this region.
+    typedef HashMap<const RenderObject*, RefPtr<RenderStyle> > RenderObjectRegionStyleMap;
+    RenderObjectRegionStyleMap m_renderObjectRegionStyle;
+
     bool m_isValid;
     bool m_hasCustomRegionStyle;
 };
index e6190ff..c8858c6 100644 (file)
@@ -58,6 +58,7 @@ RenderView::RenderView(Node* node, FrameView* view)
     , m_layoutState(0)
     , m_layoutStateDisableCount(0)
     , m_currentRenderFlowThread(0)
+    , m_currentRenderRegion(0)
 {
     // Clear our anonymous bit, set because RenderObject assumes
     // any renderer with document as the node is anonymous.
index f4c2c8a..728dd8b 100644 (file)
@@ -32,6 +32,7 @@
 namespace WebCore {
 
 class RenderFlowThread;
+class RenderRegion;
 class RenderWidget;
 
 #if USE(ACCELERATED_COMPOSITING)
@@ -187,6 +188,9 @@ public:
     RenderFlowThread* currentRenderFlowThread() const { return m_currentRenderFlowThread; }
     void setCurrentRenderFlowThread(RenderFlowThread* flowThread) { m_currentRenderFlowThread = flowThread; }
 
+    RenderRegion* currentRenderRegion() const { return m_currentRenderRegion; }
+    void setCurrentRenderRegion(RenderRegion* region) { m_currentRenderRegion = region; }
+
     void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
 
     IntervalArena* intervalArena();
@@ -276,6 +280,7 @@ private:
 #endif
     OwnPtr<RenderFlowThreadList> m_renderFlowThreadList;
     RenderFlowThread* m_currentRenderFlowThread;
+    RenderRegion* m_currentRenderRegion;
     RefPtr<IntervalArena> m_intervalArena;
 };