Index: Source/core/css/ElementRuleCollector.cpp |
diff --git a/Source/core/css/ElementRuleCollector.cpp b/Source/core/css/ElementRuleCollector.cpp |
index deff32a41630b5914d77b31d4d7a15aa6c1b6c7d..860f3675153610962392e527b3fc8b6f165bb39f 100644 |
--- a/Source/core/css/ElementRuleCollector.cpp |
+++ b/Source/core/css/ElementRuleCollector.cpp |
@@ -31,6 +31,7 @@ |
#include "core/css/CSSRuleList.h" |
#include "core/css/CSSSelector.h" |
+#include "core/css/CSSStyleRule.h" |
#include "core/css/SelectorCheckerFastPath.h" |
#include "core/css/SiblingTraversalStrategies.h" |
#include "core/css/StylePropertySet.h" |
@@ -41,7 +42,7 @@ |
namespace WebCore { |
ElementRuleCollector::ElementRuleCollector(const ElementResolveContext& context, |
- const SelectorFilter& filter, RenderStyle* style) |
+ const SelectorFilter& filter, RenderStyle* style, ShouldIncludeStyleSheetInCSSOMWrapper includeStyleSheet) |
: m_context(context) |
, m_selectorFilter(filter) |
, m_style(style) |
@@ -51,6 +52,7 @@ ElementRuleCollector::ElementRuleCollector(const ElementResolveContext& context, |
, m_canUseFastReject(m_selectorFilter.parentStackIsConsistent(context.parentNode())) |
, m_sameOriginOnly(false) |
, m_matchingUARules(false) |
+ , m_includeStyleSheet(includeStyleSheet) |
{ } |
ElementRuleCollector::~ElementRuleCollector() |
@@ -178,6 +180,46 @@ void ElementRuleCollector::collectMatchingRulesForRegion(const MatchRequest& mat |
} |
} |
+ |
+static CSSStyleSheet* findStyleSheet(StyleEngine* styleEngine, StyleRule* rule) |
+{ |
+ // FIXME: StyleEngine has a bunch of different accessors for StyleSheet lists, is this the only one we need to care about? |
+ const Vector<RefPtr<CSSStyleSheet> >& stylesheets = styleEngine->activeAuthorStyleSheets(); |
+ for (size_t i = 0; i < stylesheets.size(); ++i) { |
+ CSSStyleSheet* sheet = stylesheets[i].get(); |
+ for (unsigned j = 0; j < sheet->length(); ++j) { |
+ CSSRule* cssRule = sheet->item(j); |
+ if (cssRule->type() != CSSRule::STYLE_RULE) |
+ continue; |
+ CSSStyleRule* cssStyleRule = toCSSStyleRule(cssRule); |
+ if (cssStyleRule->styleRule() == rule) |
+ return sheet; |
+ } |
+ } |
+ return 0; |
+} |
+ |
+void ElementRuleCollector::appendCSSOMWrapperForRule(StyleRule* rule) |
+{ |
+ // FIXME: There should be no codepath that creates a CSSOMWrapper without a parent stylesheet or rule because |
+ // then that codepath can lead to the CSSStyleSheet contents not getting correctly copied when the rule is modified |
+ // through the wrapper (e.g. rule.selectorText="div"). Right now, the inspector uses the pointers for identity though, |
+ // so calling CSSStyleSheet->willMutateRules breaks the inspector. |
+ CSSStyleSheet* sheet = m_includeStyleSheet == IncludeStyleSheetInCSSOMWrapper ? findStyleSheet(m_context.element()->document().styleEngine(), rule) : 0; |
+ // We need to call willMutateRules so that the StyleSheetContents are copy-on-writed before we create the CSSOMWrappers. |
+ // Otherwise, if the sheet is modified through the regular CSSOM, the CSSOMWrappers created here won't be updated |
+ // to point to the new copied StyleRules. An alternate solution would be to update all the CSSOMWrappers when |
+ // the stylesheet is modified. |
+ if (sheet) { |
+ sheet->willMutateRules(); |
+ sheet->didMutateRules(); |
esprehn
2013/10/28 23:54:08
I think you're supposed to call didMutateRules at
ojan
2013/10/28 23:59:58
This function doesn't actually mutate the rules th
|
+ } |
+ RefPtr<CSSRule> cssRule = rule->createCSSOMWrapper(sheet); |
+ if (sheet) |
+ sheet->registerExtraChildRuleCSSOMWrapper(cssRule); |
+ ensureRuleList()->rules().append(cssRule); |
+} |
+ |
void ElementRuleCollector::sortAndTransferMatchedRules() |
{ |
if (!m_matchedRules || m_matchedRules->isEmpty()) |
@@ -187,8 +229,9 @@ void ElementRuleCollector::sortAndTransferMatchedRules() |
Vector<MatchedRule, 32>& matchedRules = *m_matchedRules; |
if (m_mode == SelectorChecker::CollectingRules) { |
- for (unsigned i = 0; i < matchedRules.size(); ++i) |
- ensureRuleList()->rules().append(matchedRules[i].ruleData()->rule()->createCSSOMWrapper()); |
+ for (unsigned i = 0; i < matchedRules.size(); ++i) { |
+ appendCSSOMWrapperForRule(matchedRules[i].ruleData()->rule()); |
+ } |
return; |
} |