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

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

Issue 2810173003: Media Controls: move all MediaControlDivElement sub-classes to modules/. (Closed)
Patch Set: fix typo 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 23 matching lines...) Expand all
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" 41 #include "core/frame/Settings.h"
42 #include "core/frame/UseCounter.h" 42 #include "core/frame/UseCounter.h"
43 #include "core/html/HTMLAnchorElement.h" 43 #include "core/html/HTMLAnchorElement.h"
44 #include "core/html/HTMLLabelElement.h"
45 #include "core/html/HTMLSpanElement.h"
46 #include "core/html/HTMLVideoElement.h" 44 #include "core/html/HTMLVideoElement.h"
47 #include "core/html/TimeRanges.h" 45 #include "core/html/TimeRanges.h"
48 #include "core/html/media/HTMLMediaElementControlsList.h" 46 #include "core/html/media/HTMLMediaElementControlsList.h"
49 #include "core/html/media/HTMLMediaSource.h" 47 #include "core/html/media/HTMLMediaSource.h"
50 #include "core/html/media/MediaControls.h" 48 #include "core/html/media/MediaControls.h"
51 #include "core/html/shadow/ShadowElementNames.h" 49 #include "core/html/shadow/ShadowElementNames.h"
52 #include "core/html/track/TextTrackList.h" 50 #include "core/html/track/TextTrackList.h"
53 #include "core/input/EventHandler.h" 51 #include "core/input/EventHandler.h"
54 #include "core/layout/LayoutBoxModelObject.h" 52 #include "core/layout/LayoutBoxModelObject.h"
55 #include "core/layout/api/LayoutSliderItem.h" 53 #include "core/layout/api/LayoutSliderItem.h"
56 #include "core/page/ChromeClient.h" 54 #include "core/page/ChromeClient.h"
57 #include "core/page/Page.h" 55 #include "core/page/Page.h"
58 #include "platform/EventDispatchForbiddenScope.h"
59 #include "platform/Histogram.h" 56 #include "platform/Histogram.h"
60 #include "platform/RuntimeEnabledFeatures.h" 57 #include "platform/RuntimeEnabledFeatures.h"
61 #include "platform/text/PlatformLocale.h"
62 #include "public/platform/Platform.h" 58 #include "public/platform/Platform.h"
63 #include "public/platform/UserMetricsAction.h" 59 #include "public/platform/UserMetricsAction.h"
64 #include "public/platform/WebScreenInfo.h" 60 #include "public/platform/WebScreenInfo.h"
65 61
66 namespace blink { 62 namespace blink {
67 63
68 using namespace HTMLNames; 64 using namespace HTMLNames;
69 65
70 namespace { 66 namespace {
71 67
72 // This is the duration from mediaControls.css
73 const double kFadeOutDuration = 0.3;
74
75 const QualifiedName& TrackIndexAttrName() {
76 // Save the track index in an attribute to avoid holding a pointer to the text
77 // track.
78 DEFINE_STATIC_LOCAL(QualifiedName, track_index_attr,
79 (g_null_atom, "data-track-index", g_null_atom));
80 return track_index_attr;
81 }
82
83 // When specified as trackIndex, disable text tracks.
84 const int kTrackIndexOffValue = -1;
85
86 bool IsUserInteractionEvent(Event* event) { 68 bool IsUserInteractionEvent(Event* event) {
87 const AtomicString& type = event->type(); 69 const AtomicString& type = event->type();
88 return type == EventTypeNames::mousedown || type == EventTypeNames::mouseup || 70 return type == EventTypeNames::mousedown || type == EventTypeNames::mouseup ||
89 type == EventTypeNames::click || type == EventTypeNames::dblclick || 71 type == EventTypeNames::click || type == EventTypeNames::dblclick ||
90 event->IsKeyboardEvent() || event->IsTouchEvent(); 72 event->IsKeyboardEvent() || event->IsTouchEvent();
91 } 73 }
92 74
93 // Sliders (the volume control and timeline) need to capture some additional 75 // Sliders (the volume control and timeline) need to capture some additional
94 // events used when dragging the thumb. 76 // events used when dragging the thumb.
95 bool IsUserInteractionEventForSlider(Event* event, 77 bool IsUserInteractionEventForSlider(Event* event,
(...skipping 24 matching lines...) Expand all
120 Element* ElementFromCenter(Element& element) { 102 Element* ElementFromCenter(Element& element) {
121 ClientRect* client_rect = element.getBoundingClientRect(); 103 ClientRect* client_rect = element.getBoundingClientRect();
122 int center_x = 104 int center_x =
123 static_cast<int>((client_rect->left() + client_rect->right()) / 2); 105 static_cast<int>((client_rect->left() + client_rect->right()) / 2);
124 int center_y = 106 int center_y =
125 static_cast<int>((client_rect->top() + client_rect->bottom()) / 2); 107 static_cast<int>((client_rect->top() + client_rect->bottom()) / 2);
126 108
127 return element.GetDocument().ElementFromPoint(center_x, center_y); 109 return element.GetDocument().ElementFromPoint(center_x, center_y);
128 } 110 }
129 111
130 bool HasDuplicateLabel(TextTrack* current_track) {
131 DCHECK(current_track);
132 TextTrackList* track_list = current_track->TrackList();
133 // The runtime of this method is quadratic but since there are usually very
134 // few text tracks it won't affect the performance much.
135 String current_track_label = current_track->label();
136 for (unsigned i = 0; i < track_list->length(); i++) {
137 TextTrack* track = track_list->AnonymousIndexedGetter(i);
138 if (current_track != track && current_track_label == track->label())
139 return true;
140 }
141 return false;
142 }
143
144 } // anonymous namespace 112 } // anonymous namespace
145 113
146 MediaControlPanelElement::MediaControlPanelElement(
147 MediaControls& media_controls)
148 : MediaControlDivElement(media_controls, kMediaControlsPanel),
149 is_displayed_(false),
150 opaque_(true),
151 transition_timer_(TaskRunnerHelper::Get(TaskType::kUnspecedTimer,
152 &media_controls.OwnerDocument()),
153 this,
154 &MediaControlPanelElement::TransitionTimerFired) {}
155
156 MediaControlPanelElement* MediaControlPanelElement::Create(
157 MediaControls& media_controls) {
158 MediaControlPanelElement* panel =
159 new MediaControlPanelElement(media_controls);
160 panel->SetShadowPseudoId(AtomicString("-webkit-media-controls-panel"));
161 return panel;
162 }
163
164 void MediaControlPanelElement::DefaultEventHandler(Event* event) {
165 // Suppress the media element activation behavior (toggle play/pause) when
166 // any part of the control panel is clicked.
167 if (event->type() == EventTypeNames::click) {
168 event->SetDefaultHandled();
169 return;
170 }
171 HTMLDivElement::DefaultEventHandler(event);
172 }
173
174 void MediaControlPanelElement::StartTimer() {
175 StopTimer();
176
177 // The timer is required to set the property display:'none' on the panel,
178 // such that captions are correctly displayed at the bottom of the video
179 // at the end of the fadeout transition.
180 // FIXME: Racing a transition with a setTimeout like this is wrong.
181 transition_timer_.StartOneShot(kFadeOutDuration, BLINK_FROM_HERE);
182 }
183
184 void MediaControlPanelElement::StopTimer() {
185 transition_timer_.Stop();
186 }
187
188 void MediaControlPanelElement::TransitionTimerFired(TimerBase*) {
189 if (!opaque_)
190 SetIsWanted(false);
191
192 StopTimer();
193 }
194
195 void MediaControlPanelElement::DidBecomeVisible() {
196 DCHECK(is_displayed_ && opaque_);
197 MediaElement().MediaControlsDidBecomeVisible();
198 }
199
200 bool MediaControlPanelElement::IsOpaque() const {
201 return opaque_;
202 }
203
204 void MediaControlPanelElement::MakeOpaque() {
205 if (opaque_)
206 return;
207
208 SetInlineStyleProperty(CSSPropertyOpacity, 1.0,
209 CSSPrimitiveValue::UnitType::kNumber);
210 opaque_ = true;
211
212 if (is_displayed_) {
213 SetIsWanted(true);
214 DidBecomeVisible();
215 }
216 }
217
218 void MediaControlPanelElement::MakeTransparent() {
219 if (!opaque_)
220 return;
221
222 SetInlineStyleProperty(CSSPropertyOpacity, 0.0,
223 CSSPrimitiveValue::UnitType::kNumber);
224
225 opaque_ = false;
226 StartTimer();
227 }
228
229 void MediaControlPanelElement::SetIsDisplayed(bool is_displayed) {
230 if (is_displayed_ == is_displayed)
231 return;
232
233 is_displayed_ = is_displayed;
234 if (is_displayed_ && opaque_)
235 DidBecomeVisible();
236 }
237
238 bool MediaControlPanelElement::KeepEventInNode(Event* event) {
239 return IsUserInteractionEvent(event);
240 }
241
242 // ----------------------------
243
244 MediaControlPlayButtonElement::MediaControlPlayButtonElement( 114 MediaControlPlayButtonElement::MediaControlPlayButtonElement(
245 MediaControls& media_controls) 115 MediaControls& media_controls)
246 : MediaControlInputElement(media_controls, kMediaPlayButton) {} 116 : MediaControlInputElement(media_controls, kMediaPlayButton) {}
247 117
248 MediaControlPlayButtonElement* MediaControlPlayButtonElement::Create( 118 MediaControlPlayButtonElement* MediaControlPlayButtonElement::Create(
249 MediaControls& media_controls) { 119 MediaControls& media_controls) {
250 MediaControlPlayButtonElement* button = 120 MediaControlPlayButtonElement* button =
251 new MediaControlPlayButtonElement(media_controls); 121 new MediaControlPlayButtonElement(media_controls);
252 button->EnsureUserAgentShadowRoot(); 122 button->EnsureUserAgentShadowRoot();
253 button->setType(InputTypeNames::button); 123 button->setType(InputTypeNames::button);
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 MediaControlInputElement::DefaultEventHandler(event); 244 MediaControlInputElement::DefaultEventHandler(event);
375 } 245 }
376 246
377 WebLocalizedString::Name 247 WebLocalizedString::Name
378 MediaControlToggleClosedCaptionsButtonElement::GetOverflowStringName() { 248 MediaControlToggleClosedCaptionsButtonElement::GetOverflowStringName() {
379 return WebLocalizedString::kOverflowMenuCaptions; 249 return WebLocalizedString::kOverflowMenuCaptions;
380 } 250 }
381 251
382 // ---------------------------- 252 // ----------------------------
383 253
384 MediaControlTextTrackListElement::MediaControlTextTrackListElement(
385 MediaControls& media_controls)
386 : MediaControlDivElement(media_controls, kMediaTextTrackList) {}
387
388 MediaControlTextTrackListElement* MediaControlTextTrackListElement::Create(
389 MediaControls& media_controls) {
390 MediaControlTextTrackListElement* element =
391 new MediaControlTextTrackListElement(media_controls);
392 element->SetShadowPseudoId(
393 AtomicString("-internal-media-controls-text-track-list"));
394 element->SetIsWanted(false);
395 return element;
396 }
397
398 void MediaControlTextTrackListElement::DefaultEventHandler(Event* event) {
399 if (event->type() == EventTypeNames::change) {
400 // Identify which input element was selected and set track to showing
401 Node* target = event->target()->ToNode();
402 if (!target || !target->IsElementNode())
403 return;
404
405 GetMediaControls().DisableShowingTextTracks();
406 int track_index =
407 ToElement(target)->GetIntegralAttribute(TrackIndexAttrName());
408 if (track_index != kTrackIndexOffValue) {
409 DCHECK_GE(track_index, 0);
410 GetMediaControls().ShowTextTrackAtIndex(track_index);
411 MediaElement().DisableAutomaticTextTrackSelection();
412 }
413
414 event->SetDefaultHandled();
415 }
416 MediaControlDivElement::DefaultEventHandler(event);
417 }
418
419 void MediaControlTextTrackListElement::SetVisible(bool visible) {
420 if (visible) {
421 SetIsWanted(true);
422 RefreshTextTrackListMenu();
423 } else {
424 SetIsWanted(false);
425 }
426 }
427
428 String MediaControlTextTrackListElement::GetTextTrackLabel(TextTrack* track) {
429 if (!track) {
430 return MediaElement().GetLocale().QueryString(
431 WebLocalizedString::kTextTracksOff);
432 }
433
434 String track_label = track->label();
435
436 if (track_label.IsEmpty())
437 track_label = track->language();
438
439 if (track_label.IsEmpty()) {
440 track_label = String(MediaElement().GetLocale().QueryString(
441 WebLocalizedString::kTextTracksNoLabel,
442 String::Number(track->TrackIndex() + 1)));
443 }
444
445 return track_label;
446 }
447
448 // TextTrack parameter when passed in as a nullptr, creates the "Off" list item
449 // in the track list.
450 Element* MediaControlTextTrackListElement::CreateTextTrackListItem(
451 TextTrack* track) {
452 int track_index = track ? track->TrackIndex() : kTrackIndexOffValue;
453 HTMLLabelElement* track_item = HTMLLabelElement::Create(GetDocument());
454 track_item->SetShadowPseudoId(
455 AtomicString("-internal-media-controls-text-track-list-item"));
456 HTMLInputElement* track_item_input =
457 HTMLInputElement::Create(GetDocument(), false);
458 track_item_input->SetShadowPseudoId(
459 AtomicString("-internal-media-controls-text-track-list-item-input"));
460 track_item_input->setType(InputTypeNames::checkbox);
461 track_item_input->SetIntegralAttribute(TrackIndexAttrName(), track_index);
462 if (!MediaElement().TextTracksVisible()) {
463 if (!track)
464 track_item_input->setChecked(true);
465 } else {
466 // If there are multiple text tracks set to showing, they must all have
467 // checkmarks displayed.
468 if (track && track->mode() == TextTrack::ShowingKeyword())
469 track_item_input->setChecked(true);
470 }
471
472 track_item->AppendChild(track_item_input);
473 String track_label = GetTextTrackLabel(track);
474 track_item->AppendChild(Text::Create(GetDocument(), track_label));
475 // Add a track kind marker icon if there are multiple tracks with the same
476 // label or if the track has no label.
477 if (track && (track->label().IsEmpty() || HasDuplicateLabel(track))) {
478 HTMLSpanElement* track_kind_marker = HTMLSpanElement::Create(GetDocument());
479 if (track->kind() == track->CaptionsKeyword()) {
480 track_kind_marker->SetShadowPseudoId(AtomicString(
481 "-internal-media-controls-text-track-list-kind-captions"));
482 } else {
483 DCHECK_EQ(track->kind(), track->SubtitlesKeyword());
484 track_kind_marker->SetShadowPseudoId(AtomicString(
485 "-internal-media-controls-text-track-list-kind-subtitles"));
486 }
487 track_item->AppendChild(track_kind_marker);
488 }
489 return track_item;
490 }
491
492 void MediaControlTextTrackListElement::RefreshTextTrackListMenu() {
493 if (!MediaElement().HasClosedCaptions() ||
494 !MediaElement().TextTracksAreReady())
495 return;
496
497 EventDispatchForbiddenScope::AllowUserAgentEvents allow_events;
498 RemoveChildren(kOmitSubtreeModifiedEvent);
499
500 // Construct a menu for subtitles and captions. Pass in a nullptr to
501 // createTextTrackListItem to create the "Off" track item.
502 AppendChild(CreateTextTrackListItem(nullptr));
503
504 TextTrackList* track_list = MediaElement().textTracks();
505 for (unsigned i = 0; i < track_list->length(); i++) {
506 TextTrack* track = track_list->AnonymousIndexedGetter(i);
507 if (!track->CanBeRendered())
508 continue;
509 AppendChild(CreateTextTrackListItem(track));
510 }
511 }
512
513 // ----------------------------
514 MediaControlOverflowMenuButtonElement::MediaControlOverflowMenuButtonElement( 254 MediaControlOverflowMenuButtonElement::MediaControlOverflowMenuButtonElement(
515 MediaControls& media_controls) 255 MediaControls& media_controls)
516 : MediaControlInputElement(media_controls, kMediaOverflowButton) {} 256 : MediaControlInputElement(media_controls, kMediaOverflowButton) {}
517 257
518 MediaControlOverflowMenuButtonElement* 258 MediaControlOverflowMenuButtonElement*
519 MediaControlOverflowMenuButtonElement::Create(MediaControls& media_controls) { 259 MediaControlOverflowMenuButtonElement::Create(MediaControls& media_controls) {
520 MediaControlOverflowMenuButtonElement* button = 260 MediaControlOverflowMenuButtonElement* button =
521 new MediaControlOverflowMenuButtonElement(media_controls); 261 new MediaControlOverflowMenuButtonElement(media_controls);
522 button->EnsureUserAgentShadowRoot(); 262 button->EnsureUserAgentShadowRoot();
523 button->setType(InputTypeNames::button); 263 button->setType(InputTypeNames::button);
(...skipping 13 matching lines...) Expand all
537 UserMetricsAction("Media.Controls.OverflowOpen")); 277 UserMetricsAction("Media.Controls.OverflowOpen"));
538 278
539 GetMediaControls().ToggleOverflowMenu(); 279 GetMediaControls().ToggleOverflowMenu();
540 event->SetDefaultHandled(); 280 event->SetDefaultHandled();
541 } 281 }
542 282
543 MediaControlInputElement::DefaultEventHandler(event); 283 MediaControlInputElement::DefaultEventHandler(event);
544 } 284 }
545 285
546 // ---------------------------- 286 // ----------------------------
547 MediaControlOverflowMenuListElement::MediaControlOverflowMenuListElement(
548 MediaControls& media_controls)
549 : MediaControlDivElement(media_controls, kMediaOverflowList) {}
550
551 MediaControlOverflowMenuListElement*
552 MediaControlOverflowMenuListElement::Create(MediaControls& media_controls) {
553 MediaControlOverflowMenuListElement* element =
554 new MediaControlOverflowMenuListElement(media_controls);
555 element->SetIsWanted(false);
556 element->SetShadowPseudoId(
557 AtomicString("-internal-media-controls-overflow-menu-list"));
558 return element;
559 }
560
561 void MediaControlOverflowMenuListElement::DefaultEventHandler(Event* event) {
562 if (event->type() == EventTypeNames::click)
563 event->SetDefaultHandled();
564
565 MediaControlDivElement::DefaultEventHandler(event);
566 }
567
568 // ----------------------------
569 MediaControlDownloadButtonElement::MediaControlDownloadButtonElement( 287 MediaControlDownloadButtonElement::MediaControlDownloadButtonElement(
570 MediaControls& media_controls) 288 MediaControls& media_controls)
571 : MediaControlInputElement(media_controls, kMediaDownloadButton) {} 289 : MediaControlInputElement(media_controls, kMediaDownloadButton) {}
572 290
573 MediaControlDownloadButtonElement* MediaControlDownloadButtonElement::Create( 291 MediaControlDownloadButtonElement* MediaControlDownloadButtonElement::Create(
574 MediaControls& media_controls) { 292 MediaControls& media_controls) {
575 MediaControlDownloadButtonElement* button = 293 MediaControlDownloadButtonElement* button =
576 new MediaControlDownloadButtonElement(media_controls); 294 new MediaControlDownloadButtonElement(media_controls);
577 button->EnsureUserAgentShadowRoot(); 295 button->EnsureUserAgentShadowRoot();
578 button->setType(InputTypeNames::button); 296 button->setType(InputTypeNames::button);
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 745
1028 void MediaControlCastButtonElement::RecordMetrics(CastOverlayMetrics metric) { 746 void MediaControlCastButtonElement::RecordMetrics(CastOverlayMetrics metric) {
1029 DCHECK(is_overlay_button_); 747 DCHECK(is_overlay_button_);
1030 DEFINE_STATIC_LOCAL( 748 DEFINE_STATIC_LOCAL(
1031 EnumerationHistogram, overlay_histogram, 749 EnumerationHistogram, overlay_histogram,
1032 ("Cast.Sender.Overlay", static_cast<int>(CastOverlayMetrics::kCount))); 750 ("Cast.Sender.Overlay", static_cast<int>(CastOverlayMetrics::kCount)));
1033 overlay_histogram.Count(static_cast<int>(metric)); 751 overlay_histogram.Count(static_cast<int>(metric));
1034 } 752 }
1035 753
1036 } // namespace blink 754 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698