Bug 882717 - Invoke TimeMarchesOn when the startTime/endTime/pauseOnExit be changed of TextTrackCue. r=rillian draft
authorbechen <bechen@mozilla.com>
Wed, 08 Jun 2016 16:53:30 +0800
changeset 376555 dd5ce95c9859347bae24e17c9ff86043850dd557
parent 376554 67f9387bbcb56a3b953596d7b3f7d75d43cbce49
child 376562 225142a4af6085789c5da23631e9f28454d90180
push id20614
push userbechen@mozilla.com
push dateWed, 08 Jun 2016 09:00:53 +0000
reviewersrillian
bugs882717
milestone50.0a1
Bug 882717 - Invoke TimeMarchesOn when the startTime/endTime/pauseOnExit be changed of TextTrackCue. r=rillian MozReview-Commit-ID: 7Xol9x83lLx
dom/html/HTMLMediaElement.h
dom/html/TextTrackManager.cpp
dom/html/TextTrackManager.h
dom/media/TextTrack.cpp
dom/media/TextTrack.h
dom/media/TextTrackCue.h
dom/media/TextTrackCueList.cpp
dom/media/TextTrackCueList.h
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -700,16 +700,21 @@ public:
       mTextTrackManager->NotifyCueAdded(aCue);
     }
   }
   void NotifyCueRemoved(TextTrackCue& aCue) {
     if (mTextTrackManager) {
       mTextTrackManager->NotifyCueRemoved(aCue);
     }
   }
+  void NotifyCueUpdated(TextTrackCue *aCue) {
+    if (mTextTrackManager) {
+      mTextTrackManager->NotifyCueUpdated(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
@@ -707,10 +707,17 @@ TextTrackManager::TimeMarchesOn()
 
   mLastTimeMarchesOnCalled = currentPlaybackTime;
   mLastActiveCues = currentCues;
 
   // Step 18.
   UpdateCueDisplay();
 }
 
+void
+TextTrackManager::NotifyCueUpdated(TextTrackCue *aCue)
+{
+  // TODO: Add/Reorder the cue to mNewCues if we have some optimization?
+  DispatchTimeMarchesOn();
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/TextTrackManager.h
+++ b/dom/html/TextTrackManager.h
@@ -93,31 +93,33 @@ public:
   void DispatchTimeMarchesOn();
   void TimeMarchesOn();
 
   void NotifyShutdown()
   {
     mShutdown = true;
   }
 
+  void NotifyCueUpdated(TextTrackCue *aCue);
+
 private:
   /**
    * Converts the TextTrackCue's cuetext into a tree of DOM objects
    * and attaches it to a div on its owning TrackElement's
    * MediaElement's caption overlay.
    */
   void UpdateCueDisplay();
 
   // List of the TextTrackManager's owning HTMLMediaElement's TextTracks.
   RefPtr<TextTrackList> mTextTracks;
   // List of text track objects awaiting loading.
   RefPtr<TextTrackList> mPendingTextTracks;
   // List of newly introduced Text Track cues.
 
-  // Contain all cues for a MediaElement.
+  // Contain all cues for a MediaElement. Not sorted.
   RefPtr<TextTrackCueList> mNewCues;
   // The active cues for the last TimeMarchesOn iteration.
   RefPtr<TextTrackCueList> mLastActiveCues;
 
   // True if the media player playback changed due to seeking prior to and
   // during running the "Time Marches On" algorithm.
   bool mHasSeeked;
   // Playback position at the time of last "Time Marches On" call
--- a/dom/media/TextTrack.cpp
+++ b/dom/media/TextTrack.cpp
@@ -112,16 +112,19 @@ TextTrack::SetMode(TextTrackMode aValue)
             mediaElement->NotifyCueAdded(*(*mCueList)[i]);
           }
         }
       }
     }
     if (mTextTrackList) {
       mTextTrackList->CreateAndDispatchChangeEvent();
     }
