Commit f40b6a19 authored by Kent Tamura's avatar Kent Tamura Committed by Commit Bot

Slider NG: Add slider thumb positioning logic

This CL ports LayoutSliderTrack::UpdateLayout() to LayoutNG.

* Add NGLayoutInputNode::IsSliderThumb()
  - Add blink::IsSliderThumb() to shadow_element_utils.*.
  - Add two shadow pseudo names to shadow_element_names.json5.

* In NGBlockLayoutAlgorithm, if a child is a slider thumb, apply
  positioning logic dedicated to slider thumbs.

This CL has no behavior changes because input[type=range] still use the
legacy layout.

Bug: 1040826
Change-Id: Ie92272df888b063755a4686cd40f910e528d802d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2418136
Commit-Queue: Kent Tamura <tkent@chromium.org>
Reviewed-by: default avatarIan Kilpatrick <ikilpatrick@chromium.org>
Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Auto-Submit: Kent Tamura <tkent@chromium.org>
Cr-Commit-Position: refs/heads/master@{#810128}
parent 172b81f4
......@@ -270,22 +270,10 @@ HTMLInputElement* SliderThumbElement::HostInput() const {
return To<HTMLInputElement>(OwnerShadowHost());
}
static const AtomicString& SliderThumbShadowPartId() {
DEFINE_STATIC_LOCAL(const AtomicString, slider_thumb,
("-webkit-slider-thumb"));
return slider_thumb;
}
static const AtomicString& MediaSliderThumbShadowPartId() {
DEFINE_STATIC_LOCAL(const AtomicString, media_slider_thumb,
("-webkit-media-slider-thumb"));
return media_slider_thumb;
}
const AtomicString& SliderThumbElement::ShadowPseudoId() const {
HTMLInputElement* input = HostInput();
if (!input || !input->GetLayoutObject())
return SliderThumbShadowPartId();
return shadow_element_names::kPseudoSliderThumb;
const ComputedStyle& slider_style = input->GetLayoutObject()->StyleRef();
switch (slider_style.EffectiveAppearance()) {
......@@ -293,9 +281,9 @@ const AtomicString& SliderThumbElement::ShadowPseudoId() const {
case kMediaSliderThumbPart:
case kMediaVolumeSliderPart:
case kMediaVolumeSliderThumbPart:
return MediaSliderThumbShadowPartId();
return shadow_element_names::kPseudoMediaSliderThumb;
default:
return SliderThumbShadowPartId();
return shadow_element_names::kPseudoSliderThumb;
}
}
......
......@@ -101,6 +101,10 @@
name: "-webkit-media-slider-container",
Symbol: "kPseudoMediaSliderContainer",
},
{
name: "-webkit-media-slider-thumb",
Symbol: "kPseudoMediaSliderThumb",
},
{
name: "-webkit-meter-inner-element",
Symbol: "kPseudoMeterInnerElement",
......@@ -109,6 +113,10 @@
name: "-webkit-slider-container",
Symbol: "kPseudoSliderContainer",
},
{
name: "-webkit-slider-thumb",
Symbol: "kPseudoSliderThumb",
},
{
name: "-webkit-slider-runnable-track",
Symbol: "kPseudoSliderTrack",
......
......@@ -18,4 +18,13 @@ bool IsSliderContainer(const Element& element) {
shadow_pseudo == shadow_element_names::kPseudoSliderContainer;
}
bool IsSliderThumb(const Node* node) {
const auto* element = DynamicTo<Element>(node);
if (!element || !element->IsInUserAgentShadowRoot())
return false;
const AtomicString& shadow_pseudo = element->ShadowPseudoId();
return shadow_pseudo == shadow_element_names::kPseudoMediaSliderThumb ||
shadow_pseudo == shadow_element_names::kPseudoSliderThumb;
}
} // namespace blink
......@@ -8,8 +8,10 @@
namespace blink {
class Element;
class Node;
bool IsSliderContainer(const Element& elmenet);
bool IsSliderThumb(const Node* node);
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_SHADOW_SHADOW_ELEMENT_UTILS_H_
......@@ -10,6 +10,7 @@
#include "base/optional.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
......@@ -1822,6 +1823,8 @@ NGLayoutResult::EStatus NGBlockLayoutAlgorithm::FinishInflow(
LogicalOffset logical_offset = CalculateLogicalOffset(
fragment, layout_result->BfcLineOffset(), child_bfc_block_offset);
if (UNLIKELY(child.IsSliderThumb()))
logical_offset = AdjustSliderThumbInlineOffset(fragment, logical_offset);
if (ConstraintSpace().HasBlockFragmentation() &&
container_builder_.BfcBlockOffset() && child_bfc_block_offset) {
......@@ -2872,4 +2875,16 @@ void NGBlockLayoutAlgorithm::LayoutRubyText(
PropagateBaselineFromChild(ruby_text_fragment, ruby_text_box_top);
}
LogicalOffset NGBlockLayoutAlgorithm::AdjustSliderThumbInlineOffset(
const NGFragment& fragment,
const LogicalOffset& logical_offset) {
// See LayoutSliderTrack::UpdateLayout().
const LayoutUnit available_extent =
ChildAvailableSize().inline_size - fragment.InlineSize();
const auto* input =
To<HTMLInputElement>(Node().GetDOMNode()->OwnerShadowHost());
LayoutUnit offset(input->RatioValue().ToDouble() * available_extent);
return {logical_offset.inline_offset + offset, logical_offset.block_offset};
}
} // namespace blink
......@@ -343,6 +343,12 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
// |ruby_text_child|. This is called only if IsRubyText() returns true.
void LayoutRubyText(NGLayoutInputNode* ruby_text_child);
// Adjusts the inline offset of the slider thumb box from the value of
// HTMLInputElement.
LogicalOffset AdjustSliderThumbInlineOffset(
const NGFragment& fragment,
const LogicalOffset& logical_offset);
LogicalSize child_percentage_size_;
LogicalSize replaced_child_percentage_size_;
......
......@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/shadow/shadow_element_utils.h"
#include "third_party/blink/renderer/core/input_type_names.h"
#include "third_party/blink/renderer/core/layout/geometry/logical_size.h"
#include "third_party/blink/renderer/core/layout/intrinsic_sizing_info.h"
......@@ -71,6 +72,10 @@ bool NGLayoutInputNode::IsSlider() const {
return false;
}
bool NGLayoutInputNode::IsSliderThumb() const {
return IsBlock() && blink::IsSliderThumb(GetDOMNode());
}
bool NGLayoutInputNode::IsEmptyTableSection() const {
return box_->IsTableSection() && To<LayoutNGTableSection>(box_)->IsEmpty();
}
......
......@@ -137,6 +137,8 @@ class CORE_EXPORT NGLayoutInputNode {
}
// Return true if this node is for <input type=range>.
bool IsSlider() const;
// Return true if this node is for a slider thumb in <input type=range>.
bool IsSliderThumb() const;
bool IsTable() const { return IsBlock() && box_->IsTable(); }
bool IsTableCaption() const { return IsBlock() && box_->IsTableCaption(); }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment