| 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 17 matching lines...) Expand all Loading... |
| 28 */ | 28 */ |
| 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/MouseEvent.h" | 39 #include "core/events/MouseEvent.h" |
| 39 #include "core/frame/LocalFrame.h" | 40 #include "core/frame/LocalFrame.h" |
| 40 #include "core/frame/Settings.h" | 41 #include "core/frame/Settings.h" |
| 41 #include "core/frame/UseCounter.h" | 42 #include "core/frame/UseCounter.h" |
| 42 #include "core/html/HTMLAnchorElement.h" | 43 #include "core/html/HTMLAnchorElement.h" |
| 43 #include "core/html/HTMLLabelElement.h" | 44 #include "core/html/HTMLLabelElement.h" |
| 44 #include "core/html/HTMLSpanElement.h" | 45 #include "core/html/HTMLSpanElement.h" |
| 45 #include "core/html/HTMLVideoElement.h" | 46 #include "core/html/HTMLVideoElement.h" |
| 46 #include "core/html/TimeRanges.h" | 47 #include "core/html/TimeRanges.h" |
| 47 #include "core/html/media/HTMLMediaElementControlsList.h" | 48 #include "core/html/media/HTMLMediaElementControlsList.h" |
| 48 #include "core/html/media/HTMLMediaSource.h" | 49 #include "core/html/media/HTMLMediaSource.h" |
| 49 #include "core/html/media/MediaControls.h" | 50 #include "core/html/media/MediaControls.h" |
| 51 #include "core/html/shadow/ShadowElementNames.h" |
| 50 #include "core/html/track/TextTrackList.h" | 52 #include "core/html/track/TextTrackList.h" |
| 51 #include "core/input/EventHandler.h" | 53 #include "core/input/EventHandler.h" |
| 54 #include "core/layout/LayoutBoxModelObject.h" |
| 52 #include "core/layout/api/LayoutSliderItem.h" | 55 #include "core/layout/api/LayoutSliderItem.h" |
| 56 #include "core/page/ChromeClient.h" |
| 53 #include "core/page/Page.h" | 57 #include "core/page/Page.h" |
| 54 #include "platform/EventDispatchForbiddenScope.h" | 58 #include "platform/EventDispatchForbiddenScope.h" |
| 55 #include "platform/Histogram.h" | 59 #include "platform/Histogram.h" |
| 56 #include "platform/RuntimeEnabledFeatures.h" | 60 #include "platform/RuntimeEnabledFeatures.h" |
| 57 #include "platform/text/PlatformLocale.h" | 61 #include "platform/text/PlatformLocale.h" |
| 58 #include "public/platform/Platform.h" | 62 #include "public/platform/Platform.h" |
| 59 #include "public/platform/UserMetricsAction.h" | 63 #include "public/platform/UserMetricsAction.h" |
| 64 #include "public/platform/WebScreenInfo.h" |
| 60 | 65 |
| 61 namespace blink { | 66 namespace blink { |
| 62 | 67 |
| 63 using namespace HTMLNames; | 68 using namespace HTMLNames; |
| 64 | 69 |
| 65 namespace { | 70 namespace { |
| 66 | 71 |
| 67 // This is the duration from mediaControls.css | 72 // This is the duration from mediaControls.css |
| 68 const double fadeOutDuration = 0.3; | 73 const double fadeOutDuration = 0.3; |
| 69 | 74 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 88 // Sliders (the volume control and timeline) need to capture some additional | 93 // Sliders (the volume control and timeline) need to capture some additional |
| 89 // events used when dragging the thumb. | 94 // events used when dragging the thumb. |
| 90 bool isUserInteractionEventForSlider(Event* event, LayoutObject* layoutObject) { | 95 bool isUserInteractionEventForSlider(Event* event, LayoutObject* layoutObject) { |
| 91 // It is unclear if this can be converted to isUserInteractionEvent(), since | 96 // It is unclear if this can be converted to isUserInteractionEvent(), since |
| 92 // mouse* events seem to be eaten during a drag anyway. crbug.com/516416 . | 97 // mouse* events seem to be eaten during a drag anyway. crbug.com/516416 . |
| 93 if (isUserInteractionEvent(event)) | 98 if (isUserInteractionEvent(event)) |
| 94 return true; | 99 return true; |
| 95 | 100 |
| 96 // Some events are only captured during a slider drag. | 101 // Some events are only captured during a slider drag. |
| 97 LayoutSliderItem slider = LayoutSliderItem(toLayoutSlider(layoutObject)); | 102 LayoutSliderItem slider = LayoutSliderItem(toLayoutSlider(layoutObject)); |
| 103 // TODO(crbug.com/695459#c1): LayoutSliderItem::inDragMode is incorrectly |
| 104 // false for drags that start from the track instead of the thumb. |
| 105 // Use SliderThumbElement::m_inDragMode and |
| 106 // SliderContainerElement::m_touchStarted instead. |
| 98 if (!slider.isNull() && !slider.inDragMode()) | 107 if (!slider.isNull() && !slider.inDragMode()) |
| 99 return false; | 108 return false; |
| 100 | 109 |
| 101 const AtomicString& type = event->type(); | 110 const AtomicString& type = event->type(); |
| 102 return type == EventTypeNames::mouseover || | 111 return type == EventTypeNames::mouseover || |
| 103 type == EventTypeNames::mouseout || | 112 type == EventTypeNames::mouseout || |
| 104 type == EventTypeNames::mousemove || | 113 type == EventTypeNames::mousemove || |
| 105 type == EventTypeNames::pointerover || | 114 type == EventTypeNames::pointerover || |
| 106 type == EventTypeNames::pointerout || | 115 type == EventTypeNames::pointerout || |
| 107 type == EventTypeNames::pointermove; | 116 type == EventTypeNames::pointermove; |
| (...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 784 | 793 |
| 785 void MediaControlTimelineElement::defaultEventHandler(Event* event) { | 794 void MediaControlTimelineElement::defaultEventHandler(Event* event) { |
| 786 if (event->isMouseEvent() && | 795 if (event->isMouseEvent() && |
| 787 toMouseEvent(event)->button() != | 796 toMouseEvent(event)->button() != |
| 788 static_cast<short>(WebPointerProperties::Button::Left)) | 797 static_cast<short>(WebPointerProperties::Button::Left)) |
| 789 return; | 798 return; |
| 790 | 799 |
| 791 if (!isConnected() || !document().isActive()) | 800 if (!isConnected() || !document().isActive()) |
| 792 return; | 801 return; |
| 793 | 802 |
| 794 if (event->type() == EventTypeNames::mousedown) { | 803 // TODO(crbug.com/706504): These should listen for pointerdown/up. |
| 795 Platform::current()->recordAction( | 804 if (event->type() == EventTypeNames::mousedown) |
| 796 UserMetricsAction("Media.Controls.ScrubbingBegin")); | |
| 797 mediaControls().beginScrubbing(); | 805 mediaControls().beginScrubbing(); |
| 806 if (event->type() == EventTypeNames::mouseup) |
| 807 mediaControls().endScrubbing(); |
| 808 |
| 809 // Only respond to main button of primary pointer(s). |
| 810 if (event->isPointerEvent() && toPointerEvent(event)->isPrimary() && |
| 811 toPointerEvent(event)->button() == |
| 812 static_cast<short>(WebPointerProperties::Button::Left)) { |
| 813 if (event->type() == EventTypeNames::pointerdown) { |
| 814 Platform::current()->recordAction( |
| 815 UserMetricsAction("Media.Controls.ScrubbingBegin")); |
| 816 mediaControls().beginScrubbing(); |
| 817 Element* thumb = userAgentShadowRoot()->getElementById( |
| 818 ShadowElementNames::sliderThumb()); |
| 819 bool startedFromThumb = thumb && thumb == event->target()->toNode(); |
| 820 m_metrics.startGesture(startedFromThumb); |
| 821 } |
| 822 if (event->type() == EventTypeNames::pointerup) { |
| 823 Platform::current()->recordAction( |
| 824 UserMetricsAction("Media.Controls.ScrubbingEnd")); |
| 825 mediaControls().endScrubbing(); |
| 826 m_metrics.recordEndGesture(timelineWidth(), mediaElement().duration()); |
| 827 } |
| 798 } | 828 } |
| 799 | 829 |
| 800 if (event->type() == EventTypeNames::mouseup) { | 830 if (event->type() == EventTypeNames::keydown) { |
| 801 Platform::current()->recordAction( | 831 m_metrics.startKey(); |
| 802 UserMetricsAction("Media.Controls.ScrubbingEnd")); | 832 } |
| 803 mediaControls().endScrubbing(); | 833 if (event->type() == EventTypeNames::keyup && event->isKeyboardEvent()) { |
| 834 m_metrics.recordEndKey(timelineWidth(), toKeyboardEvent(event)->keyCode()); |
| 804 } | 835 } |
| 805 | 836 |
| 806 MediaControlInputElement::defaultEventHandler(event); | 837 MediaControlInputElement::defaultEventHandler(event); |
| 807 | 838 |
| 808 if (event->type() != EventTypeNames::input) | 839 if (event->type() != EventTypeNames::input) |
| 809 return; | 840 return; |
| 810 | 841 |
| 811 double time = value().toDouble(); | 842 double time = value().toDouble(); |
| 812 | 843 |
| 813 double duration = mediaElement().duration(); | 844 double duration = mediaElement().duration(); |
| 814 // Workaround for floating point error - it's possible for this element's max | 845 // Workaround for floating point error - it's possible for this element's max |
| 815 // attribute to be rounded to a value slightly higher than the duration. If | 846 // attribute to be rounded to a value slightly higher than the duration. If |
| 816 // this happens and scrubber is dragged near the max, seek to duration. | 847 // this happens and scrubber is dragged near the max, seek to duration. |
| 817 if (time > duration) | 848 if (time > duration) |
| 818 time = duration; | 849 time = duration; |
| 819 | 850 |
| 851 m_metrics.onInput(mediaElement().currentTime(), time); |
| 852 |
| 820 // FIXME: This will need to take the timeline offset into consideration | 853 // FIXME: This will need to take the timeline offset into consideration |
| 821 // once that concept is supported, see https://crbug.com/312699 | 854 // once that concept is supported, see https://crbug.com/312699 |
| 822 if (mediaElement().seekable()->contain(time)) | 855 if (mediaElement().seekable()->contain(time)) |
| 823 mediaElement().setCurrentTime(time); | 856 mediaElement().setCurrentTime(time); |
| 824 | 857 |
| 825 // Provide immediate feedback (without waiting for media to seek) to make it | 858 // Provide immediate feedback (without waiting for media to seek) to make it |
| 826 // easier for user to seek to a precise time. | 859 // easier for user to seek to a precise time. |
| 827 mediaControls().updateCurrentTimeDisplay(); | 860 mediaControls().updateCurrentTimeDisplay(); |
| 828 } | 861 } |
| 829 | 862 |
| 830 bool MediaControlTimelineElement::willRespondToMouseClickEvents() { | 863 bool MediaControlTimelineElement::willRespondToMouseClickEvents() { |
| 831 return isConnected() && document().isActive(); | 864 return isConnected() && document().isActive(); |
| 832 } | 865 } |
| 833 | 866 |
| 834 void MediaControlTimelineElement::setPosition(double currentTime) { | 867 void MediaControlTimelineElement::setPosition(double currentTime) { |
| 835 setValue(String::number(currentTime)); | 868 setValue(String::number(currentTime)); |
| 836 | 869 |
| 837 if (LayoutObject* layoutObject = this->layoutObject()) | 870 if (LayoutObject* layoutObject = this->layoutObject()) |
| 838 layoutObject->setShouldDoFullPaintInvalidation(); | 871 layoutObject->setShouldDoFullPaintInvalidation(); |
| 839 } | 872 } |
| 840 | 873 |
| 841 void MediaControlTimelineElement::setDuration(double duration) { | 874 void MediaControlTimelineElement::setDuration(double duration) { |
| 842 setFloatingPointAttribute(maxAttr, std::isfinite(duration) ? duration : 0); | 875 setFloatingPointAttribute(maxAttr, std::isfinite(duration) ? duration : 0); |
| 843 | 876 |
| 844 if (LayoutObject* layoutObject = this->layoutObject()) | 877 if (LayoutObject* layoutObject = this->layoutObject()) |
| 845 layoutObject->setShouldDoFullPaintInvalidation(); | 878 layoutObject->setShouldDoFullPaintInvalidation(); |
| 846 } | 879 } |
| 847 | 880 |
| 881 void MediaControlTimelineElement::onPlaying() { |
| 882 Frame* frame = document().frame(); |
| 883 if (!frame) |
| 884 return; |
| 885 m_metrics.recordPlaying(frame->chromeClient().screenInfo().orientationType, |
| 886 mediaElement().isFullscreen(), timelineWidth()); |
| 887 } |
| 888 |
| 848 bool MediaControlTimelineElement::keepEventInNode(Event* event) { | 889 bool MediaControlTimelineElement::keepEventInNode(Event* event) { |
| 849 return isUserInteractionEventForSlider(event, layoutObject()); | 890 return isUserInteractionEventForSlider(event, layoutObject()); |
| 850 } | 891 } |
| 851 | 892 |
| 893 int MediaControlTimelineElement::timelineWidth() { |
| 894 if (LayoutBoxModelObject* box = layoutBoxModelObject()) |
| 895 return box->offsetWidth().round(); |
| 896 return 0; |
| 897 } |
| 898 |
| 852 // ---------------------------- | 899 // ---------------------------- |
| 853 | 900 |
| 854 MediaControlVolumeSliderElement::MediaControlVolumeSliderElement( | 901 MediaControlVolumeSliderElement::MediaControlVolumeSliderElement( |
| 855 MediaControls& mediaControls) | 902 MediaControls& mediaControls) |
| 856 : MediaControlInputElement(mediaControls, MediaVolumeSlider) {} | 903 : MediaControlInputElement(mediaControls, MediaVolumeSlider) {} |
| 857 | 904 |
| 858 MediaControlVolumeSliderElement* MediaControlVolumeSliderElement::create( | 905 MediaControlVolumeSliderElement* MediaControlVolumeSliderElement::create( |
| 859 MediaControls& mediaControls) { | 906 MediaControls& mediaControls) { |
| 860 MediaControlVolumeSliderElement* slider = | 907 MediaControlVolumeSliderElement* slider = |
| 861 new MediaControlVolumeSliderElement(mediaControls); | 908 new MediaControlVolumeSliderElement(mediaControls); |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1101 MediaControlCurrentTimeDisplayElement* | 1148 MediaControlCurrentTimeDisplayElement* |
| 1102 MediaControlCurrentTimeDisplayElement::create(MediaControls& mediaControls) { | 1149 MediaControlCurrentTimeDisplayElement::create(MediaControls& mediaControls) { |
| 1103 MediaControlCurrentTimeDisplayElement* element = | 1150 MediaControlCurrentTimeDisplayElement* element = |
| 1104 new MediaControlCurrentTimeDisplayElement(mediaControls); | 1151 new MediaControlCurrentTimeDisplayElement(mediaControls); |
| 1105 element->setShadowPseudoId( | 1152 element->setShadowPseudoId( |
| 1106 AtomicString("-webkit-media-controls-current-time-display")); | 1153 AtomicString("-webkit-media-controls-current-time-display")); |
| 1107 return element; | 1154 return element; |
| 1108 } | 1155 } |
| 1109 | 1156 |
| 1110 } // namespace blink | 1157 } // namespace blink |
| OLD | NEW |