blob: a1de663d121a7e01fc0dec1abff793a1e7aa12bd [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/inspector/inspector_style_resolver.h"
#include "third_party/blink/renderer/core/css/css_rule_list.h"
#include "third_party/blink/renderer/core/css/css_style_declaration.h"
#include "third_party/blink/renderer/core/css/css_style_rule.h"
#include "third_party/blink/renderer/core/css/css_value.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/flat_tree_traversal.h"
#include "third_party/blink/renderer/core/dom/pseudo_element.h"
#include "third_party/blink/renderer/core/style/computed_style_constants.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
InspectorStyleResolver::InspectorStyleResolver(Element* element,
PseudoId element_pseudo_id)
: element_(element) {
DCHECK(element_);
// Update style and layout tree for collecting an up-to-date set of rules
// and animations.
element_->GetDocument().UpdateStyleAndLayoutTreeForNode(element_);
// FIXME: It's really gross for the inspector to reach in and access
// StyleResolver directly here. We need to provide the Inspector better APIs
// to get this information without grabbing at internal style classes!
StyleResolver& style_resolver = element_->GetDocument().GetStyleResolver();
matched_rules_ = style_resolver.PseudoCSSRulesForElement(
element_, element_pseudo_id, StyleResolver::kAllCSSRules);
if (element_pseudo_id)
return;
for (PseudoId pseudo_id = kFirstPublicPseudoId;
pseudo_id < kAfterLastInternalPseudoId;
pseudo_id = static_cast<PseudoId>(pseudo_id + 1)) {
if (!PseudoElement::IsWebExposed(pseudo_id, element_))
continue;
// If the pseudo-element doesn't exist, exclude UA rules to avoid cluttering
// all elements.
unsigned rules_to_include = element_->GetPseudoElement(pseudo_id)
? StyleResolver::kAllCSSRules
: StyleResolver::kAllButUACSSRules;
RuleIndexList* matched_rules = style_resolver.PseudoCSSRulesForElement(
element_, pseudo_id, rules_to_include);
if (matched_rules && matched_rules->size()) {
InspectorCSSMatchedRules* match =
MakeGarbageCollected<InspectorCSSMatchedRules>();
match->element = element_;
match->matched_rules = matched_rules;
match->pseudo_id = pseudo_id;
pseudo_element_rules_.push_back(match);
}
}
// Parent rules.
Element* parent_element = FlatTreeTraversal::ParentElement(*element);
while (parent_element) {
RuleIndexList* parent_matched_rules = style_resolver.CssRulesForElement(
parent_element, StyleResolver::kAllCSSRules);
InspectorCSSMatchedRules* match =
MakeGarbageCollected<InspectorCSSMatchedRules>();
match->element = parent_element;
match->matched_rules = parent_matched_rules;
match->pseudo_id = kPseudoIdNone;
parent_rules_.push_back(match);
parent_element = FlatTreeTraversal::ParentElement(*parent_element);
}
}
RuleIndexList* InspectorStyleResolver::MatchedRules() const {
return matched_rules_;
}
HeapVector<Member<InspectorCSSMatchedRules>>
InspectorStyleResolver::PseudoElementRules() {
return pseudo_element_rules_;
}
HeapVector<Member<InspectorCSSMatchedRules>>
InspectorStyleResolver::ParentRules() {
return parent_rules_;
}
} // namespace blink