| Index: Source/core/html/HTMLMediaElement.cpp
|
| diff --git a/Source/core/html/HTMLMediaElement.cpp b/Source/core/html/HTMLMediaElement.cpp
|
| index 078522f4c31639712386d260f339b3ff11b03f63..ad0c827b1aab852e0650d3e655230bb38807da11 100644
|
| --- a/Source/core/html/HTMLMediaElement.cpp
|
| +++ b/Source/core/html/HTMLMediaElement.cpp
|
| @@ -3183,10 +3183,43 @@ bool HTMLMediaElement::closedCaptionsVisible() const
|
| return m_closedCaptionsVisible;
|
| }
|
|
|
| +static void assertShadowRootChildren(ShadowRoot& shadowRoot)
|
| +{
|
| +#if ENABLE(ASSERT)
|
| + // There can be up to two children, either or both of the text
|
| + // track container and media controls. If both are present, the
|
| + // text track container must be the first child.
|
| + unsigned numberOfChildren = shadowRoot.countChildren();
|
| + ASSERT(numberOfChildren <= 2);
|
| + Node* firstChild = shadowRoot.firstChild();
|
| + Node* lastChild = shadowRoot.lastChild();
|
| + if (numberOfChildren == 1) {
|
| + ASSERT(firstChild->isTextTrackContainer() || firstChild->isMediaControls());
|
| + } else if (numberOfChildren == 2) {
|
| + ASSERT(firstChild->isTextTrackContainer());
|
| + ASSERT(lastChild->isMediaControls());
|
| + }
|
| +#endif
|
| +}
|
| +
|
| TextTrackContainer& HTMLMediaElement::ensureTextTrackContainer()
|
| {
|
| - ensureMediaControls();
|
| - return *mediaControls()->textTrackContainer();
|
| + ShadowRoot& shadowRoot = ensureClosedShadowRoot();
|
| + assertShadowRootChildren(shadowRoot);
|
| +
|
| + Node* firstChild = shadowRoot.firstChild();
|
| + if (firstChild && firstChild->isTextTrackContainer())
|
| + return toTextTrackContainer(*firstChild);
|
| +
|
| + RefPtrWillBeRawPtr<TextTrackContainer> textTrackContainer = TextTrackContainer::create(document());
|
| +
|
| + // The text track container should be inserted before the media controls,
|
| + // so that they are rendered behind them.
|
| + shadowRoot.insertBefore(textTrackContainer, firstChild);
|
| +
|
| + assertShadowRootChildren(shadowRoot);
|
| +
|
| + return *textTrackContainer;
|
| }
|
|
|
| void HTMLMediaElement::updateTextTrackDisplay()
|
| @@ -3269,12 +3302,12 @@ void HTMLMediaElement::setShouldDelayLoadEvent(bool shouldDelay)
|
| document().decrementLoadEventDelayCount();
|
| }
|
|
|
| -
|
| MediaControls* HTMLMediaElement::mediaControls() const
|
| {
|
| if (ShadowRoot* shadowRoot = closedShadowRoot()) {
|
| - // Note that |shadowRoot->firstChild()| may be null.
|
| - return toMediaControls(shadowRoot->firstChild());
|
| + Node* lastChild = shadowRoot->lastChild();
|
| + if (lastChild && lastChild->isMediaControls())
|
| + return toMediaControls(lastChild);
|
| }
|
|
|
| return nullptr;
|
| @@ -3291,7 +3324,14 @@ void HTMLMediaElement::ensureMediaControls()
|
| if (isFullscreen())
|
| mediaControls->enteredFullscreen();
|
|
|
| - ensureClosedShadowRoot().appendChild(mediaControls);
|
| + ShadowRoot& shadowRoot = ensureClosedShadowRoot();
|
| + assertShadowRootChildren(shadowRoot);
|
| +
|
| + // The media controls should be inserted after the text track container,
|
| + // so that they are rendered in front of captions and subtitles.
|
| + shadowRoot.appendChild(mediaControls);
|
| +
|
| + assertShadowRootChildren(shadowRoot);
|
|
|
| if (!shouldShowControls() || !inDocument())
|
| mediaControls->hide();
|
| @@ -3347,8 +3387,8 @@ void HTMLMediaElement::configureTextTrackDisplay(VisibilityChangeAssumption assu
|
| if (!m_haveVisibleTextTrack && !mediaControls())
|
| return;
|
|
|
| - ensureMediaControls();
|
| - mediaControls()->changedClosedCaptionsVisibility();
|
| + if (mediaControls())
|
| + mediaControls()->changedClosedCaptionsVisibility();
|
|
|
| cueTimeline().updateActiveCues(currentTime());
|
|
|
|
|