Bug 882674 - Implement "pending text track change notification flag". r=rillian
MozReview-Commit-ID: G1L1ECWvNnD
--- a/dom/media/TextTrackList.cpp
+++ b/dom/media/TextTrackList.cpp
@@ -25,18 +25,19 @@ NS_INTERFACE_MAP_END_INHERITING(DOMEvent
TextTrackList::TextTrackList(nsPIDOMWindowInner* aOwnerWindow)
: DOMEventTargetHelper(aOwnerWindow)
{
}
TextTrackList::TextTrackList(nsPIDOMWindowInner* aOwnerWindow,
TextTrackManager* aTextTrackManager)
- : DOMEventTargetHelper(aOwnerWindow)
- , mTextTrackManager(aTextTrackManager)
+ : DOMEventTargetHelper(aOwnerWindow)
+ , mPendingTextTrackChange(false)
+ , mTextTrackManager(aTextTrackManager)
{
}
TextTrackList::~TextTrackList()
{
}
void
@@ -126,50 +127,68 @@ TextTrackList::RemoveTextTrack(TextTrack
void
TextTrackList::DidSeek()
{
for (uint32_t i = 0; i < mTextTracks.Length(); i++) {
mTextTracks[i]->SetDirty();
}
}
-class TrackEventRunner final: public Runnable
+class TrackEventRunner : public Runnable
{
public:
TrackEventRunner(TextTrackList* aList, nsIDOMEvent* aEvent)
: mList(aList)
, mEvent(aEvent)
{}
NS_IMETHOD Run() override
{
return mList->DispatchTrackEvent(mEvent);
}
+ RefPtr<TextTrackList> mList;
private:
- RefPtr<TextTrackList> mList;
RefPtr<nsIDOMEvent> mEvent;
};
+class ChangeEventRunner final : public TrackEventRunner
+{
+public:
+ ChangeEventRunner(TextTrackList* aList, nsIDOMEvent* aEvent)
+ : TrackEventRunner(aList, aEvent)
+ {}
+
+ NS_IMETHOD Run() override
+ {
+ mList->mPendingTextTrackChange = false;
+ return TrackEventRunner::Run();
+ }
+};
+
nsresult
TextTrackList::DispatchTrackEvent(nsIDOMEvent* aEvent)
{
return DispatchTrustedEvent(aEvent);
}
void
TextTrackList::CreateAndDispatchChangeEvent()
{
- RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
+ MOZ_ASSERT(NS_IsMainThread());
+ if (!mPendingTextTrackChange) {
+ mPendingTextTrackChange = true;
+ RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
- event->InitEvent(NS_LITERAL_STRING("change"), false, false);
- event->SetTrusted(true);
+ event->InitEvent(NS_LITERAL_STRING("change"), false, false);
+ event->SetTrusted(true);
- nsCOMPtr<nsIRunnable> eventRunner = new TrackEventRunner(this, event);
- NS_DispatchToMainThread(eventRunner);
+ nsCOMPtr<nsIRunnable> eventRunner = new ChangeEventRunner(this, event);
+ NS_DispatchToMainThread(eventRunner);
+ }
}
void
TextTrackList::CreateAndDispatchTrackEventRunner(TextTrack* aTrack,
const nsAString& aEventName)
{
nsCOMPtr<nsIThread> thread;
nsresult rv = NS_GetMainThread(getter_AddRefs(thread));
--- a/dom/media/TextTrackList.h
+++ b/dom/media/TextTrackList.h
@@ -62,16 +62,18 @@ public:
nsresult DispatchTrackEvent(nsIDOMEvent* aEvent);
void CreateAndDispatchChangeEvent();
void SetCuesInactive();
IMPL_EVENT_HANDLER(change)
IMPL_EVENT_HANDLER(addtrack)
IMPL_EVENT_HANDLER(removetrack)
+ bool mPendingTextTrackChange;
+
private:
~TextTrackList();
nsTArray< RefPtr<TextTrack> > mTextTracks;
RefPtr<TextTrackManager> mTextTrackManager;
void CreateAndDispatchTrackEventRunner(TextTrack* aTrack,
const nsAString& aEventName);
--- a/dom/media/test/test_texttracklist.html
+++ b/dom/media/test/test_texttracklist.html
@@ -23,22 +23,29 @@ isnot(video.textTracks, null, "Video sho
video.addTextTrack("subtitles", "", "");
track = video.textTracks[0];
video.textTracks.addEventListener("change", changed);
is(track.mode, "hidden", "New TextTrack's mode should be hidden.");
track.mode = "showing";
+// Bug882674: change the mode again to see if we receive only one
+// change event.
+track.mode = "hidden";
+var eventCount = 0;
function changed(event) {
+ eventCount++;
+ is(eventCount, 1, "change event dispatched multiple times.");
is(event.target, video.textTracks, "change event's target should be video.textTracks.");
ok(event instanceof window.Event, "change event should be a simple event.");
ok(!event.bubbles, "change event should not bubble.");
ok(event.isTrusted, "change event should be trusted.");
ok(!event.cancelable, "change event should not be cancelable.");
-SimpleTest.finish();
+ // Delay the finish function call for testing the change event count.
+ setTimeout(SimpleTest.finish, 0);
}
</script>
</pre>
</body>
</html>