Bug 1531863 - part2 : handle text track mode changed in MediaElement. r=jya

In order to make the implementation more fitting with the spec, move the implementation of `pending-text-track-change-notification-flag` from text track list to media element.

In addition, it also help us not to expose the internal flag `show-poster` (which will be implemented in patch3) of media element when doing the related algorithm.

Differential Revision: https://phabricator.services.mozilla.com/D21810

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Alastor Wu 2019-03-12 00:32:21 +00:00
Родитель 955915bb2a
Коммит 5f410f2fce
5 изменённых файлов: 59 добавлений и 54 удалений

Просмотреть файл

@ -7375,6 +7375,22 @@ already_AddRefed<Promise> HTMLMediaElement::SetSinkId(const nsAString& aSinkId,
return promise.forget();
}
void HTMLMediaElement::NotifyTextTrackModeChanged() {
if (mPendingTextTrackChanged) {
return;
}
mPendingTextTrackChanged = true;
mAbstractMainThread->Dispatch(
NS_NewRunnableFunction("HTMLMediaElement::NotifyTextTrackModeChanged",
[this, self = RefPtr<HTMLMediaElement>(this)]() {
mPendingTextTrackChanged = false;
if (!mTextTrackManager) {
return;
}
GetTextTracks()->CreateAndDispatchChangeEvent();
}));
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -1674,6 +1674,16 @@ class HTMLMediaElement : public nsGenericHTMLElement,
// bfcache.
bool mHasEverBeenBlockedForAutoplay = false;
// True if we have dispatched a task for text track changed, will be unset
// when we starts processing text track changed.
// https://html.spec.whatwg.org/multipage/media.html#pending-text-track-change-notification-flag
bool mPendingTextTrackChanged = false;
public:
// This function will be called whenever a text track that is in a media
// element's list of text tracks has its text track mode change value
void NotifyTextTrackModeChanged();
public:
// Helper class to measure times for playback telemetry stats
class TimeDurationAccumulator {

Просмотреть файл

@ -73,33 +73,28 @@ JSObject* TextTrack::WrapObject(JSContext* aCx,
}
void TextTrack::SetMode(TextTrackMode aValue) {
if (mMode != aValue) {
mMode = aValue;
if (aValue == TextTrackMode::Disabled) {
// Remove all the cues in MediaElement.
HTMLMediaElement* mediaElement = GetMediaElement();
if (mediaElement) {
for (size_t i = 0; i < mCueList->Length(); ++i) {
mediaElement->NotifyCueRemoved(*(*mCueList)[i]);
}
}
SetCuesInactive();
} else {
// Add all the cues into MediaElement.
HTMLMediaElement* mediaElement = GetMediaElement();
if (mediaElement) {
for (size_t i = 0; i < mCueList->Length(); ++i) {
mediaElement->NotifyCueAdded(*(*mCueList)[i]);
}
}
}
if (mTextTrackList) {
mTextTrackList->CreateAndDispatchChangeEvent();
}
// Ensure the TimeMarchesOn is called in case that the mCueList
// is empty.
NotifyCueUpdated(nullptr);
if (mMode == aValue) {
return;
}
mMode = aValue;
HTMLMediaElement* mediaElement = GetMediaElement();
if (aValue == TextTrackMode::Disabled) {
for (size_t i = 0; i < mCueList->Length() && mediaElement; ++i) {
mediaElement->NotifyCueRemoved(*(*mCueList)[i]);
}
SetCuesInactive();
} else {
for (size_t i = 0; i < mCueList->Length() && mediaElement; ++i) {
mediaElement->NotifyCueAdded(*(*mCueList)[i]);
}
}
if (mediaElement) {
mediaElement->NotifyTextTrackModeChanged();
}
// Ensure the TimeMarchesOn is called in case that the mCueList
// is empty.
NotifyCueUpdated(nullptr);
}
void TextTrack::GetId(nsAString& aId) const {

Просмотреть файл

@ -118,39 +118,25 @@ class TrackEventRunner : public Runnable {
RefPtr<Event> mEvent;
};
class ChangeEventRunner final : public TrackEventRunner {
public:
ChangeEventRunner(TextTrackList* aList, Event* aEvent)
: TrackEventRunner(aList, aEvent) {}
NS_IMETHOD Run() override {
mList->mPendingTextTrackChange = false;
return TrackEventRunner::Run();
}
};
nsresult TextTrackList::DispatchTrackEvent(Event* aEvent) {
return DispatchTrustedEvent(aEvent);
}
void TextTrackList::CreateAndDispatchChangeEvent() {
MOZ_ASSERT(NS_IsMainThread());
if (!mPendingTextTrackChange) {
nsPIDOMWindowInner* win = GetOwner();
if (!win) {
return;
}
mPendingTextTrackChange = true;
RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
event->InitEvent(NS_LITERAL_STRING("change"), false, false);
event->SetTrusted(true);
nsCOMPtr<nsIRunnable> eventRunner = new ChangeEventRunner(this, event);
nsGlobalWindowInner::Cast(win)->Dispatch(TaskCategory::Other,
eventRunner.forget());
nsPIDOMWindowInner* win = GetOwner();
if (!win) {
return;
}
RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
event->InitEvent(NS_LITERAL_STRING("change"), false, false);
event->SetTrusted(true);
nsCOMPtr<nsIRunnable> eventRunner = new TrackEventRunner(this, event);
nsGlobalWindowInner::Cast(win)->Dispatch(TaskCategory::Other,
eventRunner.forget());
}
void TextTrackList::CreateAndDispatchTrackEventRunner(

Просмотреть файл

@ -65,8 +65,6 @@ class TextTrackList final : public DOMEventTargetHelper {
IMPL_EVENT_HANDLER(addtrack)
IMPL_EVENT_HANDLER(removetrack)
bool mPendingTextTrackChange = false;
private:
~TextTrackList();