зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1562021 - part3 : cancel old VTT listener when we start a new load. r=jya,baku
When we start a new load, all previous data fetching from the previous listener and all state changing applied to track element should be ignored. Therefore, we add a new method `Cancel()` which owner of the listener should call when we would like to discard current listener. Differential Revision: https://phabricator.services.mozilla.com/D36407 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
53e5ea1cdf
Коммит
fd5355860a
|
@ -299,9 +299,15 @@ void HTMLTrackElement::LoadResource(RefPtr<WebVTTListener>&& aWebVTTListener) {
|
|||
|
||||
if (mChannel) {
|
||||
mChannel->Cancel(NS_BINDING_ABORTED);
|
||||
mChannel->SetNotificationCallbacks(nullptr);
|
||||
mChannel = nullptr;
|
||||
}
|
||||
|
||||
if (mListener) {
|
||||
mListener->Cancel();
|
||||
mListener = nullptr;
|
||||
}
|
||||
|
||||
// According to
|
||||
// https://www.w3.org/TR/html5/embedded-content-0.html#sourcing-out-of-band-text-tracks
|
||||
//
|
||||
|
|
|
@ -63,6 +63,9 @@ WebVTTListener::GetInterface(const nsIID& aIID, void** aResult) {
|
|||
}
|
||||
|
||||
nsresult WebVTTListener::LoadResource() {
|
||||
if (IsCanceled()) {
|
||||
return NS_OK;
|
||||
}
|
||||
// Exit if we failed to create the WebVTTParserWrapper (vtt.jsm)
|
||||
NS_ENSURE_SUCCESS(mParserWrapperError, mParserWrapperError);
|
||||
|
||||
|
@ -74,6 +77,9 @@ NS_IMETHODIMP
|
|||
WebVTTListener::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
|
||||
nsIChannel* aNewChannel, uint32_t aFlags,
|
||||
nsIAsyncVerifyRedirectCallback* cb) {
|
||||
if (IsCanceled()) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (mElement) {
|
||||
mElement->OnChannelRedirect(aOldChannel, aNewChannel, aFlags);
|
||||
}
|
||||
|
@ -83,12 +89,20 @@ WebVTTListener::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
|
|||
|
||||
NS_IMETHODIMP
|
||||
WebVTTListener::OnStartRequest(nsIRequest* aRequest) {
|
||||
if (IsCanceled()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
LOG("OnStartRequest");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebVTTListener::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
|
||||
if (IsCanceled()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
LOG("OnStopRequest");
|
||||
if (NS_FAILED(aStatus)) {
|
||||
LOG("Got error status");
|
||||
|
@ -111,6 +125,7 @@ nsresult WebVTTListener::ParseChunk(nsIInputStream* aInStream, void* aClosure,
|
|||
uint32_t* aWriteCount) {
|
||||
nsCString buffer(aFromSegment, aCount);
|
||||
WebVTTListener* listener = static_cast<WebVTTListener*>(aClosure);
|
||||
MOZ_ASSERT(!listener->IsCanceled());
|
||||
|
||||
if (NS_FAILED(listener->mParserWrapper->Parse(buffer))) {
|
||||
LOG_WIHTOUT_ADDRESS(
|
||||
|
@ -127,6 +142,10 @@ nsresult WebVTTListener::ParseChunk(nsIInputStream* aInStream, void* aClosure,
|
|||
NS_IMETHODIMP
|
||||
WebVTTListener::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aStream,
|
||||
uint64_t aOffset, uint32_t aCount) {
|
||||
if (IsCanceled()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
LOG("OnDataAvailable");
|
||||
uint32_t count = aCount;
|
||||
while (count > 0) {
|
||||
|
@ -144,6 +163,7 @@ WebVTTListener::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aStream,
|
|||
|
||||
NS_IMETHODIMP
|
||||
WebVTTListener::OnCue(JS::Handle<JS::Value> aCue, JSContext* aCx) {
|
||||
MOZ_ASSERT(!IsCanceled());
|
||||
if (!aCue.isObject()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -161,12 +181,14 @@ WebVTTListener::OnCue(JS::Handle<JS::Value> aCue, JSContext* aCx) {
|
|||
|
||||
NS_IMETHODIMP
|
||||
WebVTTListener::OnRegion(JS::Handle<JS::Value> aRegion, JSContext* aCx) {
|
||||
MOZ_ASSERT(!IsCanceled());
|
||||
// Nothing for this callback to do.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebVTTListener::OnParsingError(int32_t errorCode, JSContext* cx) {
|
||||
MOZ_ASSERT(!IsCanceled());
|
||||
// We only care about files that have a bad WebVTT file signature right now
|
||||
// as that means the file failed to load.
|
||||
if (errorCode == ErrorCodes::BadSignature) {
|
||||
|
@ -176,5 +198,16 @@ WebVTTListener::OnParsingError(int32_t errorCode, JSContext* cx) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
bool WebVTTListener::IsCanceled() const { return mCancel; }
|
||||
|
||||
void WebVTTListener::Cancel() {
|
||||
MOZ_ASSERT(!IsCanceled(), "Do not cancel canceled listener again!");
|
||||
LOG("Cancel listen to channel's response.");
|
||||
mCancel = true;
|
||||
mParserWrapper->Cancel();
|
||||
mParserWrapper = nullptr;
|
||||
mElement = nullptr;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -42,6 +42,14 @@ class WebVTTListener final : public nsIWebVTTListener,
|
|||
*/
|
||||
nsresult LoadResource();
|
||||
|
||||
/**
|
||||
* When this listener is not going to be used anymore, its owner should take
|
||||
* a responsibility to call `Cancel()` to prevent this listener making any
|
||||
* changes for the track element.
|
||||
*/
|
||||
bool IsCanceled() const;
|
||||
void Cancel();
|
||||
|
||||
private:
|
||||
~WebVTTListener();
|
||||
|
||||
|
@ -54,6 +62,7 @@ class WebVTTListener final : public nsIWebVTTListener,
|
|||
RefPtr<HTMLTrackElement> mElement;
|
||||
nsCOMPtr<nsIWebVTTParserWrapper> mParserWrapper;
|
||||
nsresult mParserWrapperError;
|
||||
bool mCancel = false;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -43,6 +43,12 @@ WebVTTParserWrapper.prototype =
|
|||
};
|
||||
},
|
||||
|
||||
cancel: function() {
|
||||
this.parser.oncue = null;
|
||||
this.parser.onregion = null;
|
||||
this.parser.onparsingerror = null;
|
||||
},
|
||||
|
||||
convertCueToDOMTree: function(window, cue)
|
||||
{
|
||||
return WebVTT.convertCueToDOMTree(window, cue.text);
|
||||
|
|
|
@ -52,6 +52,11 @@ interface nsIWebVTTParserWrapper : nsISupports
|
|||
*/
|
||||
void watch(in nsIWebVTTListener callback);
|
||||
|
||||
/**
|
||||
* Cancel watching notifications which parser would send.
|
||||
*/
|
||||
void cancel();
|
||||
|
||||
/**
|
||||
* Convert the text content of a WebVTT cue to a document fragment so that
|
||||
* we can display it on the page.
|
||||
|
|
Загрузка…
Ссылка в новой задаче