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

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

Issue 1082533002: Support text track selection in video controls (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 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 15 matching lines...) Expand all
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 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. 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */ 28 */
29 29
30 #include "config.h" 30 #include "config.h"
31 #include "core/html/shadow/MediaControlElements.h" 31 #include "core/html/shadow/MediaControlElements.h"
32 32
33 #include "bindings/core/v8/ExceptionStatePlaceholder.h" 33 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
34 #include "core/InputTypeNames.h" 34 #include "core/InputTypeNames.h"
35 #include "core/dom/DOMTokenList.h" 35 #include "core/dom/DOMTokenList.h"
36 #include "core/dom/Document.h"
37 #include "core/dom/Element.h"
38 #include "core/dom/Text.h"
36 #include "core/dom/shadow/ShadowRoot.h" 39 #include "core/dom/shadow/ShadowRoot.h"
37 #include "core/events/MouseEvent.h" 40 #include "core/events/MouseEvent.h"
38 #include "core/frame/LocalFrame.h" 41 #include "core/frame/LocalFrame.h"
39 #include "core/html/HTMLVideoElement.h" 42 #include "core/html/HTMLVideoElement.h"
40 #include "core/html/MediaController.h" 43 #include "core/html/MediaController.h"
41 #include "core/html/TimeRanges.h" 44 #include "core/html/TimeRanges.h"
42 #include "core/html/shadow/MediaControls.h" 45 #include "core/html/shadow/MediaControls.h"
46 #include "core/html/track/TextTrackList.h"
43 #include "core/layout/LayoutSlider.h" 47 #include "core/layout/LayoutSlider.h"
44 #include "core/layout/LayoutTheme.h" 48 #include "core/layout/LayoutTheme.h"
45 #include "core/layout/LayoutVideo.h" 49 #include "core/layout/LayoutVideo.h"
46 #include "core/page/EventHandler.h" 50 #include "core/page/EventHandler.h"
51 #include "platform/EventDispatchForbiddenScope.h"
47 #include "platform/RuntimeEnabledFeatures.h" 52 #include "platform/RuntimeEnabledFeatures.h"
53 #include "platform/text/PlatformLocale.h"
48 54
49 namespace blink { 55 namespace blink {
50 56
51 using namespace HTMLNames; 57 using namespace HTMLNames;
52 58
53 // This is the duration from mediaControls.css 59 // This is the duration from mediaControls.css
54 static const double fadeOutDuration = 0.3; 60 static const double fadeOutDuration = 0.3;
55 61
62 // track index attribute specifies trackIndex for text track list elements
63 static const char* trackIndexAttr = "x-webkit-track-index";
fs 2015/04/14 12:34:56 const char foo[] = ... Also since this should be
srivats 2015/04/16 23:37:19 I couldn't find the data- convention used for attr
fs 2015/04/17 11:54:46 I don't think the exact name should matter much -
srivats 2015/04/21 01:48:55 Done.
64
65 // when specified as trackIndex, disable text tracks
66 static const int trackIndexOffValue = -1;
67
56 static bool isUserInteractionEvent(Event* event) 68 static bool isUserInteractionEvent(Event* event)
57 { 69 {
58 const AtomicString& type = event->type(); 70 const AtomicString& type = event->type();
59 return type == EventTypeNames::mousedown 71 return type == EventTypeNames::mousedown
60 || type == EventTypeNames::mouseup 72 || type == EventTypeNames::mouseup
61 || type == EventTypeNames::click 73 || type == EventTypeNames::click
62 || type == EventTypeNames::dblclick 74 || type == EventTypeNames::dblclick
63 || event->isKeyboardEvent() 75 || event->isKeyboardEvent()
64 || event->isTouchEvent(); 76 || event->isTouchEvent();
65 } 77 }
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 button->setType(InputTypeNames::button); 346 button->setType(InputTypeNames::button);
335 button->setShadowPseudoId(AtomicString("-webkit-media-controls-toggle-closed -captions-button", AtomicString::ConstructFromLiteral)); 347 button->setShadowPseudoId(AtomicString("-webkit-media-controls-toggle-closed -captions-button", AtomicString::ConstructFromLiteral));
336 button->hide(); 348 button->hide();
337 return button.release(); 349 return button.release();
338 } 350 }
339 351
340 void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType() 352 void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType()
341 { 353 {
342 bool captionsVisible = mediaElement().closedCaptionsVisible(); 354 bool captionsVisible = mediaElement().closedCaptionsVisible();
343 setDisplayType(captionsVisible ? MediaHideClosedCaptionsButton : MediaShowCl osedCaptionsButton); 355 setDisplayType(captionsVisible ? MediaHideClosedCaptionsButton : MediaShowCl osedCaptionsButton);
344 setChecked(captionsVisible);
345 } 356 }
346 357
347 void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* e vent) 358 void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* e vent)
348 { 359 {
349 if (event->type() == EventTypeNames::click) { 360 if (event->type() == EventTypeNames::click) {
350 mediaElement().setClosedCaptionsVisible(!mediaElement().closedCaptionsVi sible()); 361 mediaControls().toggleClosedCaptionsTrackList();
351 setChecked(mediaElement().closedCaptionsVisible());
352 updateDisplayType(); 362 updateDisplayType();
353 event->setDefaultHandled(); 363 event->setDefaultHandled();
354 } 364 }
355 365
356 HTMLInputElement::defaultEventHandler(event); 366 HTMLInputElement::defaultEventHandler(event);
357 } 367 }
358 368
359 // ---------------------------- 369 // ----------------------------
360 370
371 MediaControlClosedCaptionsTrackListContainerElement::MediaControlClosedCaptionsT rackListContainerElement(MediaControls& mediaControls)
372 : MediaControlDivElement(mediaControls, MediaClosedCaptionsTrackListContaine r)
373 {
374 }
375
376 PassRefPtrWillBeRawPtr<MediaControlClosedCaptionsTrackListContainerElement>
377 MediaControlClosedCaptionsTrackListContainerElement::create(MediaControls& m ediaControls)
378 {
379 RefPtrWillBeRawPtr<MediaControlClosedCaptionsTrackListContainerElement> elem ent =
380 adoptRefWillBeNoop(new MediaControlClosedCaptionsTrackListContainerEleme nt(mediaControls));
381 element->setShadowPseudoId(AtomicString("-webkit-media-controls-closed-capti ons-track-list-container",
382 AtomicString::ConstructFromLiteral));
383 element->hide();
384 return element.release();
385 }
386
387 // ----------------------------
388
389 MediaControlClosedCaptionsTrackListElement::MediaControlClosedCaptionsTrackListE lement(MediaControls& mediaControls)
390 : MediaControlDivElement(mediaControls, MediaClosedCaptionsTrackList)
391 {
392 }
393
394 PassRefPtrWillBeRawPtr<MediaControlClosedCaptionsTrackListElement> MediaControlC losedCaptionsTrackListElement::create(MediaControls& mediaControls)
395 {
396 RefPtrWillBeRawPtr<MediaControlClosedCaptionsTrackListElement> element =
397 adoptRefWillBeNoop(new MediaControlClosedCaptionsTrackListElement(mediaC ontrols));
398 element->setShadowPseudoId(AtomicString("-webkit-media-controls-closed-capti ons-track-list",
fs 2015/04/14 12:34:56 I think we should avoid carrying the "closed capti
srivats 2015/04/16 23:37:20 Changed it here and everywhere in this CL
399 AtomicString::ConstructFromLiteral));
400 element->hide();
fs 2015/04/14 12:34:56 The container is already hidden, so this doesn't s
srivats 2015/04/16 23:37:20 Done.
401 return element.release();
402 }
403
404 void MediaControlClosedCaptionsTrackListElement::defaultEventHandler(Event* even t)
405 {
406 if (event->type() == EventTypeNames::change) {
407 // Identify which input element was selected and set track to showing
408 Node* target = event->target()->toNode();
409 if (!target || !target->isElementNode())
410 return;
411
412 bool validIndex;
413 int trackIndex = toElement(target)->getAttribute(trackIndexAttr).toInt(& validIndex);
414 if (!validIndex)
415 return;
416 bool isVisible = trackIndex != trackIndexOffValue;
417 if (isVisible && trackIndex >= 0)
418 mediaElement().showTextTrackAtIndex(trackIndex);
419
420 mediaElement().setClosedCaptionsVisible(isVisible);
fs 2015/04/14 12:34:56 If we need to call into HTMLMediaElement (directly
srivats 2015/04/16 23:37:19 Moved showTextTrackAtIndex to this file and settin
421
422 mediaControls().toggleClosedCaptionsTrackList();
423 event->setDefaultHandled();
424 }
425 }
fs 2015/04/14 12:34:57 Call the parent class?
srivats 2015/04/16 23:37:19 Done.
426
427 String MediaControlClosedCaptionsTrackListElement::getTextTrackLabel(TextTrack* track)
428 {
429 String trackLabel;
430
431 if (!(track->label().isNull() || track->label().isEmpty())) {
fs 2015/04/14 12:34:56 isEmpty implies isNull, so this can be simplified
srivats 2015/04/16 23:37:19 Done.
432 trackLabel = track->label();
433 } else {
434 if (!(track->language().isNull() || track->language().isEmpty()))
435 trackLabel = track->language();
436 else
437 trackLabel = String(mediaElement().locale().queryString(WebLocalized String::TextTracksNoLabel));
438 }
439
440 // When the track kind is captions, add a captions marker to distinguish bet ween captions and subtitles.
441 if (track->kind() == track->captionsKeyword())
442 trackLabel.append(String(mediaElement().locale().queryString(WebLocalize dString::TextTracksCaptionsMarker)));
fs 2015/04/14 12:34:56 Locale::queryString returns a String, so this cast
srivats 2015/04/16 23:37:19 Done.
443 return trackLabel;
444 }
445
446 RefPtrWillBeRawPtr<Element> MediaControlClosedCaptionsTrackListElement::createTe xtTrackListItem(const String& trackDisplayText, int trackIndex, bool isShowing)
447 {
448 Document* doc = &document();
fs 2015/04/14 12:34:56 Prefer a reference. Also 'document' rather than 'd
srivats 2015/04/16 23:37:19 Changed the variable name to document and changed
449 RefPtrWillBeRawPtr<Element> trackItem = doc->createElement(labelTag, false);
fs 2015/04/14 12:34:56 You can call the create() functions directly inste
srivats 2015/04/16 23:37:20 Calling Element::create() doesn't create an HTML e
fs 2015/04/17 11:54:46 I believe for this call it'd be HTMLLabelElement::
srivats 2015/04/21 01:48:55 Done.
450 trackItem->setShadowPseudoId(AtomicString("-webkit-media-controls-closed-cap tions-track-list-item",
451 AtomicString::ConstructFromLiteral));
452 RefPtrWillBeRawPtr<Element> trackItemInput = doc->createElement(inputTag, fa lse);
453 trackItemInput->setShadowPseudoId(AtomicString("-webkit-media-controls-close d-captions-track-list-item-input",
454 AtomicString::ConstructFromLiteral));
455 trackItemInput->setAttribute(typeAttr, InputTypeNames::radio);
456 trackItemInput->setAttribute(nameAttr, "tracks");
457 trackItemInput->setAttribute(trackIndexAttr, AtomicString::number(trackIndex ), ASSERT_NO_EXCEPTION);
458 if (!mediaElement().closedCaptionsVisible()) {
459 if (trackIndex == trackIndexOffValue)
460 toHTMLInputElement(trackItemInput)->setChecked(true);
461 } else {
462 if (trackIndex >= 0 && isShowing)
fs 2015/04/14 12:34:57 Looks like this means multiple tracks can be selec
srivats 2015/04/16 23:37:19 Since the track list is a list of input radio, it'
fs 2015/04/17 11:54:46 This is not guaranteed by this expression though A
srivats 2015/04/21 01:48:55 When multiple tracks are set to showing, it displa
463 toHTMLInputElement(trackItemInput)->setChecked(true);
464 }
465 trackItem->appendChild(trackItemInput);
466 trackItem->appendChild(doc->createTextNode(trackDisplayText));
467 return trackItem;
468 }
469
470 void MediaControlClosedCaptionsTrackListElement::refreshTextTrackListMenu()
471 {
472 if (!mediaElement().hasClosedCaptions() || !mediaElement().textTracksAreRead y())
473 return;
474
475 TextTrackList* trackList = mediaElement().textTracks();
476 if (!trackList || trackList->length() == 0)
fs 2015/04/14 12:34:56 If hasClosedCaptions() returns true, then there'll
srivats 2015/04/16 23:37:19 Good point. Removed.
477 return;
478
479 removeChildren();
480
481 // Construct a menu for subtitles and captions
482 EventDispatchForbiddenScope::AllowUserAgentEvents allowEvents;
483 Document* doc = &document();
484 RefPtrWillBeRawPtr<Element> tracksHeader = doc->createElement(h3Tag, false);
485 tracksHeader->setShadowPseudoId(AtomicString("-webkit-media-controls-closed- captions-track-list-header",
486 AtomicString::ConstructFromLiteral));
487 RefPtrWillBeRawPtr<Element> tracksSection = doc->createElement(divTag, false );
488
489 tracksHeader->appendChild(doc->createTextNode(mediaElement().locale().queryS tring(WebLocalizedString::TextTracksSubtitlesCC)));
fs 2015/04/14 12:34:56 What's the 'CC' suffix for - seems redundant unles
srivats 2015/04/16 23:37:19 I wasn't sure what the header should say. Safari u
fs 2015/04/17 11:54:46 Ok, so it's SubtitlesOrCaptions then. What the str
srivats 2015/04/21 01:48:55 That makes sense. I feel Subtitles And/Or Captions
fs 2015/04/21 12:13:34 Sounds OK to me.
srivats 2015/04/21 21:11:18 Done.
490 AtomicString tracksSectionId = AtomicString("tracks-header");
fs 2015/04/14 12:34:56 ConstructFromLiteral
srivats 2015/04/16 23:37:19 Done.
491 tracksHeader->setAttribute(idAttr, tracksSectionId);
492 tracksSection->setAttribute(roleAttr, radiogroupAttr.localName());
493 tracksSection->setAttribute(aria_labeledbyAttr, tracksSectionId);
494
495 String textTracksOffLabel = String(mediaElement().locale().queryString(WebLo calizedString::TextTracksOff));
fs 2015/04/14 12:34:56 queryString returns a String.
srivats 2015/04/16 23:37:19 Done.
496 tracksSection->appendChild(createTextTrackListItem(textTracksOffLabel, track IndexOffValue, false));
497
498 for (unsigned i = 0; i < trackList->length(); i++) {
499 TextTrack* track = trackList->item(i);
500 RefPtrWillBeRawPtr<Element> trackItem =
501 createTextTrackListItem(getTextTrackLabel(track), i, track->mode() = = TextTrack::showingKeyword());
fs 2015/04/14 12:34:56 TextTrack::trackIndex() can already give 'i', so i
srivats 2015/04/16 23:37:19 Passing in TextTrack won't help with reusing this
fs 2015/04/17 11:54:46 I guess that's a fair point to make, although I gu
srivats 2015/04/21 01:48:55 Done.
502 tracksSection->appendChild(trackItem);
503 }
504 appendChild(tracksHeader);
505 appendChild(tracksSection);
506 }
507
508 // ----------------------------
509
361 MediaControlTimelineElement::MediaControlTimelineElement(MediaControls& mediaCon trols) 510 MediaControlTimelineElement::MediaControlTimelineElement(MediaControls& mediaCon trols)
362 : MediaControlInputElement(mediaControls, MediaSlider) 511 : MediaControlInputElement(mediaControls, MediaSlider)
363 { 512 {
364 } 513 }
365 514
366 PassRefPtrWillBeRawPtr<MediaControlTimelineElement> MediaControlTimelineElement: :create(MediaControls& mediaControls) 515 PassRefPtrWillBeRawPtr<MediaControlTimelineElement> MediaControlTimelineElement: :create(MediaControls& mediaControls)
367 { 516 {
368 RefPtrWillBeRawPtr<MediaControlTimelineElement> timeline = adoptRefWillBeNoo p(new MediaControlTimelineElement(mediaControls)); 517 RefPtrWillBeRawPtr<MediaControlTimelineElement> timeline = adoptRefWillBeNoo p(new MediaControlTimelineElement(mediaControls));
369 timeline->ensureClosedShadowRoot(); 518 timeline->ensureClosedShadowRoot();
370 timeline->setType(InputTypeNames::range); 519 timeline->setType(InputTypeNames::range);
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 } 754 }
606 755
607 PassRefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> MediaControlCurren tTimeDisplayElement::create(MediaControls& mediaControls) 756 PassRefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> MediaControlCurren tTimeDisplayElement::create(MediaControls& mediaControls)
608 { 757 {
609 RefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> element = adoptRef WillBeNoop(new MediaControlCurrentTimeDisplayElement(mediaControls)); 758 RefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> element = adoptRef WillBeNoop(new MediaControlCurrentTimeDisplayElement(mediaControls));
610 element->setShadowPseudoId(AtomicString("-webkit-media-controls-current-time -display", AtomicString::ConstructFromLiteral)); 759 element->setShadowPseudoId(AtomicString("-webkit-media-controls-current-time -display", AtomicString::ConstructFromLiteral));
611 return element.release(); 760 return element.release();
612 } 761 }
613 762
614 } // namespace blink 763 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698