Bug 1550633 - part6 : clear track's cues list whenever track element's src attribute set, changed or removed. r=jya,baku
☠☠ backed out by 100b92fd6219 ☠ ☠
authoralwu <alwu@mozilla.com>
Tue, 21 May 2019 09:21:16 +0000
changeset 475133 679ce0bdbf18780f08e6481f6aa3b8a9d1c082c1
parent 475132 f75c225dc273d5cb7469483e00e2bd4852bb0d7e
child 475134 d8fdfd9505bf75d033f22644f70a5de98314c018
push id113193
push userdvarga@mozilla.com
push dateThu, 23 May 2019 16:04:39 +0000
treeherdermozilla-inbound@386097a10f84 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya, baku
bugs1550633
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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
dom/html/HTMLTrackElement.cpp
dom/html/HTMLTrackElement.h
dom/media/TextTrack.cpp
dom/media/TextTrack.h
--- a/dom/html/HTMLTrackElement.cpp
+++ b/dom/html/HTMLTrackElement.cpp
@@ -209,37 +209,41 @@ bool HTMLTrackElement::ParseAttribute(in
 
   // Otherwise call the generic implementation.
   return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
                                               aMaybeScriptedPrincipal, aResult);
 }
 
 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) {
     mChannel->Cancel(NS_BINDING_ABORTED);
     mChannel = nullptr;
   }
 
   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
 void HTMLTrackElement::MaybeDispatchLoadResource() {
   MOZ_ASSERT(mTrack, "Should have already created text track!");
 
   // step2, if the text track's text track mode is not set to one of hidden or
   // showing, then return.
@@ -458,10 +462,22 @@ void HTMLTrackElement::DropChannel() { m
 void HTMLTrackElement::NotifyShutdown() {
   if (mChannel) {
     mChannel->Cancel(NS_BINDING_ABORTED);
   }
   mChannel = nullptr;
   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
--- a/dom/html/HTMLTrackElement.h
+++ b/dom/html/HTMLTrackElement.h
@@ -82,16 +82,22 @@ class HTMLTrackElement final : public ns
                               nsAttrValue& aResult) override;
 
   // Override BindToTree() so that we can trigger a load when we become
   // the child of a media element.
   virtual nsresult BindToTree(Document* aDocument, nsIContent* aParent,
                               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);
 
   void DropChannel();
 
   void NotifyShutdown();
 
   // Only load resource for the non-disabled track with media parent.
@@ -116,15 +122,17 @@ class HTMLTrackElement final : public ns
   void CreateTextTrack();
 
  private:
   // Open a new channel to the HTMLTrackElement's src attribute and call
   // mListener's LoadResource().
   void LoadResource(RefPtr<WebVTTListener>&& aWebVTTListener);
   bool mLoadResourceDispatched;
 
+  void MaybeClearAllCues();
+
   RefPtr<WindowDestroyObserver> mWindowDestroyObserver;
 };
 
 }  // namespace dom
 }  // namespace mozilla
 
 #endif  // mozilla_dom_HTMLTrackElement_h
--- a/dom/media/TextTrack.cpp
+++ b/dom/media/TextTrack.cpp
@@ -192,16 +192,24 @@ void TextTrack::RemoveCue(TextTrackCue& 
   aCue.SetActive(false);
   aCue.SetTrack(nullptr);
   HTMLMediaElement* mediaElement = GetMediaElement();
   if (mediaElement) {
     mediaElement->NotifyCueRemoved(aCue);
   }
 }
 
+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();
   }
 }
 
 TextTrackCueList* TextTrack::GetActiveCues() {
   if (mMode != TextTrackMode::Disabled) {
--- a/dom/media/TextTrack.h
+++ b/dom/media/TextTrack.h
@@ -109,16 +109,18 @@ class TextTrack final : public DOMEventT
   // than the current playback position, and other cues, which are not in the
   // current cues. Because there would be LOTS of cues in the other cues, and we
   // don't actually need all of them. Therefore, we use a time interval to get
   // the cues which are overlapping within the time interval.
   void GetCurrentCuesAndOtherCues(RefPtr<TextTrackCueList>& aCurrentCues,
                                   RefPtr<TextTrackCueList>& aOtherCues,
                                   const media::TimeInterval& aInterval) const;
 
+  void ClearAllCues();
+
  private:
   ~TextTrack();
 
   HTMLMediaElement* GetMediaElement() const;
 
   RefPtr<TextTrackList> mTextTrackList;
 
   TextTrackKind mKind;