Bug 882718 - triggerTimeMarchesOn. r=rillian draft
authorbechen <bechen@mozilla.com>
Wed, 01 Jun 2016 13:35:58 +0800
changeset 373768 426a405c60c614139e0d29e659f169b8b2859ee9
parent 373767 de92f37386b5adddc995f529e9a5db58379354a1
child 373769 bb8b93f6d5bfd1ddbb9961ff8f8a70881814295c
child 373771 47f9d6d574bab28e3acb5f3b887cacb3661b0fb7
push id19838
push userbechen@mozilla.com
push dateWed, 01 Jun 2016 07:10:27 +0000
reviewersrillian
bugs882718
milestone49.0a1
Bug 882718 - triggerTimeMarchesOn. r=rillian MozReview-Commit-ID: 2OOqr1Z6X9
dom/html/HTMLMediaElement.h
dom/html/TextTrackManager.cpp
dom/html/TextTrackManager.h
dom/media/TextTrack.cpp
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -702,16 +702,21 @@ public:
     }
   }
 
   void AddCue(TextTrackCue& aCue) {
     if (mTextTrackManager) {
       mTextTrackManager->AddCue(aCue);
     }
   }
+  void NotifyCueRemoved(TextTrackCue& aCue) {
+    if (mTextTrackManager) {
+      mTextTrackManager->NotifyCueRemoved(aCue);
+    }
+  }
 
   /**
    * A public wrapper for FinishDecoderSetup()
    */
   nsresult FinishDecoderSetup(MediaDecoder* aDecoder, MediaResource* aStream) {
     return FinishDecoderSetup(aDecoder, aStream, nullptr);
   }
 
--- a/dom/html/TextTrackManager.cpp
+++ b/dom/html/TextTrackManager.cpp
@@ -167,32 +167,42 @@ TextTrackManager::AddCues(TextTrack* aTe
   }
 
   TextTrackCueList* cueList = aTextTrack->GetCues();
   if (cueList) {
     bool dummy;
     for (uint32_t i = 0; i < cueList->Length(); ++i) {
       mNewCues->AddCue(*cueList->IndexedGetter(i, dummy));
     }
+    DispatchTimeMarchesOn();
   }
 }
 
 void
 TextTrackManager::RemoveTextTrack(TextTrack* aTextTrack, bool aPendingListOnly)
 {
   if (!mPendingTextTracks || !mTextTracks) {
     return;
   }
 
   mPendingTextTracks->RemoveTextTrack(aTextTrack);
   if (aPendingListOnly) {
     return;
   }
 
   mTextTracks->RemoveTextTrack(aTextTrack);
+  // Remove the cues in mNewCues belong to aTextTrack.
+  TextTrackCueList* removeCueList = aTextTrack->GetCues();
+  if (removeCueList) {
+    for (uint32_t i = 0; i < removeCueList->Length(); ++i) {
+      ErrorResult dummyRv;
+      mNewCues->RemoveCue(*((*removeCueList)[i]), dummyRv);
+    }
+    DispatchTimeMarchesOn();
+  }
 }
 
 void
 TextTrackManager::DidSeek()
 {
   if (mTextTracks) {
     mTextTracks->DidSeek();
   }
@@ -230,24 +240,39 @@ TextTrackManager::UpdateCueDisplay()
 
     nsPIDOMWindowInner* window = mMediaElement->OwnerDoc()->GetInnerWindow();
     if (window) {
       sParserWrapper->ProcessCues(window, jsCues, overlay);
     }
   } else if (overlay->Length() > 0) {
     nsContentUtils::SetNodeTextContent(overlay, EmptyString(), true);
   }
+  // Call TimeMarchesOn() directly instead DispatchTimeMarchesOn()
+  // because we had render the new cue, so we must run
+  // TimeMarchesOn immediately.
+  TimeMarchesOn();
 }
 
 void
 TextTrackManager::AddCue(TextTrackCue& aCue)
 {
   if (mNewCues) {
     mNewCues->AddCue(aCue);
   }
+  DispatchTimeMarchesOn();
+}
+
+void
+TextTrackManager::NotifyCueRemoved(TextTrackCue& aCue)
+{
+  if (mNewCues) {
+    ErrorResult dummyRv;
+    mNewCues->RemoveCue(aCue, dummyRv);
+  }
+  DispatchTimeMarchesOn();
 }
 
 void
 TextTrackManager::PopulatePendingList()
 {
   if (!mTextTracks || !mPendingTextTracks || !mMediaElement) {
     return;
   }
@@ -502,30 +527,35 @@ TextTrackManager::TimeMarchesOn()
 
   nsISupports* parentObject =
     mMediaElement->OwnerDoc()->GetParentObject();
   if (NS_WARN_IF(!parentObject)) {
     return;
   }
   nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(parentObject);
 
+  if (mMediaElement && !(mMediaElement->GetPlayedOrSeeked())) {
+    return;
+  }
+
   // Step 3.
   double currentPlaybackTime = mMediaElement->CurrentTime();
   bool hasNormalPlayback = !mHasSeeked;
   mHasSeeked = false;
 
   // Step 1, 2.
   RefPtr<TextTrackCueList> currentCues =
     new TextTrackCueList(window);
   RefPtr<TextTrackCueList> otherCues =
     new TextTrackCueList(window);
   bool dummy;
   for (uint32_t index = 0; index < mTextTracks->Length(); ++index) {
     TextTrack* ttrack = mTextTracks->IndexedGetter(index, dummy);
     if (ttrack && dummy) {
+      // TODO: call GetCueListByTimeInterval on mNewCues?
       TextTrackCueList* activeCueList = ttrack->GetActiveCues();
       if (activeCueList) {
         for (uint32_t i = 0; i < activeCueList->Length(); ++i) {
           currentCues->AddCue(*((*activeCueList)[i]));
         }
       }
     }
   }
--- a/dom/html/TextTrackManager.h
+++ b/dom/html/TextTrackManager.h
@@ -52,17 +52,17 @@ public:
                                            TextTrackReadyState aReadyState,
                                            TextTrackSource aTextTrackSource);
   void AddTextTrack(TextTrack* aTextTrack);
   void RemoveTextTrack(TextTrack* aTextTrack, bool aPendingListOnly);
   void DidSeek();
 
   void AddCue(TextTrackCue& aCue);
   void AddCues(TextTrack* aTextTrack);
-
+  void NotifyCueRemoved(TextTrackCue& aCue);
   /**
    * Overview of WebVTT cuetext and anonymous content setup.
    *
    * WebVTT nodes are the parsed version of WebVTT cuetext. WebVTT cuetext is
    * the portion of a WebVTT cue that specifies what the caption will actually
    * show up as on screen.
    *
    * WebVTT cuetext can contain markup that loosely relates to HTML markup. It
--- a/dom/media/TextTrack.cpp
+++ b/dom/media/TextTrack.cpp
@@ -128,16 +128,20 @@ TextTrack::AddCue(TextTrackCue& aCue)
 
 void
 TextTrack::RemoveCue(TextTrackCue& aCue, ErrorResult& aRv)
 {
   //TODO: Apply the rules for text track cue rendering Bug 865407
   aCue.SetActive(false);
 
   mCueList->RemoveCue(aCue, aRv);
+  HTMLMediaElement* mediaElement = mTextTrackList->GetMediaElement();
+  if (mediaElement) {
+    mediaElement->NotifyCueRemoved(aCue);
+  }
   SetDirty();
 }
 
 void
 TextTrack::SetCuesDirty()
 {
   for (uint32_t i = 0; i < mCueList->Length(); i++) {
     ((*mCueList)[i])->Reset();