Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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" | |
| 36 #include "core/dom/Fullscreen.h" | 38 #include "core/dom/Fullscreen.h" |
| 39 #include "core/dom/Text.h" | |
| 37 #include "core/dom/shadow/ShadowRoot.h" | 40 #include "core/dom/shadow/ShadowRoot.h" |
| 38 #include "core/events/MouseEvent.h" | 41 #include "core/events/MouseEvent.h" |
| 39 #include "core/frame/LocalFrame.h" | 42 #include "core/frame/LocalFrame.h" |
| 43 #include "core/html/HTMLHeadingElement.h" | |
| 44 #include "core/html/HTMLLabelElement.h" | |
| 40 #include "core/html/HTMLVideoElement.h" | 45 #include "core/html/HTMLVideoElement.h" |
| 41 #include "core/html/MediaController.h" | 46 #include "core/html/MediaController.h" |
| 42 #include "core/html/TimeRanges.h" | 47 #include "core/html/TimeRanges.h" |
| 43 #include "core/html/shadow/MediaControls.h" | 48 #include "core/html/shadow/MediaControls.h" |
| 49 #include "core/html/track/TextTrackList.h" | |
| 44 #include "core/layout/LayoutSlider.h" | 50 #include "core/layout/LayoutSlider.h" |
| 45 #include "core/layout/LayoutTheme.h" | 51 #include "core/layout/LayoutTheme.h" |
| 46 #include "core/layout/LayoutVideo.h" | 52 #include "core/layout/LayoutVideo.h" |
| 47 #include "core/page/EventHandler.h" | 53 #include "core/page/EventHandler.h" |
| 54 #include "platform/EventDispatchForbiddenScope.h" | |
| 48 #include "platform/RuntimeEnabledFeatures.h" | 55 #include "platform/RuntimeEnabledFeatures.h" |
| 56 #include "platform/text/PlatformLocale.h" | |
| 49 | 57 |
| 50 namespace blink { | 58 namespace blink { |
| 51 | 59 |
| 52 using namespace HTMLNames; | 60 using namespace HTMLNames; |
| 53 | 61 |
| 54 // This is the duration from mediaControls.css | 62 // This is the duration from mediaControls.css |
| 55 static const double fadeOutDuration = 0.3; | 63 static const double fadeOutDuration = 0.3; |
| 56 | 64 |
| 65 // track index attribute specifies trackIndex for text track list elements | |
|
philipj_slow
2015/05/05 14:36:57
This comment doesn't explain what this is for. AFA
srivats
2016/02/23 01:39:26
Done.
| |
| 66 static const char trackIndexAttr[] = "data-webkit-track-index"; | |
|
philipj_slow
2015/05/05 14:36:57
Since the element is inaccessible to the outside,
srivats
2016/02/23 01:39:27
Done.
| |
| 67 | |
| 68 // when specified as trackIndex, disable text tracks | |
|
philipj_slow
2015/05/05 14:36:57
Is a special value really needed for this, couldn'
srivats
2016/02/23 01:39:26
The -1 id helps with testing mostly to track the "
| |
| 69 static const int trackIndexOffValue = -1; | |
| 70 | |
| 57 static bool isUserInteractionEvent(Event* event) | 71 static bool isUserInteractionEvent(Event* event) |
| 58 { | 72 { |
| 59 const AtomicString& type = event->type(); | 73 const AtomicString& type = event->type(); |
| 60 return type == EventTypeNames::mousedown | 74 return type == EventTypeNames::mousedown |
| 61 || type == EventTypeNames::mouseup | 75 || type == EventTypeNames::mouseup |
| 62 || type == EventTypeNames::click | 76 || type == EventTypeNames::click |
| 63 || type == EventTypeNames::dblclick | 77 || type == EventTypeNames::dblclick |
| 64 || event->isKeyboardEvent() | 78 || event->isKeyboardEvent() |
| 65 || event->isTouchEvent(); | 79 || event->isTouchEvent(); |
| 66 } | 80 } |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 335 button->setType(InputTypeNames::button); | 349 button->setType(InputTypeNames::button); |
| 336 button->setShadowPseudoId(AtomicString("-webkit-media-controls-toggle-closed -captions-button", AtomicString::ConstructFromLiteral)); | 350 button->setShadowPseudoId(AtomicString("-webkit-media-controls-toggle-closed -captions-button", AtomicString::ConstructFromLiteral)); |
| 337 button->hide(); | 351 button->hide(); |
| 338 return button.release(); | 352 return button.release(); |
| 339 } | 353 } |
| 340 | 354 |
| 341 void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType() | 355 void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType() |
| 342 { | 356 { |
| 343 bool captionsVisible = mediaElement().closedCaptionsVisible(); | 357 bool captionsVisible = mediaElement().closedCaptionsVisible(); |
| 344 setDisplayType(captionsVisible ? MediaHideClosedCaptionsButton : MediaShowCl osedCaptionsButton); | 358 setDisplayType(captionsVisible ? MediaHideClosedCaptionsButton : MediaShowCl osedCaptionsButton); |
| 345 setChecked(captionsVisible); | |
| 346 } | 359 } |
| 347 | 360 |
| 348 void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* e vent) | 361 void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* e vent) |
| 349 { | 362 { |
| 350 if (event->type() == EventTypeNames::click) { | 363 if (event->type() == EventTypeNames::click) { |
| 351 mediaElement().setClosedCaptionsVisible(!mediaElement().closedCaptionsVi sible()); | 364 mediaControls().toggleTextTrackList(); |
| 352 setChecked(mediaElement().closedCaptionsVisible()); | |
| 353 updateDisplayType(); | 365 updateDisplayType(); |
| 354 event->setDefaultHandled(); | 366 event->setDefaultHandled(); |
| 355 } | 367 } |
| 356 | 368 |
| 357 HTMLInputElement::defaultEventHandler(event); | 369 HTMLInputElement::defaultEventHandler(event); |
| 358 } | 370 } |
| 359 | 371 |
| 360 // ---------------------------- | 372 // ---------------------------- |
| 361 | 373 |
| 374 MediaControlTextTrackListElement::MediaControlTextTrackListElement(MediaControls & mediaControls) | |
| 375 : MediaControlDivElement(mediaControls, MediaTextTrackList) | |
| 376 { | |
| 377 } | |
| 378 | |
| 379 PassRefPtrWillBeRawPtr<MediaControlTextTrackListElement> MediaControlTextTrackLi stElement::create(MediaControls& mediaControls) | |
| 380 { | |
| 381 RefPtrWillBeRawPtr<MediaControlTextTrackListElement> element = | |
| 382 adoptRefWillBeNoop(new MediaControlTextTrackListElement(mediaControls)); | |
| 383 element->setShadowPseudoId(AtomicString("-internal-media-controls-text-track -list", | |
| 384 AtomicString::ConstructFromLiteral)); | |
| 385 element->hide(); | |
| 386 return element.release(); | |
| 387 } | |
| 388 | |
| 389 void MediaControlTextTrackListElement::defaultEventHandler(Event* event) | |
| 390 { | |
| 391 if (event->type() == EventTypeNames::change) { | |
| 392 // Identify which input element was selected and set track to showing | |
| 393 Node* target = event->target()->toNode(); | |
| 394 if (!target || !target->isElementNode()) | |
| 395 return; | |
| 396 | |
| 397 bool validIndex; | |
| 398 int trackIndex = toElement(target)->getAttribute(trackIndexAttr).toInt(& validIndex); | |
| 399 ASSERT(validIndex); | |
| 400 if (trackIndex != trackIndexOffValue) { | |
| 401 showTextTrackAtIndex(trackIndex); | |
|
philipj_slow
2015/05/05 14:36:56
What happens if the text tracks change while this
srivats
2016/02/23 01:39:27
I tested this out by removing a track using the co
philipj_slow
2016/03/01 11:21:04
Refreshing the menu also seems wrong, maybe the us
| |
| 402 mediaElement().setClosedCaptionsVisible(true); | |
|
philipj_slow
2015/05/05 14:36:57
I think setClosedCaptionsVisible() needs to change
fs
2015/05/05 15:32:44
I agree with this, but I think we need a "step" in
philipj_slow
2015/05/06 09:28:43
Ahem, will get to that review too...
srivats
2016/02/23 01:39:27
Not using setClosedCaptionsVisible anymore and it'
| |
| 403 } else { | |
| 404 mediaElement().setClosedCaptionsVisible(false); | |
| 405 } | |
| 406 | |
| 407 mediaControls().toggleTextTrackList(); | |
| 408 event->setDefaultHandled(); | |
| 409 } | |
| 410 HTMLDivElement::defaultEventHandler(event); | |
| 411 } | |
| 412 | |
| 413 void MediaControlTextTrackListElement::showTextTrackAtIndex(unsigned indexToEnab le) | |
| 414 { | |
| 415 TextTrackList* trackList = mediaElement().textTracks(); | |
| 416 for (unsigned i = 0; i < trackList->length(); ++i) { | |
| 417 TextTrack* track = trackList->item(i); | |
| 418 if (!track->isRenderable()) | |
|
philipj_slow
2015/05/05 14:36:57
Is this really needed?
fs
2015/05/05 15:32:44
I probably suggested this in one of the earlier CL
| |
| 419 continue; | |
| 420 if (i == indexToEnable && indexToEnable < trackList->length()) { | |
|
philipj_slow
2015/05/05 14:36:57
The indexToEnable < trackList->length() check coul
srivats
2016/02/23 01:39:27
Done.
| |
| 421 track->setMode(TextTrack::showingKeyword()); | |
| 422 mediaElement().disableAutomaticTextTrackSelection(); | |
|
philipj_slow
2015/05/05 14:36:57
This is the bit I'm saying should happen the same
| |
| 423 } else if (track->mode() == TextTrack::showingKeyword()) { | |
| 424 track->setMode(TextTrack::disabledKeyword()); | |
| 425 } | |
| 426 } | |
| 427 } | |
| 428 | |
| 429 String MediaControlTextTrackListElement::getTextTrackLabel(TextTrack* track) | |
| 430 { | |
| 431 if (!track) | |
| 432 return mediaElement().locale().queryString(WebLocalizedString::TextTrack sOff); | |
| 433 | |
| 434 String trackLabel = track->label(); | |
| 435 | |
| 436 if (trackLabel.isEmpty()) | |
| 437 trackLabel = track->language(); | |
|
philipj_slow
2015/05/05 14:36:56
This seems risky. People could use <track srclang=
fs
2015/05/05 15:32:44
ICU quite possibly have that data already. No idea
| |
| 438 | |
| 439 if (trackLabel.isEmpty()) | |
| 440 trackLabel = String(mediaElement().locale().queryString(WebLocalizedStri ng::TextTracksNoLabel)); | |
| 441 | |
| 442 // When the track kind is captions, add a captions marker to distinguish bet ween captions and subtitles. | |
|
philipj_slow
2015/05/05 14:36:57
I'm not sure this will make sense in all languages
fs
2015/05/05 15:32:44
Since it is localized, it could well be "" for Swe
srivats
2016/02/23 01:39:27
UX suggested I use icons here to differentiate bet
philipj_slow
2016/03/01 11:21:04
And I really like that new subtitles icon!
| |
| 443 if (track->kind() == track->captionsKeyword()) | |
| 444 trackLabel.append(mediaElement().locale().queryString(WebLocalizedString ::TextTracksCaptionsMarker)); | |
| 445 return trackLabel; | |
| 446 } | |
| 447 | |
| 448 RefPtrWillBeRawPtr<Element> MediaControlTextTrackListElement::createTextTrackLis tItem(TextTrack* track) | |
|
philipj_slow
2015/05/05 14:36:57
This is a bit hard to understand, what does it mea
fs
2015/05/05 15:32:44
I believe I suggested to pass a track, because the
philipj_slow
2015/05/06 09:28:43
Sorry, I skipped the history and comments, so we'r
srivats
2016/02/23 01:39:26
Added a comment explaining what the nullptr is for
| |
| 449 { | |
| 450 Document& document = this->document(); | |
| 451 int trackIndex = track ? track->trackIndex() : trackIndexOffValue; | |
| 452 RefPtrWillBeRawPtr<HTMLLabelElement> trackItem = HTMLLabelElement::create(do cument, 0); | |
| 453 trackItem->setShadowPseudoId(AtomicString("-internal-media-controls-text-tra ck-list-item", | |
| 454 AtomicString::ConstructFromLiteral)); | |
| 455 RefPtrWillBeRawPtr<HTMLInputElement> trackItemInput = HTMLInputElement::crea te(document, 0, false); | |
| 456 trackItemInput->setShadowPseudoId(AtomicString("-internal-media-controls-tex t-track-list-item-input", | |
| 457 AtomicString::ConstructFromLiteral)); | |
| 458 trackItemInput->setType(InputTypeNames::radio); | |
| 459 trackItemInput->setAttribute(trackIndexAttr, AtomicString::number(trackIndex ), ASSERT_NO_EXCEPTION); | |
| 460 if (!mediaElement().closedCaptionsVisible()) { | |
| 461 if (!track) | |
| 462 trackItemInput->setChecked(true); | |
| 463 } else { | |
| 464 if (track && track->mode() == TextTrack::showingKeyword()) | |
|
philipj_slow
2015/05/05 14:36:57
If there are multiple tracks showing, I guess they
srivats
2016/02/23 01:39:27
Yes. I tested this case out.
| |
| 465 trackItemInput->setChecked(true); | |
| 466 } | |
| 467 trackItem->appendChild(trackItemInput); | |
| 468 trackItem->appendChild(Text::create(document, getTextTrackLabel(track))); | |
| 469 return trackItem; | |
| 470 } | |
| 471 | |
| 472 void MediaControlTextTrackListElement::refreshTextTrackListMenu() | |
| 473 { | |
| 474 DEFINE_STATIC_LOCAL(const AtomicString, tracksSectionId, ("tracks-header", A tomicString::ConstructFromLiteral)); | |
| 475 if (!mediaElement().hasClosedCaptions() || !mediaElement().textTracksAreRead y()) | |
| 476 return; | |
| 477 | |
| 478 removeChildren(); | |
| 479 | |
| 480 // Construct a menu for subtitles and captions | |
| 481 EventDispatchForbiddenScope::AllowUserAgentEvents allowEvents; | |
| 482 Document& document = this->document(); | |
| 483 RefPtrWillBeRawPtr<HTMLHeadingElement> tracksHeader = HTMLHeadingElement::cr eate(h3Tag, document); | |
| 484 tracksHeader->setShadowPseudoId(AtomicString("-internal-media-controls-text- track-list-header", | |
| 485 AtomicString::ConstructFromLiteral)); | |
| 486 RefPtrWillBeRawPtr<HTMLDivElement> tracksSection = HTMLDivElement::create(do cument); | |
| 487 | |
| 488 tracksHeader->appendChild(Text::create(document, | |
| 489 mediaElement().locale().queryString(WebLocalizedString::TextTracksSubtit les))); | |
|
philipj_slow
2015/05/05 14:36:57
Is this line needed at all? Even if it were change
srivats
2016/02/23 01:39:27
I got some UX feedback on this and they're fine wi
| |
| 490 tracksHeader->setAttribute(idAttr, tracksSectionId); | |
| 491 tracksSection->setAttribute(roleAttr, radiogroupAttr.localName()); | |
| 492 tracksSection->setAttribute(aria_labeledbyAttr, tracksSectionId); | |
|
philipj_slow
2015/05/05 14:36:56
Won't we end up with multiple elements with the sa
fs
2015/05/05 15:32:44
I think it would be weird if it wasn't scoped...
philipj_slow
2015/05/06 09:28:43
Yeah, it certainly would be, just want to make sur
srivats
2016/02/23 01:39:27
No more header.
| |
| 493 | |
| 494 tracksSection->appendChild(createTextTrackListItem(nullptr)); | |
|
philipj_slow
2015/05/05 14:36:57
So this is where it looks a bit weird. Maybe if th
srivats
2016/02/23 01:39:26
I added a comment explaining what the nullptr is f
| |
| 495 | |
| 496 TextTrackList* trackList = mediaElement().textTracks(); | |
| 497 for (unsigned i = 0; i < trackList->length(); i++) { | |
| 498 TextTrack* track = trackList->item(i); | |
| 499 if (!track->isRenderable()) | |
| 500 continue; | |
| 501 RefPtrWillBeRawPtr<Element> trackItem = createTextTrackListItem(track); | |
| 502 tracksSection->appendChild(trackItem); | |
| 503 } | |
| 504 appendChild(tracksHeader); | |
| 505 appendChild(tracksSection); | |
| 506 } | |
| 507 | |
| 508 // ---------------------------- | |
| 509 | |
| 362 MediaControlTimelineElement::MediaControlTimelineElement(MediaControls& mediaCon trols) | 510 MediaControlTimelineElement::MediaControlTimelineElement(MediaControls& mediaCon trols) |
| 363 : MediaControlInputElement(mediaControls, MediaSlider) | 511 : MediaControlInputElement(mediaControls, MediaSlider) |
| 364 { | 512 { |
| 365 } | 513 } |
| 366 | 514 |
| 367 PassRefPtrWillBeRawPtr<MediaControlTimelineElement> MediaControlTimelineElement: :create(MediaControls& mediaControls) | 515 PassRefPtrWillBeRawPtr<MediaControlTimelineElement> MediaControlTimelineElement: :create(MediaControls& mediaControls) |
| 368 { | 516 { |
| 369 RefPtrWillBeRawPtr<MediaControlTimelineElement> timeline = adoptRefWillBeNoo p(new MediaControlTimelineElement(mediaControls)); | 517 RefPtrWillBeRawPtr<MediaControlTimelineElement> timeline = adoptRefWillBeNoo p(new MediaControlTimelineElement(mediaControls)); |
| 370 timeline->ensureUserAgentShadowRoot(); | 518 timeline->ensureUserAgentShadowRoot(); |
| 371 timeline->setType(InputTypeNames::range); | 519 timeline->setType(InputTypeNames::range); |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 607 } | 755 } |
| 608 | 756 |
| 609 PassRefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> MediaControlCurren tTimeDisplayElement::create(MediaControls& mediaControls) | 757 PassRefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> MediaControlCurren tTimeDisplayElement::create(MediaControls& mediaControls) |
| 610 { | 758 { |
| 611 RefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> element = adoptRef WillBeNoop(new MediaControlCurrentTimeDisplayElement(mediaControls)); | 759 RefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> element = adoptRef WillBeNoop(new MediaControlCurrentTimeDisplayElement(mediaControls)); |
| 612 element->setShadowPseudoId(AtomicString("-webkit-media-controls-current-time -display", AtomicString::ConstructFromLiteral)); | 760 element->setShadowPseudoId(AtomicString("-webkit-media-controls-current-time -display", AtomicString::ConstructFromLiteral)); |
| 613 return element.release(); | 761 return element.release(); |
| 614 } | 762 } |
| 615 | 763 |
| 616 } // namespace blink | 764 } // namespace blink |
| OLD | NEW |