From 330ae399bab6e793ff3de05980458291e73776c4 Mon Sep 17 00:00:00 2001 From: alwu Date: Tue, 21 May 2019 09:21:16 +0000 Subject: [PATCH] Bug 1550633 - part6 : clear track's cues list whenever track element's src attribute set, changed or removed. r=jya,baku According to the spec [1], we should empty track's cue list whenever a track element has its src attribute set, changed, or removed. [1] https://html.spec.whatwg.org/multipage/media.html#sourcing-out-of-band-text-tracks:attr-track-src Differential Revision: https://phabricator.services.mozilla.com/D31552 --HG-- extra : moz-landing-system : lando --- dom/html/HTMLTrackElement.cpp | 30 +++++++++++++++++++++++------- dom/html/HTMLTrackElement.h | 8 ++++++++ dom/media/TextTrack.cpp | 8 ++++++++ dom/media/TextTrack.h | 2 ++ 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/dom/html/HTMLTrackElement.cpp b/dom/html/HTMLTrackElement.cpp index 0abe44642585..50ba1f03e30f 100644 --- a/dom/html/HTMLTrackElement.cpp +++ b/dom/html/HTMLTrackElement.cpp @@ -214,17 +214,11 @@ bool HTMLTrackElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute, void HTMLTrackElement::SetSrc(const nsAString& aSrc, ErrorResult& aError) { SetHTMLAttr(nsGkAtoms::src, aSrc, aError); - uint16_t oldReadyState = ReadyState(); SetReadyState(TextTrackReadyState::NotLoaded); if (!mMediaParent) { return; } - if (mTrack && (oldReadyState != TextTrackReadyState::NotLoaded)) { - // Remove all the cues in MediaElement. - mMediaParent->RemoveTextTrack(mTrack); - // Recreate mTrack. - CreateTextTrack(); - } + // Stop WebVTTListener. mListener = nullptr; if (mChannel) { @@ -235,6 +229,16 @@ void HTMLTrackElement::SetSrc(const nsAString& aSrc, ErrorResult& aError) { MaybeDispatchLoadResource(); } +void HTMLTrackElement::MaybeClearAllCues() { + // Empty track's cue list whenever the track element's `src` attribute set, + // changed, or removed, + // https://html.spec.whatwg.org/multipage/media.html#sourcing-out-of-band-text-tracks:attr-track-src + if (!mTrack) { + return; + } + mTrack->ClearAllCues(); +} + // This function will run partial steps from `start-the-track-processing-model` // and finish the rest of steps in `LoadResource()` during the stable state. // https://html.spec.whatwg.org/multipage/media.html#start-the-track-processing-model @@ -463,5 +467,17 @@ void HTMLTrackElement::NotifyShutdown() { mListener = nullptr; } +nsresult HTMLTrackElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName, + const nsAttrValue* aValue, + const nsAttrValue* aOldValue, + nsIPrincipal* aMaybeScriptedPrincipal, + bool aNotify) { + if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::src) { + MaybeClearAllCues(); + } + return nsGenericHTMLElement::AfterSetAttr( + aNameSpaceID, aName, aValue, aOldValue, aMaybeScriptedPrincipal, aNotify); +} + } // namespace dom } // namespace mozilla diff --git a/dom/html/HTMLTrackElement.h b/dom/html/HTMLTrackElement.h index dcd570ac175e..eaa2d114d626 100644 --- a/dom/html/HTMLTrackElement.h +++ b/dom/html/HTMLTrackElement.h @@ -87,6 +87,12 @@ class HTMLTrackElement final : public nsGenericHTMLElement { nsIContent* aBindingParent) override; virtual void UnbindFromTree(bool aDeep, bool aNullParent) override; + virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName, + const nsAttrValue* aValue, + const nsAttrValue* aOldValue, + nsIPrincipal* aMaybeScriptedPrincipal, + bool aNotify) override; + void DispatchTrackRunnable(const nsString& aEventName); void DispatchTrustedEvent(const nsAString& aName); @@ -121,6 +127,8 @@ class HTMLTrackElement final : public nsGenericHTMLElement { void LoadResource(RefPtr&& aWebVTTListener); bool mLoadResourceDispatched; + void MaybeClearAllCues(); + RefPtr mWindowDestroyObserver; }; diff --git a/dom/media/TextTrack.cpp b/dom/media/TextTrack.cpp index 5831ff64b1d7..f082e299c969 100644 --- a/dom/media/TextTrack.cpp +++ b/dom/media/TextTrack.cpp @@ -197,6 +197,14 @@ void TextTrack::RemoveCue(TextTrackCue& aCue, ErrorResult& aRv) { } } +void TextTrack::ClearAllCues() { + WEBVTT_LOG("ClearAllCues"); + ErrorResult dummy; + while (!mCueList->IsEmpty()) { + RemoveCue(*(*mCueList)[0], dummy); + } +} + void TextTrack::SetCuesDirty() { for (uint32_t i = 0; i < mCueList->Length(); i++) { ((*mCueList)[i])->Reset(); diff --git a/dom/media/TextTrack.h b/dom/media/TextTrack.h index 4ecfefdd67c9..8207b08bc418 100644 --- a/dom/media/TextTrack.h +++ b/dom/media/TextTrack.h @@ -114,6 +114,8 @@ class TextTrack final : public DOMEventTargetHelper { RefPtr& aOtherCues, const media::TimeInterval& aInterval) const; + void ClearAllCues(); + private: ~TextTrack();