+    // Ensure the TimeMarchesOn is called in case that the mCueList
+    // is empty.
+    NotifyCueUpdated(nullptr);
   }
 }
 
 void
 TextTrack::GetId(nsAString& aId) const
 {
   // If the track has a track element then its id should be the same as the
   // track element's id.
@@ -279,10 +282,23 @@ TextTrack::SetTrackElement(HTMLTrackElem
 }
 
 void
 TextTrack::SetCuesInactive()
 {
   mCueList->SetCuesInactive();
 }
 
+void
+TextTrack::NotifyCueUpdated(TextTrackCue *aCue)
+{
+  mCueList->NotifyCueUpdated(aCue);
+  if (mTextTrackList) {
+    HTMLMediaElement* mediaElement = mTextTrackList->GetMediaElement();
+    if (mediaElement) {
+      mediaElement->NotifyCueUpdated(aCue);
+    }
+  }
+  SetDirty();
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/media/TextTrack.h
+++ b/dom/media/TextTrack.h
@@ -115,16 +115,18 @@ public:
   void SetTrackElement(HTMLTrackElement* aTrackElement);
 
   TextTrackSource GetTextTrackSource() {
     return mTextTrackSource;
   }
 
   void SetCuesInactive();
 
+  void NotifyCueUpdated(TextTrackCue *aCue);
+
 private:
   ~TextTrack();
 
   RefPtr<TextTrackList> mTextTrackList;
 
   TextTrackKind mKind;
   nsString mLabel;
   nsString mLanguage;
--- a/dom/media/TextTrackCue.h
+++ b/dom/media/TextTrackCue.h
@@ -79,45 +79,48 @@ public:
   void SetStartTime(double aStartTime)
   {
     if (mStartTime == aStartTime) {
       return;
     }
 
     mStartTime = aStartTime;
     mReset = true;
+    NotifyCueUpdated(this);
   }
 
   double EndTime() const
   {
     return mEndTime;
   }
 
   void SetEndTime(double aEndTime)
   {
     if (mEndTime == aEndTime) {
       return;
     }
 
     mEndTime = aEndTime;
     mReset = true;
+    NotifyCueUpdated(this);
   }
 
   bool PauseOnExit()
   {
     return mPauseOnExit;
   }
 
   void SetPauseOnExit(bool aPauseOnExit)
   {
     if (mPauseOnExit == aPauseOnExit) {
       return;
     }
 
     mPauseOnExit = aPauseOnExit;
+    NotifyCueUpdated(nullptr);
   }
 
   TextTrackRegion* GetRegion();
   void SetRegion(TextTrackRegion* aRegion);
 
   DirectionSetting Vertical() const
   {
     return mVertical;
@@ -334,16 +337,22 @@ public:
   bool GetActive()
   {
     return mActive;
   }
 
 private:
   ~TextTrackCue();
 
+  void NotifyCueUpdated(TextTrackCue* aCue)
+  {
+    if (mTrack) {
+      mTrack->NotifyCueUpdated(aCue);
+    }
+  }
   void SetDefaultCueSettings();
   nsresult StashDocument();
 
   RefPtr<nsIDocument> mDocument;
   nsString mText;
   double mStartTime;
   double mEndTime;
 
--- a/dom/media/TextTrackCueList.cpp
+++ b/dom/media/TextTrackCueList.cpp
@@ -147,10 +147,19 @@ TextTrackCueList::GetCueListByTimeInterv
     if (cue->StartTime() <= aInterval.mEnd &&
         aInterval.mStart <= cue->EndTime()) {
       output->AddCue(*cue);
     }
   }
   return output.forget();
 }
 
+void
+TextTrackCueList::NotifyCueUpdated(TextTrackCue *aCue)
+{
+  if (aCue) {
+    mList.RemoveElement(aCue);
+    mList.InsertElementSorted(aCue, CompareCuesByTime());
+  }
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/media/TextTrackCueList.h
+++ b/dom/media/TextTrackCueList.h
@@ -55,16 +55,17 @@ public:
   void RemoveCueAt(uint32_t aIndex);
   void RemoveAll();
   void GetArray(nsTArray<RefPtr<TextTrackCue> >& aCues);
 
   void SetCuesInactive();
 
   already_AddRefed<TextTrackCueList>
   GetCueListByTimeInterval(media::Interval<double>& aInterval);
+  void NotifyCueUpdated(TextTrackCue *aCue);
 
 private:
   ~TextTrackCueList();
 
   nsCOMPtr<nsISupports> mParent;
 
   // A sorted list of TextTrackCues sorted by earliest start time. If the start
   // times are equal then it will be sorted by end time, earliest first.