Skip to content

Commit

Permalink
[Inspector] Expose @position-fallback and @try rules from CDP
Browse files Browse the repository at this point in the history
This CL adds `cssPositionFallbackRules` to `getMatchedStylesForNode`
response, similar to how we currently expose `keyframes` to DevTools.

Bug: 1412227
Change-Id: I03fe48e0b344f3848d90a63deb4682f6a2227450
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4368581
Commit-Queue: Ergün Erdoğmuş <ergunsh@chromium.org>
Reviewed-by: Alex Rudenko <alexrudenko@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1122345}
  • Loading branch information
ergunsh authored and Chromium LUCI CQ committed Mar 27, 2023
1 parent 6658bc4 commit cd3647f
Show file tree
Hide file tree
Showing 17 changed files with 289 additions and 14 deletions.
20 changes: 20 additions & 0 deletions third_party/blink/public/devtools_protocol/browser_protocol.pdl
Expand Up @@ -1669,6 +1669,24 @@ experimental domain CSS
# Available variation settings (a.k.a. "axes").
optional array of FontVariationAxis fontVariationAxes

# CSS try rule representation.
type CSSTryRule extends object
properties
# The css style sheet identifier (absent for user agent stylesheet and user-specified
# stylesheet rules) this rule came from.
optional StyleSheetId styleSheetId
# Parent stylesheet's origin.
StyleSheetOrigin origin
# Associated style declaration.
optional CSSStyle style

# CSS position-fallback rule representation.
type CSSPositionFallbackRule extends object
properties
Value name
# List of keyframes.
array of CSSTryRule tryRules

# CSS keyframes rule representation.
type CSSKeyframesRule extends object
properties
Expand Down Expand Up @@ -1802,6 +1820,8 @@ experimental domain CSS
optional array of InheritedPseudoElementMatches inheritedPseudoElements
# A list of CSS keyframed animations matching this node.
optional array of CSSKeyframesRule cssKeyframesRules
# A list of CSS position fallbacks matching this node.
optional array of CSSPositionFallbackRule cssPositionFallbackRules
# Id of the first parent element that does not have display: contents.
experimental optional DOM.NodeId parentLayoutNodeId

