| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2012 Google Inc. All rights reserved. | 3 * Copyright (C) 2012 Google Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * | 8 * |
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 | 29 |
| 30 #include "core/html/shadow/MediaControlElements.h" | 30 #include "core/html/shadow/MediaControlElements.h" |
| 31 | 31 |
| 32 #include "bindings/core/v8/ExceptionState.h" | 32 #include "bindings/core/v8/ExceptionState.h" |
| 33 #include "core/InputTypeNames.h" | 33 #include "core/InputTypeNames.h" |
| 34 #include "core/dom/ClientRect.h" | 34 #include "core/dom/ClientRect.h" |
| 35 #include "core/dom/TaskRunnerHelper.h" | 35 #include "core/dom/TaskRunnerHelper.h" |
| 36 #include "core/dom/Text.h" | 36 #include "core/dom/Text.h" |
| 37 #include "core/dom/shadow/ShadowRoot.h" | 37 #include "core/dom/shadow/ShadowRoot.h" |
| 38 #include "core/events/KeyboardEvent.h" | 38 #include "core/events/KeyboardEvent.h" |
| 39 #include "core/events/MouseEvent.h" | |
| 40 #include "core/frame/LocalFrame.h" | 39 #include "core/frame/LocalFrame.h" |
| 41 #include "core/frame/UseCounter.h" | 40 #include "core/frame/UseCounter.h" |
| 42 #include "core/html/HTMLVideoElement.h" | 41 #include "core/html/HTMLVideoElement.h" |
| 43 #include "core/html/TimeRanges.h" | |
| 44 #include "core/html/media/MediaControls.h" | 42 #include "core/html/media/MediaControls.h" |
| 45 #include "core/html/shadow/ShadowElementNames.h" | 43 #include "core/html/shadow/ShadowElementNames.h" |
| 46 #include "core/html/track/TextTrackList.h" | 44 #include "core/html/track/TextTrackList.h" |
| 47 #include "core/input/EventHandler.h" | 45 #include "core/input/EventHandler.h" |
| 48 #include "core/layout/LayoutBoxModelObject.h" | 46 #include "core/layout/LayoutBoxModelObject.h" |
| 49 #include "core/layout/api/LayoutSliderItem.h" | 47 #include "core/layout/api/LayoutSliderItem.h" |
| 50 #include "core/page/ChromeClient.h" | |
| 51 #include "platform/Histogram.h" | 48 #include "platform/Histogram.h" |
| 52 #include "platform/RuntimeEnabledFeatures.h" | 49 #include "platform/RuntimeEnabledFeatures.h" |
| 53 #include "public/platform/Platform.h" | 50 #include "public/platform/Platform.h" |
| 54 #include "public/platform/UserMetricsAction.h" | 51 #include "public/platform/UserMetricsAction.h" |
| 55 #include "public/platform/WebScreenInfo.h" | |
| 56 | 52 |
| 57 namespace blink { | 53 namespace blink { |
| 58 | 54 |
| 59 using namespace HTMLNames; | 55 using namespace HTMLNames; |
| 60 | 56 |
| 61 namespace { | 57 namespace { |
| 62 | 58 |
| 63 bool IsUserInteractionEvent(Event* event) { | 59 bool IsUserInteractionEvent(Event* event) { |
| 64 const AtomicString& type = event->type(); | 60 const AtomicString& type = event->type(); |
| 65 return type == EventTypeNames::mousedown || type == EventTypeNames::mouseup || | 61 return type == EventTypeNames::mousedown || type == EventTypeNames::mouseup || |
| (...skipping 23 matching lines...) Expand all Loading... |
| 89 return type == EventTypeNames::mouseover || | 85 return type == EventTypeNames::mouseover || |
| 90 type == EventTypeNames::mouseout || | 86 type == EventTypeNames::mouseout || |
| 91 type == EventTypeNames::mousemove || | 87 type == EventTypeNames::mousemove || |
| 92 type == EventTypeNames::pointerover || | 88 type == EventTypeNames::pointerover || |
| 93 type == EventTypeNames::pointerout || | 89 type == EventTypeNames::pointerout || |
| 94 type == EventTypeNames::pointermove; | 90 type == EventTypeNames::pointermove; |
| 95 } | 91 } |
| 96 | 92 |
| 97 } // anonymous namespace | 93 } // anonymous namespace |
| 98 | 94 |
| 99 // ---------------------------- | |
| 100 | |
| 101 MediaControlTimelineElement::MediaControlTimelineElement( | |
| 102 MediaControls& media_controls) | |
| 103 : MediaControlInputElement(media_controls, kMediaSlider) {} | |
| 104 | |
| 105 MediaControlTimelineElement* MediaControlTimelineElement::Create( | |
| 106 MediaControls& media_controls) { | |
| 107 MediaControlTimelineElement* timeline = | |
| 108 new MediaControlTimelineElement(media_controls); | |
| 109 timeline->EnsureUserAgentShadowRoot(); | |
| 110 timeline->setType(InputTypeNames::range); | |
| 111 timeline->setAttribute(stepAttr, "any"); | |
| 112 timeline->SetShadowPseudoId(AtomicString("-webkit-media-controls-timeline")); | |
| 113 return timeline; | |
| 114 } | |
| 115 | |
| 116 void MediaControlTimelineElement::DefaultEventHandler(Event* event) { | |
| 117 if (event->IsMouseEvent() && | |
| 118 ToMouseEvent(event)->button() != | |
| 119 static_cast<short>(WebPointerProperties::Button::kLeft)) | |
| 120 return; | |
| 121 | |
| 122 if (!isConnected() || !GetDocument().IsActive()) | |
| 123 return; | |
| 124 | |
| 125 // TODO(crbug.com/706504): These should listen for pointerdown/up. | |
| 126 if (event->type() == EventTypeNames::mousedown) | |
| 127 GetMediaControls().BeginScrubbing(); | |
| 128 if (event->type() == EventTypeNames::mouseup) | |
| 129 GetMediaControls().EndScrubbing(); | |
| 130 | |
| 131 // Only respond to main button of primary pointer(s). | |
| 132 if (event->IsPointerEvent() && ToPointerEvent(event)->isPrimary() && | |
| 133 ToPointerEvent(event)->button() == | |
| 134 static_cast<short>(WebPointerProperties::Button::kLeft)) { | |
| 135 if (event->type() == EventTypeNames::pointerdown) { | |
| 136 Platform::Current()->RecordAction( | |
| 137 UserMetricsAction("Media.Controls.ScrubbingBegin")); | |
| 138 GetMediaControls().BeginScrubbing(); | |
| 139 Element* thumb = UserAgentShadowRoot()->GetElementById( | |
| 140 ShadowElementNames::SliderThumb()); | |
| 141 bool started_from_thumb = thumb && thumb == event->target()->ToNode(); | |
| 142 metrics_.StartGesture(started_from_thumb); | |
| 143 } | |
| 144 if (event->type() == EventTypeNames::pointerup) { | |
| 145 Platform::Current()->RecordAction( | |
| 146 UserMetricsAction("Media.Controls.ScrubbingEnd")); | |
| 147 GetMediaControls().EndScrubbing(); | |
| 148 metrics_.RecordEndGesture(TimelineWidth(), MediaElement().duration()); | |
| 149 } | |
| 150 } | |
| 151 | |
| 152 if (event->type() == EventTypeNames::keydown) { | |
| 153 metrics_.StartKey(); | |
| 154 } | |
| 155 if (event->type() == EventTypeNames::keyup && event->IsKeyboardEvent()) { | |
| 156 metrics_.RecordEndKey(TimelineWidth(), ToKeyboardEvent(event)->keyCode()); | |
| 157 } | |
| 158 | |
| 159 MediaControlInputElement::DefaultEventHandler(event); | |
| 160 | |
| 161 if (event->type() != EventTypeNames::input) | |
| 162 return; | |
| 163 | |
| 164 double time = value().ToDouble(); | |
| 165 | |
| 166 double duration = MediaElement().duration(); | |
| 167 // Workaround for floating point error - it's possible for this element's max | |
| 168 // attribute to be rounded to a value slightly higher than the duration. If | |
| 169 // this happens and scrubber is dragged near the max, seek to duration. | |
| 170 if (time > duration) | |
| 171 time = duration; | |
| 172 | |
| 173 metrics_.OnInput(MediaElement().currentTime(), time); | |
| 174 | |
| 175 // FIXME: This will need to take the timeline offset into consideration | |
| 176 // once that concept is supported, see https://crbug.com/312699 | |
| 177 if (MediaElement().seekable()->Contain(time)) | |
| 178 MediaElement().setCurrentTime(time); | |
| 179 | |
| 180 // Provide immediate feedback (without waiting for media to seek) to make it | |
| 181 // easier for user to seek to a precise time. | |
| 182 GetMediaControls().UpdateCurrentTimeDisplay(); | |
| 183 } | |
| 184 | |
| 185 bool MediaControlTimelineElement::WillRespondToMouseClickEvents() { | |
| 186 return isConnected() && GetDocument().IsActive(); | |
| 187 } | |
| 188 | |
| 189 void MediaControlTimelineElement::SetPosition(double current_time) { | |
| 190 setValue(String::Number(current_time)); | |
| 191 | |
| 192 if (LayoutObject* layout_object = this->GetLayoutObject()) | |
| 193 layout_object->SetShouldDoFullPaintInvalidation(); | |
| 194 } | |
| 195 | |
| 196 void MediaControlTimelineElement::SetDuration(double duration) { | |
| 197 SetFloatingPointAttribute(maxAttr, std::isfinite(duration) ? duration : 0); | |
| 198 | |
| 199 if (LayoutObject* layout_object = this->GetLayoutObject()) | |
| 200 layout_object->SetShouldDoFullPaintInvalidation(); | |
| 201 } | |
| 202 | |
| 203 void MediaControlTimelineElement::OnPlaying() { | |
| 204 Frame* frame = GetDocument().GetFrame(); | |
| 205 if (!frame) | |
| 206 return; | |
| 207 metrics_.RecordPlaying( | |
| 208 frame->GetChromeClient().GetScreenInfo().orientation_type, | |
| 209 MediaElement().IsFullscreen(), TimelineWidth()); | |
| 210 } | |
| 211 | |
| 212 bool MediaControlTimelineElement::KeepEventInNode(Event* event) { | |
| 213 return IsUserInteractionEventForSlider(event, GetLayoutObject()); | |
| 214 } | |
| 215 | |
| 216 int MediaControlTimelineElement::TimelineWidth() { | |
| 217 if (LayoutBoxModelObject* box = GetLayoutBoxModelObject()) | |
| 218 return box->OffsetWidth().Round(); | |
| 219 return 0; | |
| 220 } | |
| 221 | |
| 222 // ---------------------------- | |
| 223 | |
| 224 MediaControlVolumeSliderElement::MediaControlVolumeSliderElement( | 95 MediaControlVolumeSliderElement::MediaControlVolumeSliderElement( |
| 225 MediaControls& media_controls) | 96 MediaControls& media_controls) |
| 226 : MediaControlInputElement(media_controls, kMediaVolumeSlider) {} | 97 : MediaControlInputElement(media_controls, kMediaVolumeSlider) {} |
| 227 | 98 |
| 228 MediaControlVolumeSliderElement* MediaControlVolumeSliderElement::Create( | 99 MediaControlVolumeSliderElement* MediaControlVolumeSliderElement::Create( |
| 229 MediaControls& media_controls) { | 100 MediaControls& media_controls) { |
| 230 MediaControlVolumeSliderElement* slider = | 101 MediaControlVolumeSliderElement* slider = |
| 231 new MediaControlVolumeSliderElement(media_controls); | 102 new MediaControlVolumeSliderElement(media_controls); |
| 232 slider->EnsureUserAgentShadowRoot(); | 103 slider->EnsureUserAgentShadowRoot(); |
| 233 slider->setType(InputTypeNames::range); | 104 slider->setType(InputTypeNames::range); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 setValue(String::Number(volume)); | 153 setValue(String::Number(volume)); |
| 283 if (LayoutObject* layout_object = this->GetLayoutObject()) | 154 if (LayoutObject* layout_object = this->GetLayoutObject()) |
| 284 layout_object->SetShouldDoFullPaintInvalidation(); | 155 layout_object->SetShouldDoFullPaintInvalidation(); |
| 285 } | 156 } |
| 286 | 157 |
| 287 bool MediaControlVolumeSliderElement::KeepEventInNode(Event* event) { | 158 bool MediaControlVolumeSliderElement::KeepEventInNode(Event* event) { |
| 288 return IsUserInteractionEventForSlider(event, GetLayoutObject()); | 159 return IsUserInteractionEventForSlider(event, GetLayoutObject()); |
| 289 } | 160 } |
| 290 | 161 |
| 291 } // namespace blink | 162 } // namespace blink |
| OLD | NEW |