Index: third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp |
diff --git a/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp |
index de9995e67a792f67b96557734130d82dbb37b010..8704ef0217059eb7c28e6fd3b5ae4e4f96d0522b 100644 |
--- a/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp |
+++ b/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp |
@@ -690,7 +690,7 @@ void InspectorCSSAgent::restore() { |
if (m_state->booleanProperty(CSSAgentState::cssAgentEnabled, false)) |
wasEnabled(); |
if (m_state->booleanProperty(CSSAgentState::ruleRecordingEnabled, false)) |
- setUsageTrackerStatus(true); |
+ setCoverageEnabled(true); |
} |
void InspectorCSSAgent::flushPendingProtocolNotifications() { |
@@ -755,7 +755,7 @@ Response InspectorCSSAgent::disable() { |
m_state->setBoolean(CSSAgentState::cssAgentEnabled, false); |
m_resourceContentLoader->cancel(m_resourceContentLoaderClientId); |
m_state->setBoolean(CSSAgentState::ruleRecordingEnabled, false); |
- setUsageTrackerStatus(false); |
+ setCoverageEnabled(false); |
return Response::OK(); |
} |
@@ -824,6 +824,8 @@ void InspectorCSSAgent::setActiveStyleSheets( |
frontend()->styleSheetAdded( |
newStyleSheet->buildObjectForStyleSheetInfo()); |
} |
+ if (m_tracker && m_hadFirstCoverageRequest) |
+ m_coveragePendingStylsheets.push_back(newStyleSheet); |
} |
if (documentCSSStyleSheets->isEmpty()) |
@@ -2413,81 +2415,100 @@ void InspectorCSSAgent::visitLayoutTreeNodes( |
} |
} |
-void InspectorCSSAgent::setUsageTrackerStatus(bool enabled) { |
+void InspectorCSSAgent::setCoverageEnabled(bool enabled) { |
+ if (enabled == !!m_tracker) |
+ return; |
if (enabled) { |
- if (!m_tracker) |
- m_tracker = new StyleRuleUsageTracker(); |
+ m_tracker = new StyleRuleUsageTracker(); |
+ m_hadFirstCoverageRequest = false; |
} else { |
m_tracker = nullptr; |
+ m_coveragePendingStylsheets.clear(); |
+ m_unusedStyleRuleToCSSStyleRule.clear(); |
} |
- HeapVector<Member<Document>> documents = m_domAgent->documents(); |
- for (Document* document : documents) { |
+ for (Document* document : m_domAgent->documents()) |
document->styleEngine().setRuleUsageTracker(m_tracker); |
- |
- document->setNeedsStyleRecalc( |
- SubtreeStyleChange, |
- StyleChangeReasonForTracing::create(StyleChangeReason::Inspector)); |
- } |
} |
Response InspectorCSSAgent::startRuleUsageTracking() { |
m_state->setBoolean(CSSAgentState::ruleRecordingEnabled, true); |
- setUsageTrackerStatus(true); |
+ setCoverageEnabled(true); |
return Response::OK(); |
} |
-std::unique_ptr<protocol::CSS::RuleUsage> |
-InspectorCSSAgent::buildObjectForRuleUsage(CSSStyleRule* rule, bool used) { |
- InspectorStyleSheet* inspectorStyleSheet = inspectorStyleSheetForRule(rule); |
- if (!inspectorStyleSheet) |
- return nullptr; |
- |
- std::unique_ptr<protocol::CSS::RuleUsage> result = |
- inspectorStyleSheet->buildObjectForRuleUsage(rule, used); |
- |
- return result; |
-} |
- |
Response InspectorCSSAgent::stopRuleUsageTracking( |
std::unique_ptr<protocol::Array<protocol::CSS::RuleUsage>>* result) { |
- if (!m_tracker) { |
- return Response::Error("CSS rule usage tracking is not enabled"); |
- } |
+ Response response = takeCoverageDelta(result); |
+ setCoverageEnabled(false); |
+ return response; |
+} |
- *result = protocol::Array<protocol::CSS::RuleUsage>::create(); |
+void InspectorCSSAgent::collectStyleSheetsForCoverage() { |
+ DCHECK_EQ(0UL, m_coveragePendingStylsheets.size()); |
HeapVector<Member<Document>> documents = m_domAgent->documents(); |
for (Document* document : documents) { |
- HeapHashSet<Member<CSSStyleSheet>>* newSheetsVector = |
- m_documentToCSSStyleSheets.at(document); |
+ document->setNeedsStyleRecalc( |
+ SubtreeStyleChange, |
+ StyleChangeReasonForTracing::create(StyleChangeReason::Inspector)); |
+ document->updateStyleAndLayoutTree(); |
+ } |
+ m_coveragePendingStylsheets.appendRange( |
+ m_idToInspectorStyleSheet.values().begin(), |
+ m_idToInspectorStyleSheet.values().end()); |
+} |
- if (!newSheetsVector) |
- continue; |
+Response InspectorCSSAgent::takeCoverageDelta( |
+ std::unique_ptr<protocol::Array<protocol::CSS::RuleUsage>>* result) { |
+ if (!m_tracker) |
+ return Response::Error("CSS rule usage tracking is not enabled"); |
- for (auto sheet : *newSheetsVector) { |
- InspectorStyleSheet* styleSheet = |
- m_cssStyleSheetToInspectorStyleSheet.at(sheet); |
- const CSSRuleVector ruleVector = styleSheet->flatRules(); |
- for (auto rule : ruleVector) { |
- if (rule->type() != CSSRule::kStyleRule) |
- continue; |
+ if (!m_hadFirstCoverageRequest) { |
+ m_hadFirstCoverageRequest = true; |
+ collectStyleSheetsForCoverage(); |
+ } |
- CSSStyleRule* cssRule = static_cast<CSSStyleRule*>(rule.get()); |
+ HeapVector<Member<StyleRule>> coverageDeltaVector = m_tracker->takeDelta(); |
+ HeapHashSet<Member<StyleRule>> coverageDelta; |
+ for (auto item : coverageDeltaVector) |
+ coverageDelta.insert(item); |
- StyleRule* styleRule = cssRule->styleRule(); |
+ *result = protocol::Array<protocol::CSS::RuleUsage>::create(); |
+ for (auto styleSheet : m_coveragePendingStylsheets) { |
+ const CSSRuleVector& ruleVector = styleSheet->flatRules(); |
+ for (auto rule : ruleVector) { |
+ if (rule->type() != CSSRule::kStyleRule) |
+ continue; |
- std::unique_ptr<protocol::CSS::RuleUsage> protocolRule = |
- buildObjectForRuleUsage(cssRule, m_tracker->contains(styleRule)); |
- if (!protocolRule) |
- continue; |
+ StyleRule* styleRule = |
+ static_cast<CSSStyleRule*>(rule.get())->styleRule(); |
+ bool used = !!coverageDelta.take(styleRule); |
alph
2017/03/20 20:48:31
contains
|
+ std::unique_ptr<protocol::CSS::RuleUsage> ruleUsageObject = |
+ styleSheet->buildObjectForRuleUsage(rule, used); |
- result->get()->addItem(std::move(protocolRule)); |
- } |
+ if (ruleUsageObject) |
+ (*result)->addItem(std::move(ruleUsageObject)); |
+ if (!used) |
+ m_unusedStyleRuleToCSSStyleRule.set(styleRule, asCSSStyleRule(rule)); |
} |
} |
+ m_coveragePendingStylsheets.clear(); |
- setUsageTrackerStatus(false); |
+ for (Member<StyleRule> rule : coverageDelta) { |
+ HeapHashMap<Member<const StyleRule>, Member<CSSStyleRule>>::iterator it = |
alph
2017/03/20 20:48:31
nit: auto it =
|
+ m_unusedStyleRuleToCSSStyleRule.find(rule); |
+ if (it == m_unusedStyleRuleToCSSStyleRule.end()) |
+ continue; |
+ InspectorStyleSheet* styleSheet = inspectorStyleSheetForRule(it->value); |
+ if (!styleSheet) |
+ continue; |
+ std::unique_ptr<protocol::CSS::RuleUsage> ruleUsageObject = |
+ styleSheet->buildObjectForRuleUsage(it->value, true); |
+ if (ruleUsageObject) |
+ (*result)->addItem(std::move(ruleUsageObject)); |
+ m_unusedStyleRuleToCSSStyleRule.remove(it); |
+ } |
return Response::OK(); |
} |
@@ -2506,6 +2527,8 @@ DEFINE_TRACE(InspectorCSSAgent) { |
visitor->trace(m_nodeToInspectorStyleSheet); |
visitor->trace(m_inspectorUserAgentStyleSheet); |
visitor->trace(m_tracker); |
+ visitor->trace(m_unusedStyleRuleToCSSStyleRule); |
+ visitor->trace(m_coveragePendingStylsheets); |
InspectorBaseAgent::trace(visitor); |
} |