diff options
Diffstat (limited to 'Source/WebCore/html/shadow/SliderThumbElement.cpp')
-rw-r--r-- | Source/WebCore/html/shadow/SliderThumbElement.cpp | 301 |
1 files changed, 162 insertions, 139 deletions
diff --git a/Source/WebCore/html/shadow/SliderThumbElement.cpp b/Source/WebCore/html/shadow/SliderThumbElement.cpp index 33dbf2e52..87a2e4d37 100644 --- a/Source/WebCore/html/shadow/SliderThumbElement.cpp +++ b/Source/WebCore/html/shadow/SliderThumbElement.cpp @@ -36,6 +36,7 @@ #include "CSSValueKeywords.h" #include "Event.h" #include "EventHandler.h" +#include "EventNames.h" #include "Frame.h" #include "HTMLInputElement.h" #include "HTMLParserIdioms.h" @@ -44,8 +45,9 @@ #include "RenderSlider.h" #include "RenderTheme.h" #include "ShadowRoot.h" +#include "StyleResolver.h" -#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS) +#if ENABLE(IOS_TOUCH_EVENTS) #include "Document.h" #include "Page.h" #include "TouchEvent.h" @@ -55,20 +57,20 @@ namespace WebCore { using namespace HTMLNames; -inline static Decimal sliderPosition(HTMLInputElement* element) +inline static Decimal sliderPosition(HTMLInputElement& element) { - const StepRange stepRange(element->createStepRange(RejectAny)); - const Decimal oldValue = parseToDecimalForNumberType(element->value(), stepRange.defaultValue()); + const StepRange stepRange(element.createStepRange(RejectAny)); + const Decimal oldValue = parseToDecimalForNumberType(element.value(), stepRange.defaultValue()); return stepRange.proportionFromValue(stepRange.clampValue(oldValue)); } -inline static bool hasVerticalAppearance(HTMLInputElement* input) +inline static bool hasVerticalAppearance(HTMLInputElement& input) { - ASSERT(input->renderer()); - const RenderStyle& sliderStyle = input->renderer()->style(); + ASSERT(input.renderer()); + const RenderStyle& sliderStyle = input.renderer()->style(); #if ENABLE(VIDEO) - if (sliderStyle.appearance() == MediaVolumeSliderPart && input->renderer()->theme().usesVerticalVolumeSlider()) + if (sliderStyle.appearance() == MediaVolumeSliderPart && input.renderer()->theme().usesVerticalVolumeSlider()) return true; #endif @@ -77,25 +79,27 @@ inline static bool hasVerticalAppearance(HTMLInputElement* input) // -------------------------------- -RenderSliderThumb::RenderSliderThumb(SliderThumbElement& element, PassRef<RenderStyle> style) - : RenderBlockFlow(element, std::move(style)) +RenderSliderThumb::RenderSliderThumb(SliderThumbElement& element, RenderStyle&& style) + : RenderBlockFlow(element, WTFMove(style)) { } -void RenderSliderThumb::updateAppearance(RenderStyle* parentStyle) +void RenderSliderThumb::updateAppearance(const RenderStyle* parentStyle) { if (parentStyle->appearance() == SliderVerticalPart) - style().setAppearance(SliderThumbVerticalPart); + mutableStyle().setAppearance(SliderThumbVerticalPart); else if (parentStyle->appearance() == SliderHorizontalPart) - style().setAppearance(SliderThumbHorizontalPart); + mutableStyle().setAppearance(SliderThumbHorizontalPart); else if (parentStyle->appearance() == MediaSliderPart) - style().setAppearance(MediaSliderThumbPart); + mutableStyle().setAppearance(MediaSliderThumbPart); else if (parentStyle->appearance() == MediaVolumeSliderPart) - style().setAppearance(MediaVolumeSliderThumbPart); + mutableStyle().setAppearance(MediaVolumeSliderThumbPart); else if (parentStyle->appearance() == MediaFullScreenVolumeSliderPart) - style().setAppearance(MediaFullScreenVolumeSliderThumbPart); - if (style().hasAppearance()) - theme().adjustSliderThumbSize(&style(), element()); + mutableStyle().setAppearance(MediaFullScreenVolumeSliderThumbPart); + if (style().hasAppearance()) { + ASSERT(element()); + theme().adjustSliderThumbSize(mutableStyle(), element()); + } } bool RenderSliderThumb::isSliderThumb() const @@ -107,27 +111,29 @@ bool RenderSliderThumb::isSliderThumb() const // FIXME: Find a way to cascade appearance and adjust heights, and get rid of this class. // http://webkit.org/b/62535 -class RenderSliderContainer : public RenderFlexibleBox { +class RenderSliderContainer final : public RenderFlexibleBox { public: - RenderSliderContainer(SliderContainerElement& element, PassRef<RenderStyle> style) - : RenderFlexibleBox(element, std::move(style)) + RenderSliderContainer(SliderContainerElement& element, RenderStyle&& style) + : RenderFlexibleBox(element, WTFMove(style)) { } public: - virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const override; + RenderBox::LogicalExtentComputedValues computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop) const override; private: - virtual void layout() override; + void layout() override; + bool isFlexibleBoxImpl() const override { return true; } }; -void RenderSliderContainer::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const +RenderBox::LogicalExtentComputedValues RenderSliderContainer::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop) const { - HTMLInputElement* input = element()->shadowHost()->toInputElement(); + ASSERT(element()->shadowHost()); + auto& input = downcast<HTMLInputElement>(*element()->shadowHost()); bool isVertical = hasVerticalAppearance(input); #if ENABLE(DATALIST_ELEMENT) - if (input->renderer()->isSlider() && !isVertical && input->list()) { + if (input.renderer()->isSlider() && !isVertical && input.list()) { int offsetFromCenter = theme().sliderTickOffsetFromTrackCenter(); LayoutUnit trackHeight = 0; if (offsetFromCenter < 0) @@ -140,30 +146,30 @@ void RenderSliderContainer::computeLogicalHeight(LayoutUnit logicalHeight, Layou if (zoomFactor != 1.0) trackHeight *= zoomFactor; - RenderBox::computeLogicalHeight(trackHeight, logicalTop, computedValues); - return; + return RenderBox::computeLogicalHeight(trackHeight, logicalTop); } #endif if (isVertical) logicalHeight = RenderSlider::defaultTrackLength; - RenderBox::computeLogicalHeight(logicalHeight, logicalTop, computedValues); + return RenderBox::computeLogicalHeight(logicalHeight, logicalTop); } void RenderSliderContainer::layout() { - HTMLInputElement* input = element()->shadowHost()->toInputElement(); + ASSERT(element()->shadowHost()); + auto& input = downcast<HTMLInputElement>(*element()->shadowHost()); bool isVertical = hasVerticalAppearance(input); - style().setFlexDirection(isVertical ? FlowColumn : FlowRow); + mutableStyle().setFlexDirection(isVertical ? FlowColumn : FlowRow); TextDirection oldTextDirection = style().direction(); if (isVertical) { // FIXME: Work around rounding issues in RTL vertical sliders. We want them to // render identically to LTR vertical sliders. We can remove this work around when // subpixel rendering is enabled on all ports. - style().setDirection(LTR); + mutableStyle().setDirection(LTR); } - RenderBox* thumb = input->sliderThumbElement() ? input->sliderThumbElement()->renderBox() : 0; - RenderBox* track = input->sliderTrackElement() ? input->sliderTrackElement()->renderBox() : 0; + RenderBox* thumb = input.sliderThumbElement() ? input.sliderThumbElement()->renderBox() : nullptr; + RenderBox* track = input.sliderTrackElement() ? input.sliderTrackElement()->renderBox() : nullptr; // Force a layout to reset the position of the thumb so the code below doesn't move the thumb to the wrong place. // FIXME: Make a custom Render class for the track and move the thumb positioning code there. if (track) @@ -171,7 +177,7 @@ void RenderSliderContainer::layout() RenderFlexibleBox::layout(); - style().setDirection(oldTextDirection); + mutableStyle().setDirection(oldTextDirection); // These should always exist, unless someone mutates the shadow DOM (e.g., in the inspector). if (!thumb || !track) return; @@ -188,6 +194,7 @@ void RenderSliderContainer::layout() else thumbLocation.setX(thumbLocation.x() - offset); thumb->setLocation(thumbLocation); + thumb->repaint(); } // -------------------------------- @@ -195,7 +202,7 @@ void RenderSliderContainer::layout() SliderThumbElement::SliderThumbElement(Document& document) : HTMLDivElement(HTMLNames::divTag, document) , m_inDragMode(false) -#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS) +#if ENABLE(IOS_TOUCH_EVENTS) , m_exclusiveTouchIdentifier(NoIdentifier) , m_isRegisteredAsTouchEventListener(false) #endif @@ -212,9 +219,9 @@ void SliderThumbElement::setPositionFromValue() renderer()->setNeedsLayout(); } -RenderPtr<RenderElement> SliderThumbElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SliderThumbElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderSliderThumb>(*this, std::move(style)); + return createRenderer<RenderSliderThumb>(*this, WTFMove(style)); } bool SliderThumbElement::isDisabledFormControl() const @@ -223,12 +230,6 @@ bool SliderThumbElement::isDisabledFormControl() const return !input || input->isDisabledFormControl(); } -bool SliderThumbElement::matchesReadOnlyPseudoClass() const -{ - HTMLInputElement* input = hostInput(); - return input && input->matchesReadOnlyPseudoClass(); -} - bool SliderThumbElement::matchesReadWritePseudoClass() const { HTMLInputElement* input = hostInput(); @@ -242,7 +243,7 @@ Element* SliderThumbElement::focusDelegate() void SliderThumbElement::dragFrom(const LayoutPoint& point) { - Ref<SliderThumbElement> protect(*this); + Ref<SliderThumbElement> protectedThis(*this); setPositionFromPoint(point); #if !PLATFORM(IOS) startDragging(); @@ -252,52 +253,56 @@ void SliderThumbElement::dragFrom(const LayoutPoint& point) void SliderThumbElement::setPositionFromPoint(const LayoutPoint& absolutePoint) { RefPtr<HTMLInputElement> input = hostInput(); - if (!input || !input->renderer() || !renderBox()) + if (!input) return; - HTMLElement* trackElement = input->sliderTrackElement(); - if (!trackElement->renderBox()) + auto* inputRenderer = input->renderBox(); + if (!inputRenderer) return; - input->setTextAsOfLastFormControlChangeEvent(input->value()); + auto* thumbRenderer = renderBox(); + if (!thumbRenderer) + return; + + ASSERT(input->sliderTrackElement()); + auto* trackRenderer = input->sliderTrackElement()->renderBox(); + if (!trackRenderer) + return; // Do all the tracking math relative to the input's renderer's box. - RenderBox& inputRenderer = *toRenderBox(input->renderer()); - RenderBox& trackRenderer = *trackElement->renderBox(); - bool isVertical = hasVerticalAppearance(input.get()); - bool isLeftToRightDirection = renderBox()->style().isLeftToRightDirection(); + bool isVertical = hasVerticalAppearance(*input); + bool isLeftToRightDirection = thumbRenderer->style().isLeftToRightDirection(); - LayoutPoint offset = roundedLayoutPoint(inputRenderer.absoluteToLocal(absolutePoint, UseTransforms)); - FloatRect trackBoundingBox = trackRenderer.localToContainerQuad(FloatRect(0, 0, trackRenderer.width(), trackRenderer.height()), &inputRenderer).enclosingBoundingBox(); + auto offset = inputRenderer->absoluteToLocal(absolutePoint, UseTransforms); + auto trackBoundingBox = trackRenderer->localToContainerQuad(FloatRect { { }, trackRenderer->size() }, inputRenderer).enclosingBoundingBox(); LayoutUnit trackLength; LayoutUnit position; if (isVertical) { - trackLength = trackRenderer.contentHeight() - renderBox()->height(); - position = offset.y() - renderBox()->height() / 2 - trackBoundingBox.y() - renderBox()->marginBottom(); + trackLength = trackRenderer->contentHeight() - thumbRenderer->height(); + position = offset.y() - thumbRenderer->height() / 2 - trackBoundingBox.y() - thumbRenderer->marginBottom(); } else { - trackLength = trackRenderer.contentWidth() - renderBox()->width(); - position = offset.x() - renderBox()->width() / 2 - trackBoundingBox.x(); - position -= isLeftToRightDirection ? renderBox()->marginLeft() : renderBox()->marginRight(); + trackLength = trackRenderer->contentWidth() - thumbRenderer->width(); + position = offset.x() - thumbRenderer->width() / 2 - trackBoundingBox.x(); + position -= isLeftToRightDirection ? thumbRenderer->marginLeft() : thumbRenderer->marginRight(); } position = std::max<LayoutUnit>(0, std::min(position, trackLength)); - const Decimal ratio = Decimal::fromDouble(static_cast<double>(position) / trackLength); - const Decimal fraction = isVertical || !isLeftToRightDirection ? Decimal(1) - ratio : ratio; - StepRange stepRange(input->createStepRange(RejectAny)); - Decimal value = stepRange.clampValue(stepRange.valueFromProportion(fraction)); + auto ratio = Decimal::fromDouble(static_cast<double>(position) / trackLength); + auto fraction = isVertical || !isLeftToRightDirection ? Decimal(1) - ratio : ratio; + auto stepRange = input->createStepRange(RejectAny); + auto value = stepRange.clampValue(stepRange.valueFromProportion(fraction)); #if ENABLE(DATALIST_ELEMENT) const LayoutUnit snappingThreshold = renderer()->theme().sliderTickSnappingThreshold(); if (snappingThreshold > 0) { - Decimal closest = input->findClosestTickMarkValue(value); - if (closest.isFinite()) { - double closestFraction = stepRange.proportionFromValue(closest).toDouble(); + if (std::optional<Decimal> closest = input->findClosestTickMarkValue(value)) { + double closestFraction = stepRange.proportionFromValue(*closest).toDouble(); double closestRatio = isVertical || !isLeftToRightDirection ? 1.0 - closestFraction : closestFraction; LayoutUnit closestPosition = trackLength * closestRatio; if ((closestPosition - position).abs() <= snappingThreshold) - value = closest; + value = *closest; } } #endif @@ -310,7 +315,6 @@ void SliderThumbElement::setPositionFromPoint(const LayoutPoint& absolutePoint) input->setValueFromRenderer(valueString); if (renderer()) renderer()->setNeedsLayout(); - input->dispatchFormControlChangeEvent(); } void SliderThumbElement::startDragging() @@ -334,9 +338,9 @@ void SliderThumbElement::stopDragging() } #if !PLATFORM(IOS) -void SliderThumbElement::defaultEventHandler(Event* event) +void SliderThumbElement::defaultEventHandler(Event& event) { - if (!event->isMouseEvent()) { + if (!is<MouseEvent>(event)) { HTMLDivElement::defaultEventHandler(event); return; } @@ -344,15 +348,15 @@ void SliderThumbElement::defaultEventHandler(Event* event) // FIXME: Should handle this readonly/disabled check in more general way. // Missing this kind of check is likely to occur elsewhere if adding it in each shadow element. HTMLInputElement* input = hostInput(); - if (!input || input->isDisabledOrReadOnly()) { + if (!input || input->isDisabledFormControl()) { stopDragging(); HTMLDivElement::defaultEventHandler(event); return; } - MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); - bool isLeftButton = mouseEvent->button() == LeftButton; - const AtomicString& eventType = event->type(); + MouseEvent& mouseEvent = downcast<MouseEvent>(event); + bool isLeftButton = mouseEvent.button() == LeftButton; + const AtomicString& eventType = mouseEvent.type(); // We intentionally do not call event->setDefaultHandled() here because // MediaControlTimelineElement::defaultEventHandler() wants to handle these @@ -361,15 +365,16 @@ void SliderThumbElement::defaultEventHandler(Event* event) startDragging(); return; } else if (eventType == eventNames().mouseupEvent && isLeftButton) { + input->dispatchFormControlChangeEvent(); stopDragging(); return; } else if (eventType == eventNames().mousemoveEvent) { if (m_inDragMode) - setPositionFromPoint(mouseEvent->absoluteLocation()); + setPositionFromPoint(mouseEvent.absoluteLocation()); return; } - HTMLDivElement::defaultEventHandler(event); + HTMLDivElement::defaultEventHandler(mouseEvent); } #endif @@ -377,7 +382,7 @@ void SliderThumbElement::defaultEventHandler(Event* event) bool SliderThumbElement::willRespondToMouseMoveEvents() { const HTMLInputElement* input = hostInput(); - if (input && !input->isDisabledOrReadOnly() && m_inDragMode) + if (input && !input->isDisabledFormControl() && m_inDragMode) return true; return HTMLDivElement::willRespondToMouseMoveEvents(); @@ -386,7 +391,7 @@ bool SliderThumbElement::willRespondToMouseMoveEvents() bool SliderThumbElement::willRespondToMouseClickEvents() { const HTMLInputElement* input = hostInput(); - if (input && !input->isDisabledOrReadOnly()) + if (input && !input->isDisabledFormControl()) return true; return HTMLDivElement::willRespondToMouseClickEvents(); @@ -399,12 +404,12 @@ void SliderThumbElement::willDetachRenderers() if (Frame* frame = document().frame()) frame->eventHandler().setCapturingMouseEventsElement(nullptr); } -#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS) +#if ENABLE(IOS_TOUCH_EVENTS) unregisterForTouchEvents(); #endif } -#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS) +#if ENABLE(IOS_TOUCH_EVENTS) unsigned SliderThumbElement::exclusiveTouchIdentifier() const { return m_exclusiveTouchIdentifier; @@ -421,64 +426,79 @@ void SliderThumbElement::clearExclusiveTouchIdentifier() m_exclusiveTouchIdentifier = NoIdentifier; } -static Touch* findTouchWithIdentifier(TouchList* list, unsigned identifier) +static Touch* findTouchWithIdentifier(TouchList& list, unsigned identifier) { - unsigned length = list->length(); + unsigned length = list.length(); for (unsigned i = 0; i < length; ++i) { - Touch* touch = list->item(i); + Touch* touch = list.item(i); if (touch->identifier() == identifier) return touch; } return nullptr; } -void SliderThumbElement::handleTouchStart(TouchEvent* touchEvent) +void SliderThumbElement::handleTouchStart(TouchEvent& touchEvent) { - TouchList* targetTouches = touchEvent->targetTouches(); + TouchList* targetTouches = touchEvent.targetTouches(); + if (!targetTouches) + return; + if (targetTouches->length() != 1) return; - // Ignore the touch if it is not really inside the thumb. Touch* touch = targetTouches->item(0); + if (!renderer()) + return; IntRect boundingBox = renderer()->absoluteBoundingBoxRect(); + // Ignore the touch if it is not really inside the thumb. if (!boundingBox.contains(touch->pageX(), touch->pageY())) return; setExclusiveTouchIdentifier(touch->identifier()); startDragging(); - touchEvent->setDefaultHandled(); + touchEvent.setDefaultHandled(); } -void SliderThumbElement::handleTouchMove(TouchEvent* touchEvent) +void SliderThumbElement::handleTouchMove(TouchEvent& touchEvent) { unsigned identifier = exclusiveTouchIdentifier(); if (identifier == NoIdentifier) return; - Touch* touch = findTouchWithIdentifier(touchEvent->targetTouches(), identifier); + TouchList* targetTouches = touchEvent.targetTouches(); + if (!targetTouches) + return; + + Touch* touch = findTouchWithIdentifier(*targetTouches, identifier); if (!touch) return; if (m_inDragMode) setPositionFromPoint(IntPoint(touch->pageX(), touch->pageY())); - touchEvent->setDefaultHandled(); + touchEvent.setDefaultHandled(); } -void SliderThumbElement::handleTouchEndAndCancel(TouchEvent* touchEvent) +void SliderThumbElement::handleTouchEndAndCancel(TouchEvent& touchEvent) { unsigned identifier = exclusiveTouchIdentifier(); if (identifier == NoIdentifier) return; + TouchList* targetTouches = touchEvent.targetTouches(); + if (!targetTouches) + return; // If our exclusive touch still exists, it was not the touch // that ended, so we should not stop dragging. - Touch* exclusiveTouch = findTouchWithIdentifier(touchEvent->targetTouches(), identifier); + Touch* exclusiveTouch = findTouchWithIdentifier(*targetTouches, identifier); if (exclusiveTouch) return; clearExclusiveTouchIdentifier(); + RefPtr<HTMLInputElement> input = hostInput(); + if (input) + input->dispatchFormControlChangeEvent(); stopDragging(); } @@ -488,19 +508,19 @@ void SliderThumbElement::didAttachRenderers() registerForTouchEvents(); } -void SliderThumbElement::handleTouchEvent(TouchEvent* touchEvent) +void SliderThumbElement::handleTouchEvent(TouchEvent& touchEvent) { HTMLInputElement* input = hostInput(); ASSERT(input); if (input->isReadOnly() || input->isDisabledFormControl()) { clearExclusiveTouchIdentifier(); stopDragging(); - touchEvent->setDefaultHandled(); + touchEvent.setDefaultHandled(); HTMLDivElement::defaultEventHandler(touchEvent); return; } - const AtomicString& eventType = touchEvent->type(); + const AtomicString& eventType = touchEvent.type(); if (eventType == eventNames().touchstartEvent) { handleTouchStart(touchEvent); return; @@ -529,7 +549,7 @@ void SliderThumbElement::registerForTouchEvents() ASSERT(shouldAcceptTouchEvents()); - document().addTouchEventListener(this); + document().addTouchEventHandler(this); m_isRegisteredAsTouchEventListener = true; } @@ -541,7 +561,7 @@ void SliderThumbElement::unregisterForTouchEvents() clearExclusiveTouchIdentifier(); stopDragging(); - document().removeTouchEventListener(this); + document().removeTouchEventHandler(this); m_isRegisteredAsTouchEventListener = false; } @@ -552,53 +572,49 @@ void SliderThumbElement::disabledAttributeChanged() else unregisterForTouchEvents(); } -#endif // ENABLE(TOUCH_EVENTS) && PLATFORM(IOS) +#endif // ENABLE(IOS_TOUCH_EVENTS) HTMLInputElement* SliderThumbElement::hostInput() const { // Only HTMLInputElement creates SliderThumbElement instances as its shadow nodes. // So, shadowHost() must be an HTMLInputElement. - Element* host = shadowHost(); - return host ? host->toInputElement() : 0; + return downcast<HTMLInputElement>(shadowHost()); } -static const AtomicString& sliderThumbShadowPseudoId() +std::optional<ElementStyle> SliderThumbElement::resolveCustomStyle(const RenderStyle&, const RenderStyle* hostStyle) { - DEFINE_STATIC_LOCAL(const AtomicString, sliderThumb, ("-webkit-slider-thumb", AtomicString::ConstructFromLiteral)); - return sliderThumb; -} + // This doesn't actually compute style. This is just a hack to pick shadow pseudo id when host style is known. -static const AtomicString& mediaSliderThumbShadowPseudoId() -{ - DEFINE_STATIC_LOCAL(const AtomicString, mediaSliderThumb, ("-webkit-media-slider-thumb", AtomicString::ConstructFromLiteral)); - return mediaSliderThumb; -} + static NeverDestroyed<const AtomicString> sliderThumbShadowPseudoId("-webkit-slider-thumb", AtomicString::ConstructFromLiteral); + static NeverDestroyed<const AtomicString> mediaSliderThumbShadowPseudoId("-webkit-media-slider-thumb", AtomicString::ConstructFromLiteral); -const AtomicString& SliderThumbElement::shadowPseudoId() const -{ - HTMLInputElement* input = hostInput(); - if (!input) - return sliderThumbShadowPseudoId(); - if (!input->renderer()) - return emptyAtom; + if (!hostStyle) + return std::nullopt; - const RenderStyle& sliderStyle = input->renderer()->style(); - switch (sliderStyle.appearance()) { + switch (hostStyle->appearance()) { case MediaSliderPart: case MediaSliderThumbPart: case MediaVolumeSliderPart: case MediaVolumeSliderThumbPart: case MediaFullScreenVolumeSliderPart: case MediaFullScreenVolumeSliderThumbPart: - return mediaSliderThumbShadowPseudoId(); + m_shadowPseudoId = mediaSliderThumbShadowPseudoId; + break; default: - return sliderThumbShadowPseudoId(); + m_shadowPseudoId = sliderThumbShadowPseudoId; } + + return std::nullopt; +} + +const AtomicString& SliderThumbElement::shadowPseudoId() const +{ + return m_shadowPseudoId; } -PassRefPtr<Element> SliderThumbElement::cloneElementWithoutAttributesAndChildren() +Ref<Element> SliderThumbElement::cloneElementWithoutAttributesAndChildren(Document& targetDocument) { - return create(document()); + return create(targetDocument); } // -------------------------------- @@ -606,41 +622,48 @@ PassRefPtr<Element> SliderThumbElement::cloneElementWithoutAttributesAndChildren inline SliderContainerElement::SliderContainerElement(Document& document) : HTMLDivElement(HTMLNames::divTag, document) { + setHasCustomStyleResolveCallbacks(); } -PassRefPtr<SliderContainerElement> SliderContainerElement::create(Document& document) +Ref<SliderContainerElement> SliderContainerElement::create(Document& document) { - return adoptRef(new SliderContainerElement(document)); + return adoptRef(*new SliderContainerElement(document)); } -RenderPtr<RenderElement> SliderContainerElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SliderContainerElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderSliderContainer>(*this, std::move(style)); + return createRenderer<RenderSliderContainer>(*this, WTFMove(style)); } -const AtomicString& SliderContainerElement::shadowPseudoId() const +std::optional<ElementStyle> SliderContainerElement::resolveCustomStyle(const RenderStyle&, const RenderStyle* hostStyle) { - DEFINE_STATIC_LOCAL(const AtomicString, mediaSliderContainer, ("-webkit-media-slider-container", AtomicString::ConstructFromLiteral)); - DEFINE_STATIC_LOCAL(const AtomicString, sliderContainer, ("-webkit-slider-container", AtomicString::ConstructFromLiteral)); + // This doesn't actually compute style. This is just a hack to pick shadow pseudo id when host style is known. - HTMLInputElement* input = shadowHost()->toInputElement(); - if (!input) - return sliderContainer; - if (!input->renderer()) - return emptyAtom; + static NeverDestroyed<const AtomicString> mediaSliderContainer("-webkit-media-slider-container", AtomicString::ConstructFromLiteral); + static NeverDestroyed<const AtomicString> sliderContainer("-webkit-slider-container", AtomicString::ConstructFromLiteral); + + if (!hostStyle) + return std::nullopt; - const RenderStyle& sliderStyle = input->renderer()->style(); - switch (sliderStyle.appearance()) { + switch (hostStyle->appearance()) { case MediaSliderPart: case MediaSliderThumbPart: case MediaVolumeSliderPart: case MediaVolumeSliderThumbPart: case MediaFullScreenVolumeSliderPart: case MediaFullScreenVolumeSliderThumbPart: - return mediaSliderContainer; + m_shadowPseudoId = mediaSliderContainer; + break; default: - return sliderContainer; + m_shadowPseudoId = sliderContainer; } + + return std::nullopt; +} + +const AtomicString& SliderContainerElement::shadowPseudoId() const +{ + return m_shadowPseudoId; } } |