Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(237)

Side by Side Diff: third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp

Issue 2813103006: Media Controls: move last buttons to modules/. (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 20 matching lines...) Expand all
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" 39 #include "core/events/MouseEvent.h"
40 #include "core/frame/LocalFrame.h" 40 #include "core/frame/LocalFrame.h"
41 #include "core/frame/Settings.h"
42 #include "core/frame/UseCounter.h" 41 #include "core/frame/UseCounter.h"
43 #include "core/html/HTMLAnchorElement.h"
44 #include "core/html/HTMLVideoElement.h" 42 #include "core/html/HTMLVideoElement.h"
45 #include "core/html/TimeRanges.h" 43 #include "core/html/TimeRanges.h"
46 #include "core/html/media/HTMLMediaElementControlsList.h"
47 #include "core/html/media/HTMLMediaSource.h"
48 #include "core/html/media/MediaControls.h" 44 #include "core/html/media/MediaControls.h"
49 #include "core/html/shadow/ShadowElementNames.h" 45 #include "core/html/shadow/ShadowElementNames.h"
50 #include "core/html/track/TextTrackList.h" 46 #include "core/html/track/TextTrackList.h"
51 #include "core/input/EventHandler.h" 47 #include "core/input/EventHandler.h"
52 #include "core/layout/LayoutBoxModelObject.h" 48 #include "core/layout/LayoutBoxModelObject.h"
53 #include "core/layout/api/LayoutSliderItem.h" 49 #include "core/layout/api/LayoutSliderItem.h"
54 #include "core/page/ChromeClient.h" 50 #include "core/page/ChromeClient.h"
55 #include "core/page/Page.h"
56 #include "platform/Histogram.h" 51 #include "platform/Histogram.h"
57 #include "platform/RuntimeEnabledFeatures.h" 52 #include "platform/RuntimeEnabledFeatures.h"
58 #include "public/platform/Platform.h" 53 #include "public/platform/Platform.h"
59 #include "public/platform/UserMetricsAction.h" 54 #include "public/platform/UserMetricsAction.h"
60 #include "public/platform/WebScreenInfo.h" 55 #include "public/platform/WebScreenInfo.h"
61 56
62 namespace blink { 57 namespace blink {
63 58
64 using namespace HTMLNames; 59 using namespace HTMLNames;
65 60
(...skipping 26 matching lines...) Expand all
92 87
93 const AtomicString& type = event->type(); 88 const AtomicString& type = event->type();
94 return type == EventTypeNames::mouseover || 89 return type == EventTypeNames::mouseover ||
95 type == EventTypeNames::mouseout || 90 type == EventTypeNames::mouseout ||
96 type == EventTypeNames::mousemove || 91 type == EventTypeNames::mousemove ||
97 type == EventTypeNames::pointerover || 92 type == EventTypeNames::pointerover ||
98 type == EventTypeNames::pointerout || 93 type == EventTypeNames::pointerout ||
99 type == EventTypeNames::pointermove; 94 type == EventTypeNames::pointermove;
100 } 95 }
101 96
102 Element* ElementFromCenter(Element& element) {
103 ClientRect* client_rect = element.getBoundingClientRect();
104 int center_x =
105 static_cast<int>((client_rect->left() + client_rect->right()) / 2);
106 int center_y =
107 static_cast<int>((client_rect->top() + client_rect->bottom()) / 2);
108
109 return element.GetDocument().ElementFromPoint(center_x, center_y);
110 }
111
112 } // anonymous namespace 97 } // anonymous namespace
113 98
114 // ---------------------------- 99 // ----------------------------
115 MediaControlDownloadButtonElement::MediaControlDownloadButtonElement(
116 MediaControls& media_controls)
117 : MediaControlInputElement(media_controls, kMediaDownloadButton) {}
118
119 MediaControlDownloadButtonElement* MediaControlDownloadButtonElement::Create(
120 MediaControls& media_controls) {
121 MediaControlDownloadButtonElement* button =
122 new MediaControlDownloadButtonElement(media_controls);
123 button->EnsureUserAgentShadowRoot();
124 button->setType(InputTypeNames::button);
125 button->SetShadowPseudoId(
126 AtomicString("-internal-media-controls-download-button"));
127 button->SetIsWanted(false);
128 return button;
129 }
130
131 WebLocalizedString::Name
132 MediaControlDownloadButtonElement::GetOverflowStringName() {
133 return WebLocalizedString::kOverflowMenuDownload;
134 }
135
136 bool MediaControlDownloadButtonElement::ShouldDisplayDownloadButton() {
137 const KURL& url = MediaElement().currentSrc();
138
139 // Check page settings to see if download is disabled.
140 if (GetDocument().GetPage() &&
141 GetDocument().GetPage()->GetSettings().GetHideDownloadUI())
142 return false;
143
144 // URLs that lead to nowhere are ignored.
145 if (url.IsNull() || url.IsEmpty())
146 return false;
147
148 // If we have no source, we can't download.
149 if (MediaElement().getNetworkState() == HTMLMediaElement::kNetworkEmpty ||
150 MediaElement().getNetworkState() == HTMLMediaElement::kNetworkNoSource) {
151 return false;
152 }
153
154 // Local files and blobs (including MSE) should not have a download button.
155 if (url.IsLocalFile() || url.ProtocolIs("blob"))
156 return false;
157
158 // MediaStream can't be downloaded.
159 if (HTMLMediaElement::IsMediaStreamURL(url.GetString()))
160 return false;
161
162 // MediaSource can't be downloaded.
163 if (HTMLMediaSource::Lookup(url))
164 return false;
165
166 // HLS stream shouldn't have a download button.
167 if (HTMLMediaElement::IsHLSURL(url))
168 return false;
169
170 // Infinite streams don't have a clear end at which to finish the download
171 // (would require adding UI to prompt for the duration to download).
172 if (MediaElement().duration() == std::numeric_limits<double>::infinity())
173 return false;
174
175 // The attribute disables the download button.
176 if (MediaElement().ControlsListInternal()->ShouldHideDownload()) {
177 UseCounter::Count(MediaElement().GetDocument(),
178 UseCounter::kHTMLMediaElementControlsListNoDownload);
179 return false;
180 }
181
182 return true;
183 }
184
185 void MediaControlDownloadButtonElement::SetIsWanted(bool wanted) {
186 MediaControlElement::SetIsWanted(wanted);
187
188 if (!IsWanted())
189 return;
190
191 DCHECK(IsWanted());
192 if (!show_use_counted_) {
193 show_use_counted_ = true;
194 RecordMetrics(DownloadActionMetrics::kShown);
195 }
196 }
197
198 void MediaControlDownloadButtonElement::DefaultEventHandler(Event* event) {
199 const KURL& url = MediaElement().currentSrc();
200 if (event->type() == EventTypeNames::click &&
201 !(url.IsNull() || url.IsEmpty())) {
202 Platform::Current()->RecordAction(
203 UserMetricsAction("Media.Controls.Download"));
204 if (!click_use_counted_) {
205 click_use_counted_ = true;
206 RecordMetrics(DownloadActionMetrics::kClicked);
207 }
208 if (!anchor_) {
209 HTMLAnchorElement* anchor = HTMLAnchorElement::Create(GetDocument());
210 anchor->setAttribute(HTMLNames::downloadAttr, "");
211 anchor_ = anchor;
212 }
213 anchor_->SetURL(url);
214 anchor_->DispatchSimulatedClick(event);
215 }
216 MediaControlInputElement::DefaultEventHandler(event);
217 }
218
219 DEFINE_TRACE(MediaControlDownloadButtonElement) {
220 visitor->Trace(anchor_);
221 MediaControlInputElement::Trace(visitor);
222 }
223
224 void MediaControlDownloadButtonElement::RecordMetrics(
225 DownloadActionMetrics metric) {
226 DEFINE_STATIC_LOCAL(EnumerationHistogram, download_action_histogram,
227 ("Media.Controls.Download",
228 static_cast<int>(DownloadActionMetrics::kCount)));
229 download_action_histogram.Count(static_cast<int>(metric));
230 }
231
232 // ----------------------------
233 100
234 MediaControlTimelineElement::MediaControlTimelineElement( 101 MediaControlTimelineElement::MediaControlTimelineElement(
235 MediaControls& media_controls) 102 MediaControls& media_controls)
236 : MediaControlInputElement(media_controls, kMediaSlider) {} 103 : MediaControlInputElement(media_controls, kMediaSlider) {}
237 104
238 MediaControlTimelineElement* MediaControlTimelineElement::Create( 105 MediaControlTimelineElement* MediaControlTimelineElement::Create(
239 MediaControls& media_controls) { 106 MediaControls& media_controls) {
240 MediaControlTimelineElement* timeline = 107 MediaControlTimelineElement* timeline =
241 new MediaControlTimelineElement(media_controls); 108 new MediaControlTimelineElement(media_controls);
242 timeline->EnsureUserAgentShadowRoot(); 109 timeline->EnsureUserAgentShadowRoot();
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 281
415 setValue(String::Number(volume)); 282 setValue(String::Number(volume));
416 if (LayoutObject* layout_object = this->GetLayoutObject()) 283 if (LayoutObject* layout_object = this->GetLayoutObject())
417 layout_object->SetShouldDoFullPaintInvalidation(); 284 layout_object->SetShouldDoFullPaintInvalidation();
418 } 285 }
419 286
420 bool MediaControlVolumeSliderElement::KeepEventInNode(Event* event) { 287 bool MediaControlVolumeSliderElement::KeepEventInNode(Event* event) {
421 return IsUserInteractionEventForSlider(event, GetLayoutObject()); 288 return IsUserInteractionEventForSlider(event, GetLayoutObject());
422 } 289 }
423 290
424 // ----------------------------
425
426 MediaControlCastButtonElement::MediaControlCastButtonElement(
427 MediaControls& media_controls,
428 bool is_overlay_button)
429 : MediaControlInputElement(media_controls, kMediaCastOnButton),
430 is_overlay_button_(is_overlay_button) {
431 if (is_overlay_button_)
432 RecordMetrics(CastOverlayMetrics::kCreated);
433 SetIsPlayingRemotely(false);
434 }
435
436 MediaControlCastButtonElement* MediaControlCastButtonElement::Create(
437 MediaControls& media_controls,
438 bool is_overlay_button) {
439 MediaControlCastButtonElement* button =
440 new MediaControlCastButtonElement(media_controls, is_overlay_button);
441 button->EnsureUserAgentShadowRoot();
442 button->SetShadowPseudoId(is_overlay_button
443 ? "-internal-media-controls-overlay-cast-button"
444 : "-internal-media-controls-cast-button");
445 button->setType(InputTypeNames::button);
446 return button;
447 }
448
449 void MediaControlCastButtonElement::DefaultEventHandler(Event* event) {
450 if (event->type() == EventTypeNames::click) {
451 if (is_overlay_button_)
452 Platform::Current()->RecordAction(
453 UserMetricsAction("Media.Controls.CastOverlay"));
454 else
455 Platform::Current()->RecordAction(
456 UserMetricsAction("Media.Controls.Cast"));
457
458 if (is_overlay_button_ && !click_use_counted_) {
459 click_use_counted_ = true;
460 RecordMetrics(CastOverlayMetrics::kClicked);
461 }
462 if (MediaElement().IsPlayingRemotely()) {
463 MediaElement().RequestRemotePlaybackControl();
464 } else {
465 MediaElement().RequestRemotePlayback();
466 }
467 }
468 MediaControlInputElement::DefaultEventHandler(event);
469 }
470
471 void MediaControlCastButtonElement::SetIsPlayingRemotely(
472 bool is_playing_remotely) {
473 if (is_playing_remotely) {
474 if (is_overlay_button_) {
475 SetDisplayType(kMediaOverlayCastOnButton);
476 } else {
477 SetDisplayType(kMediaCastOnButton);
478 }
479 } else {
480 if (is_overlay_button_) {
481 SetDisplayType(kMediaOverlayCastOffButton);
482 } else {
483 SetDisplayType(kMediaCastOffButton);
484 }
485 }
486 UpdateOverflowString();
487 }
488
489 WebLocalizedString::Name
490 MediaControlCastButtonElement::GetOverflowStringName() {
491 if (MediaElement().IsPlayingRemotely())
492 return WebLocalizedString::kOverflowMenuStopCast;
493 return WebLocalizedString::kOverflowMenuCast;
494 }
495
496 void MediaControlCastButtonElement::TryShowOverlay() {
497 DCHECK(is_overlay_button_);
498
499 SetIsWanted(true);
500 if (ElementFromCenter(*this) != &MediaElement()) {
501 SetIsWanted(false);
502 return;
503 }
504
505 DCHECK(IsWanted());
506 if (!show_use_counted_) {
507 show_use_counted_ = true;
508 RecordMetrics(CastOverlayMetrics::kShown);
509 }
510 }
511
512 bool MediaControlCastButtonElement::KeepEventInNode(Event* event) {
513 return IsUserInteractionEvent(event);
514 }
515
516 void MediaControlCastButtonElement::RecordMetrics(CastOverlayMetrics metric) {
517 DCHECK(is_overlay_button_);
518 DEFINE_STATIC_LOCAL(
519 EnumerationHistogram, overlay_histogram,
520 ("Cast.Sender.Overlay", static_cast<int>(CastOverlayMetrics::kCount)));
521 overlay_histogram.Count(static_cast<int>(metric));
522 }
523
524 } // namespace blink 291 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698