Bug 1281418 - Release and reload the vtt resource when the src attribute of TrackElement changed. r=rillian
MozReview-Commit-ID: B8wdOxP3HId
--- a/dom/html/HTMLTrackElement.cpp
+++ b/dom/html/HTMLTrackElement.cpp
@@ -71,16 +71,17 @@ static constexpr nsAttrValue::EnumTable
// Invalid values are treated as "metadata" in ParseAttribute, but if no value
// at all is specified, it's treated as "subtitles" in GetKind
static constexpr const nsAttrValue::EnumTable* kKindTableInvalidValueDefault = &kKindTable[4];
/** HTMLTrackElement */
HTMLTrackElement::HTMLTrackElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
: nsGenericHTMLElement(aNodeInfo)
+ , mLoadResourceDispatched(false)
{
}
HTMLTrackElement::~HTMLTrackElement()
{
}
NS_IMPL_ELEMENT_CLONE(HTMLTrackElement)
@@ -178,18 +179,55 @@ HTMLTrackElement::ParseAttribute(int32_t
// Otherwise call the generic implementation.
return nsGenericHTMLElement::ParseAttribute(aNamespaceID,
aAttribute,
aValue,
aResult);
}
void
+HTMLTrackElement::SetSrc(const nsAString& aSrc, ErrorResult& aError)
+{
+ SetHTMLAttr(nsGkAtoms::src, aSrc, aError);
+ uint16_t oldReadyState = ReadyState();
+ SetReadyState(TextTrackReadyState::NotLoaded);
+ if (!mMediaParent) {
+ return;
+ }
+ if (mTrack && (oldReadyState != TextTrackReadyState::NotLoaded)) {
+ // Remove all the cues in MediaElement.
+ mMediaParent->RemoveTextTrack(mTrack);
+ // Recreate mTrack.
+ CreateTextTrack();
+ }
+ // Stop WebVTTListener.
+ mListener = nullptr;
+ if (mChannel) {
+ mChannel->Cancel(NS_BINDING_ABORTED);
+ mChannel = nullptr;
+ }
+
+ DispatchLoadResource();
+}
+
+void
+HTMLTrackElement::DispatchLoadResource()
+{
+ if (!mLoadResourceDispatched) {
+ RefPtr<Runnable> r = NewRunnableMethod(this, &HTMLTrackElement::LoadResource);
+ nsContentUtils::RunInStableState(r.forget());
+ mLoadResourceDispatched = true;
+ }
+}
+
+void
HTMLTrackElement::LoadResource()
{
+ mLoadResourceDispatched = false;
+
// Find our 'src' url
nsAutoString src;
if (!GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
return;
}
nsCOMPtr<nsIURI> uri;
nsresult rv = NewURIFromString(src, getter_AddRefs(uri));
@@ -253,18 +291,17 @@ HTMLTrackElement::BindToTree(nsIDocument
LOG(LogLevel::Debug, ("Track element sent notification to parent."));
// We may already have a TextTrack at this point if GetTrack() has already
// been called. This happens, for instance, if script tries to get the
// TextTrack before its mTrackElement has been bound to the DOM tree.
if (!mTrack) {
CreateTextTrack();
}
- RefPtr<Runnable> r = NewRunnableMethod(this, &HTMLTrackElement::LoadResource);
- nsContentUtils::RunInStableState(r.forget());
+ DispatchLoadResource();
}
return NS_OK;
}
void
HTMLTrackElement::UnbindFromTree(bool aDeep, bool aNullParent)
{
--- a/dom/html/HTMLTrackElement.h
+++ b/dom/html/HTMLTrackElement.h
@@ -41,20 +41,18 @@ public:
{
SetHTMLAttr(nsGkAtoms::kind, aKind, aError);
}
void GetSrc(DOMString& aSrc) const
{
GetHTMLURIAttr(nsGkAtoms::src, aSrc);
}
- void SetSrc(const nsAString& aSrc, ErrorResult& aError)
- {
- SetHTMLAttr(nsGkAtoms::src, aSrc, aError);
- }
+
+ void SetSrc(const nsAString& aSrc, ErrorResult& aError);
void GetSrclang(DOMString& aSrclang) const
{
GetHTMLAttr(nsGkAtoms::srclang, aSrclang);
}
void GetSrclang(nsAString& aSrclang) const
{
GetHTMLAttr(nsGkAtoms::srclang, aSrclang);
@@ -129,14 +127,18 @@ protected:
friend class WebVTTListener;
RefPtr<TextTrack> mTrack;
nsCOMPtr<nsIChannel> mChannel;
RefPtr<HTMLMediaElement> mMediaParent;
RefPtr<WebVTTListener> mListener;
void CreateTextTrack();
+
+private:
+ void DispatchLoadResource();
+ bool mLoadResourceDispatched;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_HTMLTrackElement_h