Expand Down
Expand Up @@ -56,6 +56,10 @@ class CSSPositionFallbackRule final : public CSSRule {
CSSPositionFallbackRule(StyleRulePositionFallback*, CSSStyleSheet* parent);
~CSSPositionFallbackRule() final;

StyleRulePositionFallback* PositionFallback() {
return position_fallback_rule_.Get();
}

String name() const { return position_fallback_rule_->Name(); }

Type GetType() const final { return kPositionFallbackRule; }
Expand Down
Expand Up @@ -90,7 +90,8 @@ class CSSRuleSourceData final : public GarbageCollected<CSSRuleSourceData> {

bool HasProperties() const {
return type == StyleRule::kStyle || type == StyleRule::kFontFace ||
type == StyleRule::kPage || type == StyleRule::kKeyframe;
type == StyleRule::kPage || type == StyleRule::kKeyframe ||
type == StyleRule::kTry;
}

bool HasMedia() const {
Expand Down
18 changes: 18 additions & 0 deletions third_party/blink/renderer/core/css/css_try_rule.cc
Expand Up @@ -6,6 +6,7 @@

#include "third_party/blink/renderer/core/css/css_position_fallback_rule.h"
#include "third_party/blink/renderer/core/css/css_property_value_set.h"
#include "third_party/blink/renderer/core/css/style_rule_css_style_declaration.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"

namespace blink {
Expand Down Expand Up @@ -38,13 +39,30 @@ String CSSTryRule::cssText() const {
return result.ReleaseString();
}

MutableCSSPropertyValueSet& StyleRuleTry::MutableProperties() {
if (!properties_->IsMutable()) {
properties_ = properties_->MutableCopy();
}
return *To<MutableCSSPropertyValueSet>(properties_.Get());
}

CSSStyleDeclaration* CSSTryRule::style() const {
if (!properties_cssom_wrapper_) {
properties_cssom_wrapper_ =
MakeGarbageCollected<StyleRuleCSSStyleDeclaration>(
try_rule_->MutableProperties(), const_cast<CSSTryRule*>(this));
}
return properties_cssom_wrapper_.Get();
}

void CSSTryRule::Reattach(StyleRuleBase* rule) {
DCHECK(rule);
try_rule_ = To<StyleRuleTry>(rule);
}

void CSSTryRule::Trace(Visitor* visitor) const {
visitor->Trace(try_rule_);
visitor->Trace(properties_cssom_wrapper_);
CSSRule::Trace(visitor);
}

Expand Down
4 changes: 4 additions & 0 deletions third_party/blink/renderer/core/css/css_try_rule.h
Expand Up @@ -11,13 +11,15 @@
namespace blink {

class CSSPositionFallbackRule;
class StyleRuleCSSStyleDeclaration;

class StyleRuleTry final : public StyleRuleBase {
public:
explicit StyleRuleTry(CSSPropertyValueSet*);
~StyleRuleTry();

const CSSPropertyValueSet& Properties() const { return *properties_; }
MutableCSSPropertyValueSet& MutableProperties();

void TraceAfterDispatch(Visitor*) const;

Expand All @@ -37,6 +39,7 @@ class CSSTryRule final : public CSSRule {
CSSTryRule(StyleRuleTry*, CSSPositionFallbackRule* parent);
~CSSTryRule() final;

CSSStyleDeclaration* style() const;
Type GetType() const final { return kTryRule; }

String cssText() const final;
Expand All @@ -46,6 +49,7 @@ class CSSTryRule final : public CSSRule {

private:
Member<StyleRuleTry> try_rule_;
mutable Member<StyleRuleCSSStyleDeclaration> properties_cssom_wrapper_;
};

} // namespace blink
Expand Down
Expand Up @@ -2199,7 +2199,8 @@ void CSSParserImpl::ConsumeDeclaration(CSSParserTokenStream& stream,
}

if (observer_ &&
(rule_type == StyleRule::kStyle || rule_type == StyleRule::kKeyframe)) {
(rule_type == StyleRule::kStyle || rule_type == StyleRule::kKeyframe ||
rule_type == StyleRule::kTry)) {
// The end offset is the offset of the terminating token, which is peeked
// but not yet consumed.
observer_->ObserveProperty(decl_offset_start, stream.LookAheadOffset(),
Expand Down
34 changes: 24 additions & 10 deletions third_party/blink/renderer/core/css/resolver/style_resolver.cc
Expand Up @@ -47,6 +47,7 @@
#include "third_party/blink/renderer/core/css/css_initial_color_value.h"
#include "third_party/blink/renderer/core/css/css_keyframe_rule.h"
#include "third_party/blink/renderer/core/css/css_keyframes_rule.h"
#include "third_party/blink/renderer/core/css/css_position_fallback_rule.h"
#include "third_party/blink/renderer/core/css/css_property_names.h"
#include "third_party/blink/renderer/core/css/css_rule_list.h"
#include "third_party/blink/renderer/core/css/css_selector.h"
Expand Down Expand Up @@ -2869,14 +2870,9 @@ Element& StyleResolver::EnsureElementForFormattedText() {
return *formatted_text_element_;
}

scoped_refptr<const ComputedStyle> StyleResolver::ResolvePositionFallbackStyle(
Element& element,
unsigned index) {
const ComputedStyle& base_style = element.ComputedStyleRef();
const ScopedCSSName* position_fallback = base_style.PositionFallback();
DCHECK(position_fallback);

const TreeScope* tree_scope = position_fallback->GetTreeScope();
StyleRulePositionFallback* StyleResolver::ResolvePositionFallbackRule(
const TreeScope* tree_scope,
AtomicString position_fallback_name) {
if (!tree_scope) {
tree_scope = &GetDocument();
}
Expand All @@ -2885,7 +2881,7 @@ scoped_refptr<const ComputedStyle> StyleResolver::ResolvePositionFallbackStyle(
for (; tree_scope; tree_scope = tree_scope->ParentTreeScope()) {
if (ScopedStyleResolver* resolver = tree_scope->GetScopedStyleResolver()) {
position_fallback_rule =
resolver->PositionFallbackForName(position_fallback->GetName());
resolver->PositionFallbackForName(position_fallback_name);
if (position_fallback_rule) {
break;
}
Expand All @@ -2897,13 +2893,31 @@ scoped_refptr<const ComputedStyle> StyleResolver::ResolvePositionFallbackStyle(
for (const auto& rule : CSSDefaultStyleSheets::Instance()
.DefaultHtmlStyle()
->PositionFallbackRules()) {
if (position_fallback->GetName() == rule->Name()) {
if (position_fallback_name == rule->Name()) {
position_fallback_rule = rule;
break;
}
}
}

return position_fallback_rule;
}

scoped_refptr<const ComputedStyle> StyleResolver::ResolvePositionFallbackStyle(
Element& element,
unsigned index) {
const ComputedStyle& base_style = element.ComputedStyleRef();
const ScopedCSSName* position_fallback = base_style.PositionFallback();
DCHECK(position_fallback);

const TreeScope* tree_scope = position_fallback->GetTreeScope();
if (!tree_scope) {
tree_scope = &GetDocument();
}

StyleRulePositionFallback* position_fallback_rule =
ResolvePositionFallbackRule(tree_scope, position_fallback->GetName());

if (!position_fallback_rule ||
index >= position_fallback_rule->TryRules().size()) {
return nullptr;
Expand Down
Expand Up @@ -29,6 +29,7 @@
#include "third_party/blink/renderer/core/animation/property_handle.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/css/color_scheme_flags.h"
#include "third_party/blink/renderer/core/css/css_position_fallback_rule.h"
#include "third_party/blink/renderer/core/css/element_rule_collector.h"
#include "third_party/blink/renderer/core/css/resolver/matched_properties_cache.h"
#include "third_party/blink/renderer/core/css/resolver/style_builder.h"
Expand Down Expand Up @@ -213,7 +214,9 @@ class CORE_EXPORT StyleResolver final : public GarbageCollected<StyleResolver> {
Element& element,
const ComputedStyle& base_style,
ActiveInterpolationsMap& transition_interpolations);

StyleRulePositionFallback* ResolvePositionFallbackRule(
const TreeScope* tree_scope,
AtomicString position_fallback_name);
scoped_refptr<const ComputedStyle> ResolvePositionFallbackStyle(
Element&,
unsigned index);
Expand Down
109 changes: 108 additions & 1 deletion third_party/blink/renderer/core/inspector/inspector_css_agent.cc
Expand Up @@ -44,6 +44,7 @@
#include "third_party/blink/renderer/core/css/css_layer_block_rule.h"
#include "third_party/blink/renderer/core/css/css_layer_statement_rule.h"
#include "third_party/blink/renderer/core/css/css_media_rule.h"
#include "third_party/blink/renderer/core/css/css_position_fallback_rule.h"
#include "third_party/blink/renderer/core/css/css_property_name.h"
#include "third_party/blink/renderer/core/css/css_property_names.h"
#include "third_party/blink/renderer/core/css/css_property_value_set.h"
Expand Down Expand Up @@ -987,6 +988,8 @@ Response InspectorCSSAgent::getMatchedStylesForNode(
inherited_pseudo_id_matches,
Maybe<protocol::Array<protocol::CSS::CSSKeyframesRule>>*
css_keyframes_rules,
Maybe<protocol::Array<protocol::CSS::CSSPositionFallbackRule>>*
css_position_fallback_rules,
Maybe<int>* parentLayoutNodeId) {
Response response = AssertEnabled();
if (!response.IsSuccess())
Expand Down Expand Up @@ -1103,6 +1106,7 @@ Response InspectorCSSAgent::getMatchedStylesForNode(
}

*css_keyframes_rules = AnimationsForNode(element, animating_element);
*css_position_fallback_rules = PositionFallbackRulesForNode(element);

auto* parentLayoutNode = LayoutTreeBuilderTraversal::LayoutParent(*element);
if (parentLayoutNode) {
Expand All @@ -1116,8 +1120,12 @@ Response InspectorCSSAgent::getMatchedStylesForNode(
template <class CSSRuleCollection>
static CSSKeyframesRule* FindKeyframesRule(CSSRuleCollection* css_rules,
StyleRuleKeyframes* keyframes_rule) {
if (!css_rules) {
return nullptr;
}

CSSKeyframesRule* result = nullptr;
for (unsigned j = 0; css_rules && j < css_rules->length() && !result; ++j) {
for (unsigned j = 0; j < css_rules->length() && !result; ++j) {
CSSRule* css_rule = css_rules->item(j);
if (auto* css_style_rule = DynamicTo<CSSKeyframesRule>(css_rule)) {
if (css_style_rule->Keyframes() == keyframes_rule)
Expand All @@ -1131,6 +1139,105 @@ static CSSKeyframesRule* FindKeyframesRule(CSSRuleCollection* css_rules,
return result;
}

template <class CSSRuleCollection>
static CSSPositionFallbackRule* FindPositionFallbackRule(
CSSRuleCollection* css_rules,
StyleRulePositionFallback* position_fallback_rule) {
if (!css_rules) {
return nullptr;
}

CSSPositionFallbackRule* result = nullptr;
for (unsigned j = 0; j < css_rules->length() && !result; ++j) {
CSSRule* css_rule = css_rules->item(j);
if (auto* css_style_rule = DynamicTo<CSSPositionFallbackRule>(css_rule)) {
if (css_style_rule->PositionFallback() == position_fallback_rule) {
result = css_style_rule;
}
} else if (auto* css_import_rule = DynamicTo<CSSImportRule>(css_rule)) {
result = FindPositionFallbackRule(css_import_rule->styleSheet(),
position_fallback_rule);
} else {
result = FindPositionFallbackRule(css_rule->cssRules(),
position_fallback_rule);
}
}
return result;
}

std::unique_ptr<protocol::Array<protocol::CSS::CSSPositionFallbackRule>>
InspectorCSSAgent::PositionFallbackRulesForNode(Element* element) {
auto css_position_fallback_rules = std::make_unique<
protocol::Array<protocol::CSS::CSSPositionFallbackRule>>();
Document& document = element->GetDocument();
DCHECK(!document.NeedsLayoutTreeUpdateForNode(*element));

const ComputedStyle* style = element->EnsureComputedStyle();
if (!style) {
return css_position_fallback_rules;
}

const ScopedCSSName* position_fallback = style->PositionFallback();
if (!position_fallback) {
return css_position_fallback_rules;
}

const TreeScope* tree_scope = position_fallback->GetTreeScope();
if (!tree_scope) {
tree_scope = &document;
}

StyleResolver& style_resolver = document.GetStyleResolver();
StyleRulePositionFallback* position_fallback_rule =
style_resolver.ResolvePositionFallbackRule(tree_scope,
position_fallback->GetName());

// Find CSSOM wrapper from internal Style rule.
CSSPositionFallbackRule* css_position_fallback_rule = nullptr;
for (CSSStyleSheet* style_sheet :
*document_to_css_style_sheets_.at(&document)) {
css_position_fallback_rule =
FindPositionFallbackRule(style_sheet, position_fallback_rule);
if (css_position_fallback_rule) {
break;
}
}

if (!css_position_fallback_rule) {
return css_position_fallback_rules;
}

auto try_rules =
std::make_unique<protocol::Array<protocol::CSS::CSSTryRule>>();
for (unsigned j = 0; j < css_position_fallback_rule->length(); ++j) {
InspectorStyleSheet* inspector_style_sheet =
BindStyleSheet(css_position_fallback_rule->parentStyleSheet());
try_rules->emplace_back(inspector_style_sheet->BuildObjectForTryRule(
css_position_fallback_rule->Item(j)));
}

InspectorStyleSheet* inspector_style_sheet =
BindStyleSheet(css_position_fallback_rule->parentStyleSheet());
CSSRuleSourceData* source_data =
inspector_style_sheet->SourceDataForRule(css_position_fallback_rule);
std::unique_ptr<protocol::CSS::Value> name =
protocol::CSS::Value::create()
.setText(css_position_fallback_rule->name())
.build();
if (source_data) {
name->setRange(inspector_style_sheet->BuildSourceRangeObject(
source_data->rule_header_range));
}

css_position_fallback_rules->emplace_back(
protocol::CSS::CSSPositionFallbackRule::create()
.setName(std::move(name))
.setTryRules(std::move(try_rules))
.build());

return css_position_fallback_rules;
}

std::unique_ptr<protocol::Array<protocol::CSS::CSSKeyframesRule>>
InspectorCSSAgent::AnimationsForNode(Element* element,
Element* animating_element) {
Expand Down
Expand Up @@ -159,6 +159,7 @@ class CORE_EXPORT InspectorCSSAgent final
protocol::Maybe<
protocol::Array<protocol::CSS::InheritedPseudoElementMatches>>*,
protocol::Maybe<protocol::Array<protocol::CSS::CSSKeyframesRule>>*,
protocol::Maybe<protocol::Array<protocol::CSS::CSSPositionFallbackRule>>*,
protocol::Maybe<int>*) override;
protocol::Response getInlineStylesForNode(
int node_id,
Expand Down Expand Up @@ -320,6 +321,9 @@ class CORE_EXPORT InspectorCSSAgent final
std::unique_ptr<protocol::Array<protocol::CSS::StyleDeclarationEdit>>,
HeapVector<Member<StyleSheetAction>>* actions);

std::unique_ptr<protocol::Array<protocol::CSS::CSSPositionFallbackRule>>
PositionFallbackRulesForNode(Element* element);

// If the |animating_element| is a pseudo element, then |element| is a
// reference to its originating DOM element.
std::unique_ptr<protocol::Array<protocol::CSS::CSSKeyframesRule>>
Expand Down

0 comments on commit cd3647f

Please sign in to comment.