Skip to content

Commit

Permalink
[@layer] Cascade @page rules in layer ordering
Browse files Browse the repository at this point in the history
Bug: 1095765
Change-Id: Iadf69ecc4cde948608409c8b385f937206d8791d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3188735
Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org>
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Cr-Commit-Position: refs/heads/main@{#925799}
  • Loading branch information
xiaochengh authored and Chromium LUCI CQ committed Sep 28, 2021
1 parent 1ab1858 commit 4a2ae1b
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 12 deletions.
21 changes: 13 additions & 8 deletions third_party/blink/renderer/core/css/page_rule_collector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,14 @@
#include "third_party/blink/renderer/core/css/page_rule_collector.h"

#include <algorithm>
#include "third_party/blink/renderer/core/css/cascade_layer_map.h"
#include "third_party/blink/renderer/core/css/css_property_value_set.h"
#include "third_party/blink/renderer/core/css/style_rule.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"

namespace blink {

static inline bool ComparePageRules(const StyleRulePage* r1,
const StyleRulePage* r2) {
return r1->Selector()->Specificity() < r2->Selector()->Specificity();
}

bool PageRuleCollector::IsLeftPage(const ComputedStyle* root_element_style,
uint32_t page_index) const {
bool is_first_page_left = false;
Expand All @@ -68,7 +64,8 @@ PageRuleCollector::PageRuleCollector(const ComputedStyle* root_element_style,
page_name_(page_name),
result_(match_result) {}

void PageRuleCollector::MatchPageRules(RuleSet* rules) {
void PageRuleCollector::MatchPageRules(RuleSet* rules,
const CascadeLayerMap* layer_map) {
if (!rules)
return;

Expand All @@ -78,8 +75,16 @@ void PageRuleCollector::MatchPageRules(RuleSet* rules) {
if (matched_page_rules.IsEmpty())
return;

std::stable_sort(matched_page_rules.begin(), matched_page_rules.end(),
ComparePageRules);
std::stable_sort(
matched_page_rules.begin(), matched_page_rules.end(),
[layer_map](const StyleRulePage* r1, const StyleRulePage* r2) {
if (r1->GetCascadeLayer() != r2->GetCascadeLayer()) {
DCHECK(layer_map);
return layer_map->CompareLayerOrder(r1->GetCascadeLayer(),
r2->GetCascadeLayer()) < 0;
}
return r1->Selector()->Specificity() < r2->Selector()->Specificity();
});

for (unsigned i = 0; i < matched_page_rules.size(); i++)
result_.AddMatchedProperties(&matched_page_rules[i]->Properties());
Expand Down
3 changes: 2 additions & 1 deletion third_party/blink/renderer/core/css/page_rule_collector.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

namespace blink {

class CascadeLayerMap;
class StyleRulePage;

class PageRuleCollector {
Expand All @@ -39,7 +40,7 @@ class PageRuleCollector {
const AtomicString& page_name,
MatchResult&);

void MatchPageRules(RuleSet* rules);
void MatchPageRules(RuleSet* rules, const CascadeLayerMap* layer_map);
const MatchResult& MatchedResult() { return result_; }

private:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,8 +292,10 @@ void ScopedStyleResolver::CollectMatchingPartPseudoRules(
void ScopedStyleResolver::MatchPageRules(PageRuleCollector& collector) {
// Currently, only @page rules in the document scope apply.
DCHECK(scope_->RootNode().IsDocumentNode());
for (auto sheet : style_sheets_)
collector.MatchPageRules(&sheet->Contents()->GetRuleSet());
for (auto sheet : style_sheets_) {
collector.MatchPageRules(&sheet->Contents()->GetRuleSet(),
GetCascadeLayerMap());
}
}

void ScopedStyleResolver::RebuildCascadeLayerMap(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1121,7 +1121,8 @@ scoped_refptr<const ComputedStyle> StyleResolver::StyleForPage(
cascade.MutableMatchResult());

collector.MatchPageRules(
CSSDefaultStyleSheets::Instance().DefaultPrintStyle());
CSSDefaultStyleSheets::Instance().DefaultPrintStyle(),
nullptr /* layer_map */);

if (ScopedStyleResolver* scoped_resolver =
GetDocument().GetScopedStyleResolver())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/css/resolver/style_resolver.h"

#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/web/web_print_page_description.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h"
#include "third_party/blink/renderer/core/animation/animation_test_helpers.h"
#include "third_party/blink/renderer/core/animation/document_timeline.h"
Expand All @@ -24,6 +25,7 @@
#include "third_party/blink/renderer/core/dom/pseudo_element.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/dom/text.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html/html_style_element.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
Expand Down Expand Up @@ -1504,4 +1506,30 @@ TEST_F(StyleResolverTest, CascadeLayersInDifferentTreeScopes) {
&GetDocument());
}

// TODO(crbug.com/1095765): We should have a WPT for this test case, but
// currently Blink web test runner can't test @page rules in WPT.
TEST_F(StyleResolverTest, CascadeLayersAndPageRules) {
ScopedCSSCascadeLayersForTest enabled_scope(true);

GetDocument().documentElement()->setInnerHTML(R"HTML(
<style>
@layer {
@page { margin-top: 100px; }
}
@page { margin-top: 50px; }
</style>
)HTML");

constexpr FloatSize initial_page_size(800, 600);

GetDocument().GetFrame()->StartPrinting(initial_page_size, initial_page_size);
GetDocument().View()->UpdateLifecyclePhasesForPrinting();

WebPrintPageDescription description;
GetDocument().GetPageDescription(0, &description);

// The layered declaraion should win the cascading.
EXPECT_EQ(100, description.margin_top);
}

} // namespace blink
1 change: 1 addition & 0 deletions third_party/blink/renderer/core/css/rule_set.cc
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ void RuleSet::AddChildRules(const HeapVector<Member<StyleRuleBase>>& rules,
}
}
} else if (auto* page_rule = DynamicTo<StyleRulePage>(rule)) {
page_rule->SetCascadeLayer(cascade_layer);
AddPageRule(page_rule);
} else if (auto* media_rule = DynamicTo<StyleRuleMedia>(rule)) {
if (MatchMediaForAddRules(medium, media_rule->MediaQueries())) {
Expand Down
1 change: 1 addition & 0 deletions third_party/blink/renderer/core/css/style_rule.cc
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ MutableCSSPropertyValueSet& StyleRulePage::MutableProperties() {

void StyleRulePage::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(properties_);
visitor->Trace(layer_);
StyleRuleBase::TraceAfterDispatch(visitor);
}

Expand Down
4 changes: 4 additions & 0 deletions third_party/blink/renderer/core/css/style_rule.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,10 +200,14 @@ class StyleRulePage : public StyleRuleBase {
return MakeGarbageCollected<StyleRulePage>(*this);
}

void SetCascadeLayer(const CascadeLayer* layer) { layer_ = layer; }
const CascadeLayer* GetCascadeLayer() const { return layer_; }

void TraceAfterDispatch(blink::Visitor*) const;

private:
Member<CSSPropertyValueSet> properties_; // Cannot be null.
Member<const CascadeLayer> layer_;
CSSSelectorList selector_list_;
};

Expand Down

0 comments on commit 4a2ae1b

Please sign in to comment.