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" | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |