OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. | |
3 * Copyright (C) 2012 Google Inc. All rights reserved. | |
4 * | |
5 * Redistribution and use in source and binary forms, with or without | |
6 * modification, are permitted provided that the following conditions | |
7 * are met: | |
8 * | |
9 * 1. Redistributions of source code must retain the above copyright | |
10 * notice, this list of conditions and the following disclaimer. | |
11 * 2. Redistributions in binary form must reproduce the above copyright | |
12 * notice, this list of conditions and the following disclaimer in the | |
13 * documentation and/or other materials provided with the distribution. | |
14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of | |
15 * its contributors may be used to endorse or promote products derived | |
16 * from this software without specific prior written permission. | |
17 * | |
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY | |
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY | |
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
28 */ | |
29 | |
30 #include "core/html/shadow/MediaControlElements.h" | |
31 | |
32 #include "bindings/core/v8/ExceptionState.h" | |
33 #include "core/InputTypeNames.h" | |
34 #include "core/dom/ClientRect.h" | |
35 #include "core/dom/TaskRunnerHelper.h" | |
36 #include "core/dom/Text.h" | |
37 #include "core/dom/shadow/ShadowRoot.h" | |
38 #include "core/events/KeyboardEvent.h" | |
39 #include "core/frame/LocalFrame.h" | |
40 #include "core/frame/UseCounter.h" | |
41 #include "core/html/HTMLVideoElement.h" | |
42 #include "core/html/media/MediaControls.h" | |
43 #include "core/html/shadow/ShadowElementNames.h" | |
44 #include "core/html/track/TextTrackList.h" | |
45 #include "core/input/EventHandler.h" | |
46 #include "core/layout/LayoutBoxModelObject.h" | |
47 #include "core/layout/api/LayoutSliderItem.h" | |
48 #include "platform/Histogram.h" | |
49 #include "platform/RuntimeEnabledFeatures.h" | |
50 #include "public/platform/Platform.h" | |
51 #include "public/platform/UserMetricsAction.h" | |
52 | |
53 namespace blink { | |
54 | |
55 using namespace HTMLNames; | |
56 | |
57 namespace { | |
58 | |
59 bool IsUserInteractionEvent(Event* event) { | |
60 const AtomicString& type = event->type(); | |
61 return type == EventTypeNames::mousedown || type == EventTypeNames::mouseup || | |
62 type == EventTypeNames::click || type == EventTypeNames::dblclick || | |
63 event->IsKeyboardEvent() || event->IsTouchEvent(); | |
64 } | |
65 | |
66 // Sliders (the volume control and timeline) need to capture some additional | |
67 // events used when dragging the thumb. | |
68 bool IsUserInteractionEventForSlider(Event* event, | |
69 LayoutObject* layout_object) { | |
70 // It is unclear if this can be converted to isUserInteractionEvent(), since | |
71 // mouse* events seem to be eaten during a drag anyway. crbug.com/516416 . | |
72 if (IsUserInteractionEvent(event)) | |
73 return true; | |
74 | |
75 // Some events are only captured during a slider drag. | |
76 LayoutSliderItem slider = LayoutSliderItem(ToLayoutSlider(layout_object)); | |
77 // TODO(crbug.com/695459#c1): LayoutSliderItem::inDragMode is incorrectly | |
78 // false for drags that start from the track instead of the thumb. | |
79 // Use SliderThumbElement::m_inDragMode and | |
80 // SliderContainerElement::m_touchStarted instead. | |
81 if (!slider.IsNull() && !slider.InDragMode()) | |
82 return false; | |
83 | |
84 const AtomicString& type = event->type(); | |
85 return type == EventTypeNames::mouseover || | |
86 type == EventTypeNames::mouseout || | |
87 type == EventTypeNames::mousemove || | |
88 type == EventTypeNames::pointerover || | |
89 type == EventTypeNames::pointerout || | |
90 type == EventTypeNames::pointermove; | |
91 } | |
92 | |
93 } // anonymous namespace | |
94 | |
95 MediaControlVolumeSliderElement::MediaControlVolumeSliderElement( | |
96 MediaControls& media_controls) | |
97 : MediaControlInputElement(media_controls, kMediaVolumeSlider) {} | |
98 | |
99 MediaControlVolumeSliderElement* MediaControlVolumeSliderElement::Create( | |
100 MediaControls& media_controls) { | |
101 MediaControlVolumeSliderElement* slider = | |
102 new MediaControlVolumeSliderElement(media_controls); | |
103 slider->EnsureUserAgentShadowRoot(); | |
104 slider->setType(InputTypeNames::range); | |
105 slider->setAttribute(stepAttr, "any"); | |
106 slider->setAttribute(maxAttr, "1"); | |
107 slider->SetShadowPseudoId( | |
108 AtomicString("-webkit-media-controls-volume-slider")); | |
109 return slider; | |
110 } | |
111 | |
112 void MediaControlVolumeSliderElement::DefaultEventHandler(Event* event) { | |
113 if (!isConnected() || !GetDocument().IsActive()) | |
114 return; | |
115 | |
116 MediaControlInputElement::DefaultEventHandler(event); | |
117 | |
118 if (event->type() == EventTypeNames::mousedown) | |
119 Platform::Current()->RecordAction( | |
120 UserMetricsAction("Media.Controls.VolumeChangeBegin")); | |
121 | |
122 if (event->type() == EventTypeNames::mouseup) | |
123 Platform::Current()->RecordAction( | |
124 UserMetricsAction("Media.Controls.VolumeChangeEnd")); | |
125 | |
126 if (event->type() == EventTypeNames::input) { | |
127 double volume = value().ToDouble(); | |
128 MediaElement().setVolume(volume); | |
129 MediaElement().setMuted(false); | |
130 if (LayoutObject* layout_object = this->GetLayoutObject()) | |
131 layout_object->SetShouldDoFullPaintInvalidation(); | |
132 } | |
133 } | |
134 | |
135 bool MediaControlVolumeSliderElement::WillRespondToMouseMoveEvents() { | |
136 if (!isConnected() || !GetDocument().IsActive()) | |
137 return false; | |
138 | |
139 return MediaControlInputElement::WillRespondToMouseMoveEvents(); | |
140 } | |
141 | |
142 bool MediaControlVolumeSliderElement::WillRespondToMouseClickEvents() { | |
143 if (!isConnected() || !GetDocument().IsActive()) | |
144 return false; | |
145 | |
146 return MediaControlInputElement::WillRespondToMouseClickEvents(); | |
147 } | |
148 | |
149 void MediaControlVolumeSliderElement::SetVolume(double volume) { | |
150 if (value().ToDouble() == volume) | |
151 return; | |
152 | |
153 setValue(String::Number(volume)); | |
154 if (LayoutObject* layout_object = this->GetLayoutObject()) | |
155 layout_object->SetShouldDoFullPaintInvalidation(); | |
156 } | |
157 | |
158 bool MediaControlVolumeSliderElement::KeepEventInNode(Event* event) { | |
159 return IsUserInteractionEventForSlider(event, GetLayoutObject()); | |
160 } | |
161 | |
162 } // namespace blink | |
OLD | NEW |