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 { ...@@ -270,22 +270,10 @@ HTMLInputElement* SliderThumbElement::HostInput() const {
return To<HTMLInputElement>(OwnerShadowHost()); 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 { const AtomicString& SliderThumbElement::ShadowPseudoId() const {
HTMLInputElement* input = HostInput(); HTMLInputElement* input = HostInput();
if (!input || !input->GetLayoutObject()) if (!input || !input->GetLayoutObject())
return SliderThumbShadowPartId(); return shadow_element_names::kPseudoSliderThumb;
const ComputedStyle& slider_style = input->GetLayoutObject()->StyleRef(); const ComputedStyle& slider_style = input->GetLayoutObject()->StyleRef();
switch (slider_style.EffectiveAppearance()) { switch (slider_style.EffectiveAppearance()) {
...@@ -293,9 +281,9 @@ const AtomicString& SliderThumbElement::ShadowPseudoId() const { ...@@ -293,9 +281,9 @@ const AtomicString& SliderThumbElement::ShadowPseudoId() const {
case kMediaSliderThumbPart: case kMediaSliderThumbPart:
case kMediaVolumeSliderPart: case kMediaVolumeSliderPart:
case kMediaVolumeSliderThumbPart: case kMediaVolumeSliderThumbPart:
return MediaSliderThumbShadowPartId(); return shadow_element_names::kPseudoMediaSliderThumb;
default: default:
return SliderThumbShadowPartId(); return shadow_element_names::kPseudoSliderThumb;
} }
} }
......
...@@ -101,6 +101,10 @@ ...@@ -101,6 +101,10 @@
name: "-webkit-media-slider-container", name: "-webkit-media-slider-container",
Symbol: "kPseudoMediaSliderContainer", Symbol: "kPseudoMediaSliderContainer",
}, },
{
name: "-webkit-media-slider-thumb",
Symbol: "kPseudoMediaSliderThumb",
},
{ {
name: "-webkit-meter-inner-element", name: "-webkit-meter-inner-element",
Symbol: "kPseudoMeterInnerElement", Symbol: "kPseudoMeterInnerElement",
...@@ -109,6 +113,10 @@ ...@@ -109,6 +113,10 @@
name: "-webkit-slider-container", name: "-webkit-slider-container",
Symbol: "kPseudoSliderContainer", Symbol: "kPseudoSliderContainer",
}, },
{
name: "-webkit-slider-thumb",
Symbol: "kPseudoSliderThumb",
},
{ {
name: "-webkit-slider-runnable-track", name: "-webkit-slider-runnable-track",
Symbol: "kPseudoSliderTrack", Symbol: "kPseudoSliderTrack",
......
...@@ -18,4 +18,13 @@ bool IsSliderContainer(const Element& element) { ...@@ -18,4 +18,13 @@ bool IsSliderContainer(const Element& element) {
shadow_pseudo == shadow_element_names::kPseudoSliderContainer; 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 } // namespace blink
...@@ -8,8 +8,10 @@ ...@@ -8,8 +8,10 @@
namespace blink { namespace blink {
class Element; class Element;
class Node;
bool IsSliderContainer(const Element& elmenet); bool IsSliderContainer(const Element& elmenet);
bool IsSliderThumb(const Node* node);
} // namespace blink } // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_SHADOW_SHADOW_ELEMENT_UTILS_H_ #endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_SHADOW_SHADOW_ELEMENT_UTILS_H_
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/optional.h" #include "base/optional.h"
#include "third_party/blink/renderer/core/frame/web_feature.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/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_cursor.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
...@@ -1822,6 +1823,8 @@ NGLayoutResult::EStatus NGBlockLayoutAlgorithm::FinishInflow( ...@@ -1822,6 +1823,8 @@ NGLayoutResult::EStatus NGBlockLayoutAlgorithm::FinishInflow(
LogicalOffset logical_offset = CalculateLogicalOffset( LogicalOffset logical_offset = CalculateLogicalOffset(
fragment, layout_result->BfcLineOffset(), child_bfc_block_offset); fragment, layout_result->BfcLineOffset(), child_bfc_block_offset);
if (UNLIKELY(child.IsSliderThumb()))
logical_offset = AdjustSliderThumbInlineOffset(fragment, logical_offset);
if (ConstraintSpace().HasBlockFragmentation() && if (ConstraintSpace().HasBlockFragmentation() &&
container_builder_.BfcBlockOffset() && child_bfc_block_offset) { container_builder_.BfcBlockOffset() && child_bfc_block_offset) {
...@@ -2872,4 +2875,16 @@ void NGBlockLayoutAlgorithm::LayoutRubyText( ...@@ -2872,4 +2875,16 @@ void NGBlockLayoutAlgorithm::LayoutRubyText(
PropagateBaselineFromChild(ruby_text_fragment, ruby_text_box_top); 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 } // namespace blink
...@@ -343,6 +343,12 @@ class CORE_EXPORT NGBlockLayoutAlgorithm ...@@ -343,6 +343,12 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
// |ruby_text_child|. This is called only if IsRubyText() returns true. // |ruby_text_child|. This is called only if IsRubyText() returns true.
void LayoutRubyText(NGLayoutInputNode* ruby_text_child); 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 child_percentage_size_;
LogicalSize replaced_child_percentage_size_; LogicalSize replaced_child_percentage_size_;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h" #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/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/input_type_names.h"
#include "third_party/blink/renderer/core/layout/geometry/logical_size.h" #include "third_party/blink/renderer/core/layout/geometry/logical_size.h"
#include "third_party/blink/renderer/core/layout/intrinsic_sizing_info.h" #include "third_party/blink/renderer/core/layout/intrinsic_sizing_info.h"
...@@ -71,6 +72,10 @@ bool NGLayoutInputNode::IsSlider() const { ...@@ -71,6 +72,10 @@ bool NGLayoutInputNode::IsSlider() const {
return false; return false;
} }
bool NGLayoutInputNode::IsSliderThumb() const {
return IsBlock() && blink::IsSliderThumb(GetDOMNode());
}
bool NGLayoutInputNode::IsEmptyTableSection() const { bool NGLayoutInputNode::IsEmptyTableSection() const {
return box_->IsTableSection() && To<LayoutNGTableSection>(box_)->IsEmpty(); return box_->IsTableSection() && To<LayoutNGTableSection>(box_)->IsEmpty();
} }
......
...@@ -137,6 +137,8 @@ class CORE_EXPORT NGLayoutInputNode { ...@@ -137,6 +137,8 @@ class CORE_EXPORT NGLayoutInputNode {
} }
// Return true if this node is for <input type=range>. // Return true if this node is for <input type=range>.
bool IsSlider() const; 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 IsTable() const { return IsBlock() && box_->IsTable(); }
bool IsTableCaption() const { return IsBlock() && box_->IsTableCaption(); } 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