blob: 47f8941f14b53d2e865c6731cbed8e77e09f1092 [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// 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/layout/layout_ruby_as_block.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/layout/layout_ruby.h"
#include "third_party/blink/renderer/core/layout/layout_ruby_column.h"
#include "third_party/blink/renderer/core/layout/ruby_container.h"
namespace blink {
LayoutRubyAsBlock::LayoutRubyAsBlock(Element* element)
: LayoutNGBlockFlow(element),
ruby_container_(MakeGarbageCollected<RubyContainer>(*this)) {
UseCounter::Count(GetDocument(), WebFeature::kRenderRuby);
}
LayoutRubyAsBlock::~LayoutRubyAsBlock() = default;
void LayoutRubyAsBlock::Trace(Visitor* visitor) const {
visitor->Trace(ruby_container_);
LayoutNGBlockFlow::Trace(visitor);
}
void LayoutRubyAsBlock::AddChild(LayoutObject* child,
LayoutObject* before_child) {
NOT_DESTROYED();
if (RuntimeEnabledFeatures::BlockRubyWrappingInlineRubyEnabled()) {
LayoutObject* inline_ruby = FirstChild();
if (!inline_ruby) {
if (RuntimeEnabledFeatures::RubyLineBreakableEnabled()) {
inline_ruby = MakeGarbageCollected<LayoutInline>(nullptr);
} else {
inline_ruby = MakeGarbageCollected<LayoutRuby>(nullptr);
}
inline_ruby->SetDocumentForAnonymous(&GetDocument());
ComputedStyleBuilder new_style_builder =
GetDocument()
.GetStyleResolver()
.CreateAnonymousStyleBuilderWithDisplay(StyleRef(),
EDisplay::kRuby);
inline_ruby->SetStyle(new_style_builder.TakeStyle());
LayoutNGBlockFlow::AddChild(inline_ruby);
}
inline_ruby->AddChild(child, before_child);
return;
}
// If the child is a ruby column, just add it normally.
if (child->IsRubyColumn()) {
LayoutNGBlockFlow::AddChild(child, before_child);
return;
}
ruby_container_->AddChild(child, before_child);
}
void LayoutRubyAsBlock::RemoveChild(LayoutObject* child) {
NOT_DESTROYED();
if (RuntimeEnabledFeatures::BlockRubyWrappingInlineRubyEnabled()) {
if (child->Parent() == this) {
DCHECK(DynamicTo<LayoutRuby>(child));
LayoutNGBlockFlow::RemoveChild(child);
return;
}
NOTREACHED() << child;
return;
}
// If the child's parent is *this (must be a ruby column), just use the normal
// remove method.
if (child->Parent() == this) {
DCHECK(child->IsRubyColumn());
LayoutNGBlockFlow::RemoveChild(child);
return;
}
NOTREACHED() << child;
}
void LayoutRubyAsBlock::DidRemoveChildFromColumn(LayoutObject& child) {
DCHECK(!RuntimeEnabledFeatures::BlockRubyWrappingInlineRubyEnabled());
ruby_container_->DidRemoveChildFromColumn(child);
}
void LayoutRubyAsBlock::StyleDidChange(StyleDifference diff,
const ComputedStyle* old_style) {
NOT_DESTROYED();
LayoutNGBlockFlow::StyleDidChange(diff, old_style);
PropagateStyleToAnonymousChildren();
if (RuntimeEnabledFeatures::BlockRubyWrappingInlineRubyEnabled()) {
// Because LayoutInline::AnonymousHasStylePropagationOverride() returns
// true, PropagateStyleToAnonymousChildren() doesn't update the style of
// the LayoutRuby child.
if (auto* inline_ruby = FirstChild()) {
ComputedStyleBuilder new_style_builder =
GetDocument()
.GetStyleResolver()
.CreateAnonymousStyleBuilderWithDisplay(
StyleRef(), inline_ruby->StyleRef().Display());
UpdateAnonymousChildStyle(inline_ruby, new_style_builder);
inline_ruby->SetStyle(new_style_builder.TakeStyle());
}
}
}
void LayoutRubyAsBlock::RemoveLeftoverAnonymousBlock(LayoutBlock*) {
NOT_DESTROYED();
NOTREACHED();
}
} // namespace blink