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

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: Removed container and addressed comments from fs 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
« no previous file with comments | « Source/core/html/shadow/MediaControlElements.h ('k') | Source/core/html/shadow/MediaControls.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
42 #include "core/html/HTMLLabelElement.h"
39 #include "core/html/HTMLVideoElement.h" 43 #include "core/html/HTMLVideoElement.h"
40 #include "core/html/MediaController.h" 44 #include "core/html/MediaController.h"
41 #include "core/html/TimeRanges.h" 45 #include "core/html/TimeRanges.h"
42 #include "core/html/shadow/MediaControls.h" 46 #include "core/html/shadow/MediaControls.h"
47 #include "core/html/track/TextTrackList.h"
43 #include "core/layout/LayoutSlider.h" 48 #include "core/layout/LayoutSlider.h"
44 #include "core/layout/LayoutTheme.h" 49 #include "core/layout/LayoutTheme.h"
45 #include "core/layout/LayoutVideo.h" 50 #include "core/layout/LayoutVideo.h"
46 #include "core/page/EventHandler.h" 51 #include "core/page/EventHandler.h"
52 #include "platform/EventDispatchForbiddenScope.h"
47 #include "platform/RuntimeEnabledFeatures.h" 53 #include "platform/RuntimeEnabledFeatures.h"
54 #include "platform/text/PlatformLocale.h"
48 55
49 namespace blink { 56 namespace blink {
50 57
51 using namespace HTMLNames; 58 using namespace HTMLNames;
52 59
53 // This is the duration from mediaControls.css 60 // This is the duration from mediaControls.css
54 static const double fadeOutDuration = 0.3; 61 static const double fadeOutDuration = 0.3;
55 62
63 // track index attribute specifies trackIndex for text track list elements
64 static const char trackIndexAttr[] = "data-webkit-track-index";
65
66 // when specified as trackIndex, disable text tracks
67 static const int trackIndexOffValue = -1;
68
56 static bool isUserInteractionEvent(Event* event) 69 static bool isUserInteractionEvent(Event* event)
57 { 70 {
58 const AtomicString& type = event->type(); 71 const AtomicString& type = event->type();
59 return type == EventTypeNames::mousedown 72 return type == EventTypeNames::mousedown
60 || type == EventTypeNames::mouseup 73 || type == EventTypeNames::mouseup
61 || type == EventTypeNames::click 74 || type == EventTypeNames::click
62 || type == EventTypeNames::dblclick 75 || type == EventTypeNames::dblclick
63 || event->isKeyboardEvent() 76 || event->isKeyboardEvent()
64 || event->isTouchEvent(); 77 || event->isTouchEvent();
65 } 78 }
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 button->setType(InputTypeNames::button); 347 button->setType(InputTypeNames::button);
335 button->setShadowPseudoId(AtomicString("-webkit-media-controls-toggle-closed -captions-button", AtomicString::ConstructFromLiteral)); 348 button->setShadowPseudoId(AtomicString("-webkit-media-controls-toggle-closed -captions-button", AtomicString::ConstructFromLiteral));
336 button->hide(); 349 button->hide();
337 return button.release(); 350 return button.release();
338 } 351 }
339 352
340 void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType() 353 void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType()
341 { 354 {
342 bool captionsVisible = mediaElement().closedCaptionsVisible(); 355 bool captionsVisible = mediaElement().closedCaptionsVisible();
343 setDisplayType(captionsVisible ? MediaHideClosedCaptionsButton : MediaShowCl osedCaptionsButton); 356 setDisplayType(captionsVisible ? MediaHideClosedCaptionsButton : MediaShowCl osedCaptionsButton);
344 setChecked(captionsVisible);
345 } 357 }
346 358
347 void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* e vent) 359 void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* e vent)
348 { 360 {
349 if (event->type() == EventTypeNames::click) { 361 if (event->type() == EventTypeNames::click) {
350 mediaElement().setClosedCaptionsVisible(!mediaElement().closedCaptionsVi sible()); 362 mediaControls().toggleTextTrackList();
351 setChecked(mediaElement().closedCaptionsVisible());
352 updateDisplayType(); 363 updateDisplayType();
353 event->setDefaultHandled(); 364 event->setDefaultHandled();
354 } 365 }
355 366
356 HTMLInputElement::defaultEventHandler(event); 367 HTMLInputElement::defaultEventHandler(event);
357 } 368 }
358 369
359 // ---------------------------- 370 // ----------------------------
360 371
372 MediaControlTextTrackListElement::MediaControlTextTrackListElement(MediaControls & mediaControls)
373 : MediaControlDivElement(mediaControls, MediaTextTrackList)
374 {
375 }
376
377 PassRefPtrWillBeRawPtr<MediaControlTextTrackListElement> MediaControlTextTrackLi stElement::create(MediaControls& mediaControls)
378 {
379 RefPtrWillBeRawPtr<MediaControlTextTrackListElement> element =
380 adoptRefWillBeNoop(new MediaControlTextTrackListElement(mediaControls));
381 element->setShadowPseudoId(AtomicString("-webkit-media-controls-text-track-l ist",
fs 2015/04/21 12:13:34 s/webkit/internal/ for all new pseudo elements IIR
srivats 2015/04/21 21:11:18 Done.
382 AtomicString::ConstructFromLiteral));
383 element->hide();
384 return element.release();
385 }
386
387 void MediaControlTextTrackListElement::defaultEventHandler(Event* event)
388 {
389 if (event->type() == EventTypeNames::change) {
390 // Identify which input element was selected and set track to showing
391 Node* target = event->target()->toNode();
392 if (!target || !target->isElementNode())
393 return;
394
395 bool validIndex;
396 int trackIndex = toElement(target)->getAttribute(trackIndexAttr).toInt(& validIndex);
397 if (!validIndex)
fs 2015/04/21 12:13:34 This seems "unexpected", so maybe it should suffic
srivats 2015/04/21 21:11:18 Done.
398 return;
399 if (trackIndex != trackIndexOffValue) {
400 showTextTrackAtIndex(trackIndex);
401 mediaElement().setClosedCaptionsVisible(true);
402 } else {
403 mediaElement().setClosedCaptionsVisible(false);
404 }
405
406 mediaControls().toggleTextTrackList();
407 event->setDefaultHandled();
408 }
409 HTMLDivElement::defaultEventHandler(event);
410 }
411
412 void MediaControlTextTrackListElement::showTextTrackAtIndex(unsigned index)
413 {
414 TextTrackList* trackList = mediaElement().textTracks();
415 for (unsigned i = 0; i < trackList->length(); ++i) {
416 TextTrack* track = trackList->item(i);
417 if (track->mode() == TextTrack::showingKeyword())
fs 2015/04/21 12:13:34 Should check isRenderable() here too I think. Migh
srivats 2015/04/21 21:11:18 Done.
418 track->setMode(TextTrack::disabledKeyword());
419 }
420
421 if (index < trackList->length()) {
422 TextTrack* track = trackList->item(index);
423 if (!track->isRenderable())
424 return;
425 track->setMode(TextTrack::showingKeyword());
426 mediaElement().disableAutomaticTextTrackSelection();
427 }
428 }
429
430 String MediaControlTextTrackListElement::getTextTrackLabel(TextTrack* track)
431 {
432 if (!track)
433 return mediaElement().locale().queryString(WebLocalizedString::TextTrack sOff);
434
435 String trackLabel = track->label();
436
437 if (trackLabel.isEmpty())
438 trackLabel = track->language();
439
440 if (trackLabel.isEmpty())
441 trackLabel = String(mediaElement().locale().queryString(WebLocalizedStri ng::TextTracksNoLabel));
442
443 // When the track kind is captions, add a captions marker to distinguish bet ween captions and subtitles.
444 if (track->kind() == track->captionsKeyword())
445 trackLabel.append(mediaElement().locale().queryString(WebLocalizedString ::TextTracksCaptionsMarker));
446 return trackLabel;
447 }
448
449 RefPtrWillBeRawPtr<Element> MediaControlTextTrackListElement::createTextTrackLis tItem(TextTrack* track)
450 {
451 Document& document = this->document();
452 int trackIndex = track ? track->trackIndex() : trackIndexOffValue;
453 RefPtrWillBeRawPtr<HTMLLabelElement> trackItem = HTMLLabelElement::create(do cument, 0);
454 trackItem->setShadowPseudoId(AtomicString("-webkit-media-controls-text-track -list-item",
455 AtomicString::ConstructFromLiteral));
456 RefPtrWillBeRawPtr<HTMLInputElement> trackItemInput = HTMLInputElement::crea te(document, 0, false);
457 trackItemInput->setShadowPseudoId(AtomicString("-webkit-media-controls-text- track-list-item-input",
458 AtomicString::ConstructFromLiteral));
459 trackItemInput->setType(InputTypeNames::radio);
460 trackItemInput->setAttribute(nameAttr, AtomicString("tracks", AtomicString:: ConstructFromLiteral));
461 trackItemInput->setAttribute(trackIndexAttr, AtomicString::number(trackIndex ), ASSERT_NO_EXCEPTION);
462 if (!mediaElement().closedCaptionsVisible()) {
463 if (!track)
464 trackItemInput->setChecked(true);
465 } else {
466 if (track && track->mode() == TextTrack::showingKeyword())
467 trackItemInput->setChecked(true);
468 }
469 trackItem->appendChild(trackItemInput);
470 trackItem->appendChild(document.createTextNode(getTextTrackLabel(track)));
fs 2015/04/21 12:13:34 document.createTextNode(...) -> Text::create(docum
srivats 2015/04/21 21:11:18 Done.
471 return trackItem;
472 }
473
474 void MediaControlTextTrackListElement::refreshTextTrackListMenu()
475 {
476 DEFINE_STATIC_LOCAL(const AtomicString, tracksSectionId, ("tracks-header", A tomicString::ConstructFromLiteral));
477 if (!mediaElement().hasClosedCaptions() || !mediaElement().textTracksAreRead y())
478 return;
479
480 removeChildren();
481
482 // Construct a menu for subtitles and captions
483 EventDispatchForbiddenScope::AllowUserAgentEvents allowEvents;
484 Document& document = this->document();
485 RefPtrWillBeRawPtr<HTMLElement> tracksHeader = HTMLElement::create(h3Tag, do cument);
fs 2015/04/21 12:13:34 HTMLElement -> HTMLHeadingElement
srivats 2015/04/21 21:11:18 Done.
486 tracksHeader->setShadowPseudoId(AtomicString("-webkit-media-controls-text-tr ack-list-header",
487 AtomicString::ConstructFromLiteral));
488 RefPtrWillBeRawPtr<HTMLDivElement> tracksSection = HTMLDivElement::create(do cument);
489
490 tracksHeader->appendChild(document.createTextNode(mediaElement().locale().qu eryString(WebLocalizedString::TextTracksSubtitlesCC)));
491 tracksHeader->setAttribute(idAttr, tracksSectionId);
492 tracksSection->setAttribute(roleAttr, radiogroupAttr.localName());
493 tracksSection->setAttribute(aria_labeledbyAttr, tracksSectionId);
494
495 tracksSection->appendChild(createTextTrackListItem(nullptr));
496
497 TextTrackList* trackList = mediaElement().textTracks();
498 for (unsigned i = 0; i < trackList->length(); i++) {
499 TextTrack* track = trackList->item(i);
500 if (!track->isRenderable())
501 continue;
502 RefPtrWillBeRawPtr<Element> trackItem = createTextTrackListItem(track);
503 tracksSection->appendChild(trackItem);
504 }
505 appendChild(tracksHeader);
506 appendChild(tracksSection);
507 }
508
509 // ----------------------------
510
361 MediaControlTimelineElement::MediaControlTimelineElement(MediaControls& mediaCon trols) 511 MediaControlTimelineElement::MediaControlTimelineElement(MediaControls& mediaCon trols)
362 : MediaControlInputElement(mediaControls, MediaSlider) 512 : MediaControlInputElement(mediaControls, MediaSlider)
363 { 513 {
364 } 514 }
365 515
366 PassRefPtrWillBeRawPtr<MediaControlTimelineElement> MediaControlTimelineElement: :create(MediaControls& mediaControls) 516 PassRefPtrWillBeRawPtr<MediaControlTimelineElement> MediaControlTimelineElement: :create(MediaControls& mediaControls)
367 { 517 {
368 RefPtrWillBeRawPtr<MediaControlTimelineElement> timeline = adoptRefWillBeNoo p(new MediaControlTimelineElement(mediaControls)); 518 RefPtrWillBeRawPtr<MediaControlTimelineElement> timeline = adoptRefWillBeNoo p(new MediaControlTimelineElement(mediaControls));
369 timeline->ensureUserAgentShadowRoot(); 519 timeline->ensureUserAgentShadowRoot();
370 timeline->setType(InputTypeNames::range); 520 timeline->setType(InputTypeNames::range);
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 } 755 }
606 756
607 PassRefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> MediaControlCurren tTimeDisplayElement::create(MediaControls& mediaControls) 757 PassRefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> MediaControlCurren tTimeDisplayElement::create(MediaControls& mediaControls)
608 { 758 {
609 RefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> element = adoptRef WillBeNoop(new MediaControlCurrentTimeDisplayElement(mediaControls)); 759 RefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> element = adoptRef WillBeNoop(new MediaControlCurrentTimeDisplayElement(mediaControls));
610 element->setShadowPseudoId(AtomicString("-webkit-media-controls-current-time -display", AtomicString::ConstructFromLiteral)); 760 element->setShadowPseudoId(AtomicString("-webkit-media-controls-current-time -display", AtomicString::ConstructFromLiteral));
611 return element.release(); 761 return element.release();
612 } 762 }
613 763
614 } // namespace blink 764 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/html/shadow/MediaControlElements.h ('k') | Source/core/html/shadow/MediaControls.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698