Chromium Code Reviews| Index: third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElement.cpp |
| diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElement.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElement.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c4618a7c024fa1b9e30471579e342b79885931c4 |
| --- /dev/null |
| +++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElement.cpp |
| @@ -0,0 +1,143 @@ |
| +// Copyright 2017 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "modules/media_controls/elements/MediaControlTimelineElement.h" |
| + |
| +#include "core/HTMLNames.h" |
| +#include "core/InputTypeNames.h" |
| +#include "core/events/Event.h" |
| +#include "core/events/KeyboardEvent.h" |
| +#include "core/events/MouseEvent.h" |
| +#include "core/events/PointerEvent.h" |
| +#include "core/html/HTMLMediaElement.h" |
| +#include "core/html/TimeRanges.h" |
| +#include "core/html/shadow/ShadowElementNames.h" |
| +#include "core/layout/LayoutBoxModelObject.h" |
| +#include "core/page/ChromeClient.h" |
| +#include "modules/media_controls/MediaControlsImpl.h" |
| +#include "modules/media_controls/elements/MediaControlElementsHelper.h" |
| +#include "public/platform/Platform.h" |
| +#include "public/platform/WebScreenInfo.h" |
| + |
| +namespace blink { |
| + |
| +MediaControlTimelineElement::MediaControlTimelineElement( |
| + MediaControlsImpl& media_controls) |
| + : MediaControlInputElement(media_controls, kMediaSlider) { |
| + EnsureUserAgentShadowRoot(); |
| + setType(InputTypeNames::range); |
| + setAttribute(HTMLNames::stepAttr, "any"); |
| + SetShadowPseudoId(AtomicString("-webkit-media-controls-timeline")); |
| +} |
| + |
| +bool MediaControlTimelineElement::WillRespondToMouseClickEvents() { |
| + return isConnected() && GetDocument().IsActive(); |
| +} |
| + |
| +void MediaControlTimelineElement::SetPosition(double current_time) { |
| + setValue(String::Number(current_time)); |
| + |
| + if (LayoutObject* layout_object = this->GetLayoutObject()) |
| + layout_object->SetShouldDoFullPaintInvalidation(); |
| +} |
| + |
| +void MediaControlTimelineElement::SetDuration(double duration) { |
| + SetFloatingPointAttribute(HTMLNames::maxAttr, |
| + std::isfinite(duration) ? duration : 0); |
| + |
| + if (LayoutObject* layout_object = this->GetLayoutObject()) |
| + layout_object->SetShouldDoFullPaintInvalidation(); |
| +} |
| + |
| +void MediaControlTimelineElement::OnPlaying() { |
| + Frame* frame = GetDocument().GetFrame(); |
| + if (!frame) |
| + return; |
| + metrics_.RecordPlaying( |
| + frame->GetChromeClient().GetScreenInfo().orientation_type, |
| + MediaElement().IsFullscreen(), TimelineWidth()); |
| +} |
| + |
| +void MediaControlTimelineElement::DefaultEventHandler(Event* event) { |
|
Zhiqiang Zhang (Slow)
2017/04/20 10:56:34
I know this method is old code, but it seems too l
mlamouri (slow - plz ping)
2017/04/20 14:17:20
I agree that this could be improved. Hopefully, we
|
| + if (event->IsMouseEvent() && |
| + ToMouseEvent(event)->button() != |
| + static_cast<short>(WebPointerProperties::Button::kLeft)) |
| + return; |
| + |
| + if (!isConnected() || !GetDocument().IsActive()) |
| + return; |
| + |
| + // TODO(crbug.com/706504): These should listen for pointerdown/up. |
| + if (event->type() == EventTypeNames::mousedown) |
| + static_cast<MediaControlsImpl&>(GetMediaControls()).BeginScrubbing(); |
| + if (event->type() == EventTypeNames::mouseup) |
| + static_cast<MediaControlsImpl&>(GetMediaControls()).EndScrubbing(); |
| + |
| + // Only respond to main button of primary pointer(s). |
| + if (event->IsPointerEvent() && ToPointerEvent(event)->isPrimary() && |
| + ToPointerEvent(event)->button() == |
| + static_cast<short>(WebPointerProperties::Button::kLeft)) { |
| + if (event->type() == EventTypeNames::pointerdown) { |
| + Platform::Current()->RecordAction( |
| + UserMetricsAction("Media.Controls.ScrubbingBegin")); |
| + static_cast<MediaControlsImpl&>(GetMediaControls()).BeginScrubbing(); |
| + Element* thumb = UserAgentShadowRoot()->GetElementById( |
| + ShadowElementNames::SliderThumb()); |
| + bool started_from_thumb = thumb && thumb == event->target()->ToNode(); |
| + metrics_.StartGesture(started_from_thumb); |
| + } |
| + if (event->type() == EventTypeNames::pointerup) { |
| + Platform::Current()->RecordAction( |
| + UserMetricsAction("Media.Controls.ScrubbingEnd")); |
| + static_cast<MediaControlsImpl&>(GetMediaControls()).EndScrubbing(); |
| + metrics_.RecordEndGesture(TimelineWidth(), MediaElement().duration()); |
| + } |
| + } |
| + |
| + if (event->type() == EventTypeNames::keydown) { |
| + metrics_.StartKey(); |
| + } |
| + if (event->type() == EventTypeNames::keyup && event->IsKeyboardEvent()) { |
| + metrics_.RecordEndKey(TimelineWidth(), ToKeyboardEvent(event)->keyCode()); |
| + } |
| + |
| + MediaControlInputElement::DefaultEventHandler(event); |
| + |
| + if (event->type() != EventTypeNames::input) |
| + return; |
| + |
| + double time = value().ToDouble(); |
| + |
| + double duration = MediaElement().duration(); |
| + // Workaround for floating point error - it's possible for this element's max |
| + // attribute to be rounded to a value slightly higher than the duration. If |
| + // this happens and scrubber is dragged near the max, seek to duration. |
| + if (time > duration) |
| + time = duration; |
| + |
| + metrics_.OnInput(MediaElement().currentTime(), time); |
| + |
| + // FIXME: This will need to take the timeline offset into consideration |
| + // once that concept is supported, see https://crbug.com/312699 |
| + if (MediaElement().seekable()->Contain(time)) |
| + MediaElement().setCurrentTime(time); |
| + |
| + // Provide immediate feedback (without waiting for media to seek) to make it |
| + // easier for user to seek to a precise time. |
| + static_cast<MediaControlsImpl&>(GetMediaControls()) |
| + .UpdateCurrentTimeDisplay(); |
| +} |
| + |
| +bool MediaControlTimelineElement::KeepEventInNode(Event* event) { |
| + return MediaControlElementsHelper::IsUserInteractionEventForSlider( |
| + event, GetLayoutObject()); |
| +} |
| + |
| +int MediaControlTimelineElement::TimelineWidth() { |
| + if (LayoutBoxModelObject* box = GetLayoutBoxModelObject()) |
| + return box->OffsetWidth().Round(); |
| + return 0; |
| +} |
| + |
| +} // namespace blink |