Backed out 23 changesets (bug 1550633) for causing bug 1548454 to permafail on a CLOSED TREE
authorAndreea Pavel <apavel@mozilla.com>
Fri, 24 May 2019 03:38:26 +0300
changeset 475290 6acae89335b04d1d634fe5f6be2637f25e3e81e2
parent 475289 3b14313df83b02bcbc04a4b788d63f6e9a20becb
child 475291 c87317c4190283cc4352331417babef3d3f9546d
child 475292 be1723043e976056d8cbb139912c9f2a325e190e
push id36058
push useraciure@mozilla.com
push dateFri, 24 May 2019 03:53:25 +0000
treeherdermozilla-central@c87317c41902 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1550633, 1548454
milestone69.0a1
backs outce4a146da49d57afadd9205edd251c32d5d0bd9a
e1a33576d6ad38789b39e381c2ebaac2c2a81b93
bbd8f62b9bff25922b19925a83cf287be4b2dc1d
583d4e0945ad964ef5a9cc1a8ccec8faa248e32b
29487a59512dd951a532f1be441d29c6c618c1d8
0f6ddd898e891aa423510b0c66c702c09d77c728
fd1afdd721e3261a2f716ea117763ba52a231d05
d4a6c1337f891a761cd7ef03668d91743a50f065
2d4773f2dc6c83c0399e6add6a592e1782fffc3b
e9dea69efffeea4795c1640d225580008fdf060f
4265dd65cec3cc256ead96f0b9054c0756f13252
2aaaa42c409b7b56b3660326c4c7ffbdb2215635
d85485f76233138488e76d8434be46d954547ea3
b6e8370b6efb20689269602b5361406dfce1d574
afaef937598b8c46c009a0523c0fbe4ba61c6c25
470d8fae0461968d745100f64c23aa296f0d9a05
8024fcefe8b13d215211cbfe09f979998f3c5217
224eadc5ef27bdcd41375742314c8360464173b7
26c3c521ce27aa67922a0a0ed1f4b6d3272e902a
def294ad0efb614102f890e85b5b8f9c1e0cf2d7
b15cc6e689e79f87439d0163e7f7bb1964ad23bc
be178934cbbba786670417e9a1090713cc4ebc05
9893ccf1f8ad07ae7a1c8a69b089ef5b3f99d6ed
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 23 changesets (bug 1550633) for causing bug 1548454 to permafail on a CLOSED TREE Backed out changeset ce4a146da49d (bug 1550633) Backed out changeset e1a33576d6ad (bug 1550633) Backed out changeset bbd8f62b9bff (bug 1550633) Backed out changeset 583d4e0945ad (bug 1550633) Backed out changeset 29487a59512d (bug 1550633) Backed out changeset 0f6ddd898e89 (bug 1550633) Backed out changeset fd1afdd721e3 (bug 1550633) Backed out changeset d4a6c1337f89 (bug 1550633) Backed out changeset 2d4773f2dc6c (bug 1550633) Backed out changeset e9dea69efffe (bug 1550633) Backed out changeset 4265dd65cec3 (bug 1550633) Backed out changeset 2aaaa42c409b (bug 1550633) Backed out changeset d85485f76233 (bug 1550633) Backed out changeset b6e8370b6efb (bug 1550633) Backed out changeset afaef937598b (bug 1550633) Backed out changeset 470d8fae0461 (bug 1550633) Backed out changeset 8024fcefe8b1 (bug 1550633) Backed out changeset 224eadc5ef27 (bug 1550633) Backed out changeset 26c3c521ce27 (bug 1550633) Backed out changeset def294ad0efb (bug 1550633) Backed out changeset b15cc6e689e7 (bug 1550633) Backed out changeset be178934cbbb (bug 1550633) Backed out changeset 9893ccf1f8ad (bug 1550633)
browser/components/originattributes/test/browser/browser_cache.js
dom/html/HTMLTrackElement.cpp
dom/html/HTMLTrackElement.h
dom/html/TextTrackManager.cpp
dom/media/TextTrack.cpp
dom/media/TextTrack.h
dom/media/test/test_bug883173.html
dom/media/test/test_bug895091.html
dom/media/test/test_texttrack.html
dom/media/test/test_texttrack_moz.html
dom/media/test/test_texttrackcue.html
dom/media/test/test_texttrackregion.html
dom/media/test/test_trackelementevent.html
testing/profiles/web-platform/user.js
testing/web-platform/meta/html/semantics/embedded-content/media-elements/autoplay-with-broken-track.html.ini
testing/web-platform/meta/html/semantics/embedded-content/media-elements/track/track-element/src-clear-cues.html.ini
testing/web-platform/meta/html/semantics/embedded-content/media-elements/track/track-element/src-empty-string.html.ini
testing/web-platform/meta/html/semantics/embedded-content/media-elements/track/track-element/track-default-attribute.html.ini
testing/web-platform/meta/html/semantics/embedded-content/media-elements/track/track-element/track-element-src-change-error.html.ini
testing/web-platform/meta/html/semantics/embedded-content/media-elements/track/track-element/track-element-src-change.html.ini
testing/web-platform/meta/html/semantics/embedded-content/media-elements/track/track-element/track-mode-not-changed-by-new-track.html.ini
testing/web-platform/meta/html/semantics/embedded-content/media-elements/track/track-element/track-mode-triggers-loading.html.ini
testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/track-element-src-change-error.html
testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/track-element-src-change.html
testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/track-mode-not-changed-by-new-track.html
testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/track-selection-task-order.html
--- a/browser/components/originattributes/test/browser/browser_cache.js
+++ b/browser/components/originattributes/test/browser/browser_cache.js
@@ -179,17 +179,16 @@ async function doTest(aBrowser) {
       audioTrack.addEventListener("load", trackListener);
       audio.addEventListener("suspend", audioListener);
 
       // Assign attributes for the audio element.
       audioSource.setAttribute("src", audioURL + URLSuffix);
       audioSource.setAttribute("type", "audio/ogg");
       audioTrack.setAttribute("src", trackURL);
       audioTrack.setAttribute("kind", "subtitles");
-      audioTrack.setAttribute("default", true);
 
       audio.appendChild(audioSource);
       audio.appendChild(audioTrack);
       audio.autoplay = true;
 
       content.document.body.appendChild(audio);
     });
 
--- a/dom/html/HTMLTrackElement.cpp
+++ b/dom/html/HTMLTrackElement.cpp
@@ -37,19 +37,17 @@
 #include "nsISupportsPrimitives.h"
 #include "nsMappedAttributes.h"
 #include "nsNetUtil.h"
 #include "nsStyleConsts.h"
 #include "nsThreadUtils.h"
 #include "nsVideoFrame.h"
 
 static mozilla::LazyLogModule gTrackElementLog("nsTrackElement");
-#define LOG(msg, ...)                          \
-  MOZ_LOG(gTrackElementLog, LogLevel::Verbose, \
-          ("TextTrackElement=%p, " msg, this, ##__VA_ARGS__))
+#define LOG(type, msg) MOZ_LOG(gTrackElementLog, type, msg)
 
 // Replace the usual NS_IMPL_NS_NEW_HTML_ELEMENT(Track) so
 // we can return an UnknownElement instead when pref'd off.
 nsGenericHTMLElement* NS_NewHTMLTrackElement(
     already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
     mozilla::dom::FromParser aFromParser) {
   return new mozilla::dom::HTMLTrackElement(std::move(aNodeInfo));
 }
@@ -210,101 +208,63 @@ bool HTMLTrackElement::ParseAttribute(in
   }
 
   // Otherwise call the generic implementation.
   return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
                                               aMaybeScriptedPrincipal, aResult);
 }
 
 void HTMLTrackElement::SetSrc(const nsAString& aSrc, ErrorResult& aError) {
-  LOG("Set src=%s", NS_ConvertUTF16toUTF8(aSrc).get());
-
-  nsAutoString src;
-  if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, src) && src == aSrc) {
-    LOG("No need to reload for same src url");
-    return;
-  }
-
   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;
   }
 
-  MaybeDispatchLoadResource();
-}
-
-void HTMLTrackElement::MaybeClearAllCues() {
-  // Empty track's cue list whenever the track element's `src` attribute set,
-  // changed, or removed,
-  // https://html.spec.whatwg.org/multipage/media.html#sourcing-out-of-band-text-tracks:attr-track-src
-  if (!mTrack) {
-    return;
-  }
-  mTrack->ClearAllCues();
+  DispatchLoadResource();
 }
 
-// This function will run partial steps from `start-the-track-processing-model`
-// and finish the rest of steps in `LoadResource()` during the stable state.
-// https://html.spec.whatwg.org/multipage/media.html#start-the-track-processing-model
-void HTMLTrackElement::MaybeDispatchLoadResource() {
-  MOZ_ASSERT(mTrack, "Should have already created text track!");
-
-  // step2, if the text track's text track mode is not set to one of hidden or
-  // showing, then return.
-  if (mTrack->Mode() == TextTrackMode::Disabled) {
-    LOG("Do not load resource for disable track");
-    return;
-  }
-
-  // step3, if the text track's track element does not have a media element as a
-  // parent, return.
-  if (!mMediaParent) {
-    LOG("Do not load resource for track without media element");
-    return;
-  }
-
-  if (ReadyState() == TextTrackReadyState::Loaded) {
-    LOG("Has already loaded resource");
-    return;
-  }
-
-  // step5, await a stable state and run the rest of steps.
+void HTMLTrackElement::DispatchLoadResource() {
   if (!mLoadResourceDispatched) {
     RefPtr<WebVTTListener> listener = new WebVTTListener(this);
     RefPtr<Runnable> r = NewRunnableMethod<RefPtr<WebVTTListener>>(
         "dom::HTMLTrackElement::LoadResource", this,
         &HTMLTrackElement::LoadResource, std::move(listener));
     nsContentUtils::RunInStableState(r.forget());
     mLoadResourceDispatched = true;
   }
 }
 
 void HTMLTrackElement::LoadResource(RefPtr<WebVTTListener>&& aWebVTTListener) {
-  LOG("LoadResource");
   mLoadResourceDispatched = false;
 
+  // Find our 'src' url
   nsAutoString src;
-  if (!GetAttr(kNameSpaceID_None, nsGkAtoms::src, src) || src.IsEmpty()) {
-    LOG("Fail to load because no src");
-    SetReadyState(TextTrackReadyState::FailedToLoad);
+  if (!GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
     return;
   }
 
   nsCOMPtr<nsIURI> uri;
   nsresult rv = NewURIFromString(src, getter_AddRefs(uri));
   NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));
-  LOG("Trying to load from src=%s", NS_ConvertUTF16toUTF8(src).get());
+  LOG(LogLevel::Info, ("%p Trying to load from src=%s", this,
+                       NS_ConvertUTF16toUTF8(src).get()));
 
   if (mChannel) {
     mChannel->Cancel(NS_BINDING_ABORTED);
     mChannel = nullptr;
   }
 
   // According to
   // https://www.w3.org/TR/html5/embedded-content-0.html#sourcing-out-of-band-text-tracks
@@ -340,76 +300,73 @@ void HTMLTrackElement::LoadResource(RefP
   Document* doc = OwnerDoc();
   if (!doc) {
     return;
   }
 
   // 9. End the synchronous section, continuing the remaining steps in parallel.
   nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction(
       "dom::HTMLTrackElement::LoadResource",
-      [self = RefPtr<HTMLTrackElement>(this), this, uri, secFlags]() {
-        if (!mListener) {
+      [self = RefPtr<HTMLTrackElement>(this), uri, secFlags]() {
+        if (!self->mListener) {
           // Shutdown got called, abort.
           return;
         }
         nsCOMPtr<nsIChannel> channel;
-        nsCOMPtr<nsILoadGroup> loadGroup = OwnerDoc()->GetDocumentLoadGroup();
+        nsCOMPtr<nsILoadGroup> loadGroup =
+            self->OwnerDoc()->GetDocumentLoadGroup();
         nsresult rv = NS_NewChannel(getter_AddRefs(channel), uri,
-                                    static_cast<Element*>(this), secFlags,
+                                    static_cast<Element*>(self), secFlags,
                                     nsIContentPolicy::TYPE_INTERNAL_TRACK,
                                     nullptr,  // PerformanceStorage
                                     loadGroup);
 
+        NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));
+
+        channel->SetNotificationCallbacks(self->mListener);
+
+        LOG(LogLevel::Debug, ("opening webvtt channel"));
+        rv = channel->AsyncOpen(self->mListener);
+
         if (NS_FAILED(rv)) {
-          LOG("create channel failed.");
-          SetReadyState(TextTrackReadyState::FailedToLoad);
+          self->SetReadyState(TextTrackReadyState::FailedToLoad);
           return;
         }
-
-        channel->SetNotificationCallbacks(mListener);
-
-        LOG("opening webvtt channel");
-        rv = channel->AsyncOpen(mListener);
-
-        if (NS_FAILED(rv)) {
-          SetReadyState(TextTrackReadyState::FailedToLoad);
-          return;
-        }
-        mChannel = channel;
+        self->mChannel = channel;
       });
   doc->Dispatch(TaskCategory::Other, runnable.forget());
 }
 
 nsresult HTMLTrackElement::BindToTree(Document* aDocument, nsIContent* aParent,
                                       nsIContent* aBindingParent) {
   nsresult rv =
       nsGenericHTMLElement::BindToTree(aDocument, aParent, aBindingParent);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  LOG("Track Element bound to tree.");
+  LOG(LogLevel::Debug, ("Track Element bound to tree."));
   auto* parent = HTMLMediaElement::FromNodeOrNull(aParent);
   if (!parent) {
     return NS_OK;
   }
 
   // Store our parent so we can look up its frame for display.
   if (!mMediaParent) {
     mMediaParent = parent;
 
     // TODO: separate notification for 'alternate' tracks?
     mMediaParent->NotifyAddedSource();
-    LOG("Track element sent notification to parent.");
+    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();
     }
-    MaybeDispatchLoadResource();
+    DispatchLoadResource();
   }
 
   return NS_OK;
 }
 
 void HTMLTrackElement::UnbindFromTree(bool aDeep, bool aNullParent) {
   if (mMediaParent && aNullParent) {
     // mTrack can be null if HTMLTrackElement::LoadResource has never been
@@ -435,21 +392,19 @@ uint16_t HTMLTrackElement::ReadyState() 
 void HTMLTrackElement::SetReadyState(uint16_t aReadyState) {
   if (ReadyState() == aReadyState) {
     return;
   }
 
   if (mTrack) {
     switch (aReadyState) {
       case TextTrackReadyState::Loaded:
-        LOG("dispatch 'load' event");
         DispatchTrackRunnable(NS_LITERAL_STRING("load"));
         break;
       case TextTrackReadyState::FailedToLoad:
-        LOG("dispatch 'error' event");
         DispatchTrackRunnable(NS_LITERAL_STRING("error"));
         break;
     }
     mTrack->SetReadyState(aReadyState);
   }
 }
 
 void HTMLTrackElement::DispatchTrackRunnable(const nsString& aEventName) {
@@ -477,29 +432,10 @@ void HTMLTrackElement::DropChannel() { m
 void HTMLTrackElement::NotifyShutdown() {
   if (mChannel) {
     mChannel->Cancel(NS_BINDING_ABORTED);
   }
   mChannel = nullptr;
   mListener = nullptr;
 }
 
-nsresult HTMLTrackElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
-                                        const nsAttrValue* aValue,
-                                        const nsAttrValue* aOldValue,
-                                        nsIPrincipal* aMaybeScriptedPrincipal,
-                                        bool aNotify) {
-  if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::src) {
-    MaybeClearAllCues();
-    // In spec, `start the track processing model` step10, while fetching is
-    // ongoing, if the track URL changes, then we have to set the `FailedToLoad`
-    // state.
-    // https://html.spec.whatwg.org/multipage/media.html#sourcing-out-of-band-text-tracks:text-track-failed-to-load-3
-    if (ReadyState() == TextTrackReadyState::Loading && aValue != aOldValue) {
-      SetReadyState(TextTrackReadyState::FailedToLoad);
-    }
-  }
-  return nsGenericHTMLElement::AfterSetAttr(
-      aNameSpaceID, aName, aValue, aOldValue, aMaybeScriptedPrincipal, aNotify);
-}
-
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/html/HTMLTrackElement.h
+++ b/dom/html/HTMLTrackElement.h
@@ -82,32 +82,23 @@ class HTMLTrackElement final : public ns
                               nsAttrValue& aResult) override;
 
   // Override BindToTree() so that we can trigger a load when we become
   // the child of a media element.
   virtual nsresult BindToTree(Document* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent) override;
   virtual void UnbindFromTree(bool aDeep, bool aNullParent) override;
 
-  virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
-                                const nsAttrValue* aValue,
-                                const nsAttrValue* aOldValue,
-                                nsIPrincipal* aMaybeScriptedPrincipal,
-                                bool aNotify) override;
-
   void DispatchTrackRunnable(const nsString& aEventName);
   void DispatchTrustedEvent(const nsAString& aName);
 
   void DropChannel();
 
   void NotifyShutdown();
 
-  // Only load resource for the non-disabled track with media parent.
-  void MaybeDispatchLoadResource();
-
  protected:
   virtual ~HTMLTrackElement();
 
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aGivenProto) override;
   void OnChannelRedirect(nsIChannel* aChannel, nsIChannel* aNewChannel,
                          uint32_t aFlags);
 
@@ -117,22 +108,21 @@ class HTMLTrackElement final : public ns
   RefPtr<TextTrack> mTrack;
   nsCOMPtr<nsIChannel> mChannel;
   RefPtr<HTMLMediaElement> mMediaParent;
   RefPtr<WebVTTListener> mListener;
 
   void CreateTextTrack();
 
  private:
+  void DispatchLoadResource();
   // Open a new channel to the HTMLTrackElement's src attribute and call
   // mListener's LoadResource().
   void LoadResource(RefPtr<WebVTTListener>&& aWebVTTListener);
   bool mLoadResourceDispatched;
 
-  void MaybeClearAllCues();
-
   RefPtr<WindowDestroyObserver> mWindowDestroyObserver;
 };
 
 }  // namespace dom
 }  // namespace mozilla
 
 #endif  // mozilla_dom_HTMLTrackElement_h
--- a/dom/html/TextTrackManager.cpp
+++ b/dom/html/TextTrackManager.cpp
@@ -161,17 +161,17 @@ already_AddRefed<TextTrack> TextTrackMan
              NS_ConvertUTF16toUTF8(aLanguage).get());
   AddCues(track);
   ReportTelemetryForTrack(track);
 
   if (aTextTrackSource == TextTrackSource::Track) {
     RefPtr<nsIRunnable> task = NewRunnableMethod(
         "dom::TextTrackManager::HonorUserPreferencesForTrackSelection", this,
         &TextTrackManager::HonorUserPreferencesForTrackSelection);
-    NS_DispatchToMainThread(task.forget());
+    nsContentUtils::RunInStableState(task.forget());
   }
 
   return track.forget();
 }
 
 void TextTrackManager::AddTextTrack(TextTrack* aTextTrack) {
   if (!mMediaElement || !mTextTracks) {
     return;
@@ -180,17 +180,17 @@ void TextTrackManager::AddTextTrack(Text
   mTextTracks->AddTextTrack(aTextTrack, CompareTextTracks(mMediaElement));
   AddCues(aTextTrack);
   ReportTelemetryForTrack(aTextTrack);
 
   if (aTextTrack->GetTextTrackSource() == TextTrackSource::Track) {
     RefPtr<nsIRunnable> task = NewRunnableMethod(
         "dom::TextTrackManager::HonorUserPreferencesForTrackSelection", this,
         &TextTrackManager::HonorUserPreferencesForTrackSelection);
-    NS_DispatchToMainThread(task.forget());
+    nsContentUtils::RunInStableState(task.forget());
   }
 }
 
 void TextTrackManager::AddCues(TextTrack* aTextTrack) {
   if (!mNewCues) {
     WEBVTT_LOG("AddCues mNewCues is null");
     return;
   }
--- a/dom/media/TextTrack.cpp
+++ b/dom/media/TextTrack.cpp
@@ -49,34 +49,16 @@ static const char* ToReadyStateStr(const
     case TextTrackReadyState::FailedToLoad:
       return "FailedToLoad";
     default:
       MOZ_ASSERT_UNREACHABLE("Invalid state.");
   }
   return "Unknown";
 }
 
-static const char* ToTextTrackKindStr(const TextTrackKind aKind) {
-  switch (aKind) {
-    case TextTrackKind::Subtitles:
-      return "Subtitles";
-    case TextTrackKind::Captions:
-      return "Captions";
-    case TextTrackKind::Descriptions:
-      return "Descriptions";
-    case TextTrackKind::Chapters:
-      return "Chapters";
-    case TextTrackKind::Metadata:
-      return "Metadata";
-    default:
-      MOZ_ASSERT_UNREACHABLE("Invalid kind.");
-  }
-  return "Unknown";
-}
-
 NS_IMPL_CYCLE_COLLECTION_INHERITED(TextTrack, DOMEventTargetHelper, mCueList,
                                    mActiveCueList, mTextTrackList,
                                    mTrackElement)
 
 NS_IMPL_ADDREF_INHERITED(TextTrack, DOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(TextTrack, DOMEventTargetHelper)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TextTrack)
 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
@@ -125,40 +107,33 @@ JSObject* TextTrack::WrapObject(JSContex
                                 JS::Handle<JSObject*> aGivenProto) {
   return TextTrack_Binding::Wrap(aCx, this, aGivenProto);
 }
 
 void TextTrack::SetMode(TextTrackMode aValue) {
   if (mMode == aValue) {
     return;
   }
-  WEBVTT_LOG("Set mode=%s for track kind %s", ToStateStr(aValue),
-             ToTextTrackKindStr(mKind));
+  WEBVTT_LOG("Set mode=%s", ToStateStr(aValue));
   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();
   }
-  // https://html.spec.whatwg.org/multipage/media.html#sourcing-out-of-band-text-tracks:start-the-track-processing-model
-  // Run the `start-the-track-processing-model` to track's corresponding track
-  // element whenever track's mode changes.
-  if (mTrackElement) {
-    mTrackElement->MaybeDispatchLoadResource();
-  }
   // 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.
@@ -192,24 +167,16 @@ void TextTrack::RemoveCue(TextTrackCue& 
   aCue.SetActive(false);
   aCue.SetTrack(nullptr);
   HTMLMediaElement* mediaElement = GetMediaElement();
   if (mediaElement) {
     mediaElement->NotifyCueRemoved(aCue);
   }
 }
 
-void TextTrack::ClearAllCues() {
-  WEBVTT_LOG("ClearAllCues");
-  ErrorResult dummy;
-  while (!mCueList->IsEmpty()) {
-    RemoveCue(*(*mCueList)[0], dummy);
-  }
-}
-
 void TextTrack::SetCuesDirty() {
   for (uint32_t i = 0; i < mCueList->Length(); i++) {
     ((*mCueList)[i])->Reset();
   }
 }
 
 TextTrackCueList* TextTrack::GetActiveCues() {
   if (mMode != TextTrackMode::Disabled) {
--- a/dom/media/TextTrack.h
+++ b/dom/media/TextTrack.h
@@ -109,18 +109,16 @@ class TextTrack final : public DOMEventT
   // than the current playback position, and other cues, which are not in the
   // current cues. Because there would be LOTS of cues in the other cues, and we
   // don't actually need all of them. Therefore, we use a time interval to get
   // the cues which are overlapping within the time interval.
   void GetCurrentCuesAndOtherCues(RefPtr<TextTrackCueList>& aCurrentCues,
                                   RefPtr<TextTrackCueList>& aOtherCues,
                                   const media::TimeInterval& aInterval) const;
 
-  void ClearAllCues();
-
  private:
   ~TextTrack();
 
   HTMLMediaElement* GetMediaElement() const;
 
   RefPtr<TextTrackList> mTextTrackList;
 
   TextTrackKind mKind;
--- a/dom/media/test/test_bug883173.html
+++ b/dom/media/test/test_bug883173.html
@@ -1,39 +1,59 @@
 <!DOCTYPE HTML>
 <html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=883173
+-->
 <head>
+  <meta charset='utf-8'>
   <title>Test for Bug 883173 - TextTrackCue(List) Sorting</title>
+  <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
   <script src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
-<video id="v" src="seek.webm" preload="metadata">
-  <track src="bug883173.vtt" kind="subtitles" id="default" default>
-</video>
-<script type="text/javascript">
-/**
- * This test is used to ensure that the cues in the cue list should be sorted by
- * cues' start time and end time, not the present order in the file.
- */
-function runTest() {
-  let trackElement = document.getElementById("default");
-  is(trackElement.readyState, 2, "Track::ReadyState should be set to LOADED.");
+<p id="display"></p>
+<div id="content">
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+SimpleTest.waitForExplicitFinish();
 
-  let expected = [[1, 3], [1, 2], [2, 4], [2, 3], [3, 4]];
-  let cueList = trackElement.track.cues;
-  is(cueList.length, expected.length, "Cue list length should be 5.");
+var video = document.createElement("video");
+video.src = "seek.webm";
+video.preload = "metadata";
+
+var trackElement = document.createElement("track");
+trackElement.src = "bug883173.vtt";
+trackElement.kind = "subtitles";
 
-  for (let i = 0; i < expected.length; i++) {
-    is(cueList[i].startTime, expected[i][0],
-       `Cue's start time should be ${expected[i][0]}`);
-    is(cueList[i].endTime, expected[i][1],
-       `Cue's end time should be ${expected[i][1]}`);
-  }
+document.getElementById("content").appendChild(video);
+video.appendChild(trackElement);
+video.addEventListener("loadedmetadata",
+  function run_tests() {
+    // Re-queue run_tests() at the end of the event loop until the track
+    // element has loaded its data.
+    if (trackElement.readyState == 1) {
+      setTimeout(run_tests, 0);
+      return;
+    }
+    is(trackElement.readyState, 2, "Track::ReadyState should be set to LOADED.");
+
+    // Set mode to hidden so that the active cue lists are being updated.
+    trackElement.track.mode = "hidden";
 
-  SimpleTest.finish();
-}
+    var expected = [[1, 3], [1, 2], [2, 4], [2, 3], [3, 4]];
+    var cueList = trackElement.track.cues;
+    is(cueList.length, expected.length, "Cue list length should be 5.");
 
-SimpleTest.waitForExplicitFinish();
-onload = runTest;
+    for (var i = 0; i < expected.length; i++) {
+      is(cueList[i].startTime, expected[i][0], "Cue's start time should be " + expected[i][0]);
+      is(cueList[i].endTime, expected[i][1], "Cue's end time should be " + expected[i][1]);
+    }
+
+    SimpleTest.finish();
+  }
+);
 </script>
+</pre>
 </body>
-</html>
+</html>
\ No newline at end of file
--- a/dom/media/test/test_bug895091.html
+++ b/dom/media/test/test_bug895091.html
@@ -1,60 +1,60 @@
 <!DOCTYPE HTML>
 <html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=895091
+-->
 <head>
+  <meta charset='utf-8'>
   <title>Test for Bug 895091 - Integrating vtt.js</title>
+  <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
   <script src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="manifest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
-<video id="v" src="seek.webm" preload="metadata">
-  <track src="long.vtt" kind="subtitles" id="track1">
-  <track src="long.vtt" kind="subtitles" id="track2">
-</video>
-<script type="text/javascript">
-/**
- * This test is used to ensure that we can load two track elements with large
- * amount of cues at same time. In this test, both tracks are disable by default,
- * we have to enable them in order to start loading.
- */
-var trackElement = document.getElementById("track1");
-var trackElementTwo = document.getElementById("track2");
+<p id="display"></p>
+<div id="content">
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+
+var video = document.createElement("video");
+video.src = "seek.webm";
+video.preload = "metadata";
+
+var trackElement = document.createElement("track");
+trackElement.src = "long.vtt";
+trackElement.kind = "subtitles";
 
-async function runTest() {
-  enableBothTracks();
-  await waitUntilBothTracksLoaded();
-  checkTrackReadyStateShouldBeLoaded();
-  checkCuesAmount();
-  SimpleTest.finish();
-}
+var trackElementTwo = document.createElement("track");
+trackElementTwo.src = "long.vtt";
+trackElementTwo.kind = "subtitles";
+
+document.getElementById("content").appendChild(video);
+video.appendChild(trackElement);
+video.appendChild(trackElementTwo);
 
-SimpleTest.waitForExplicitFinish();
-onload = runTest;
+video.addEventListener("loadedmetadata", function run_tests() {
+  // Re-que run_tests() at the end of the event loop until the track
+  // element has loaded its data.
+  if (trackElement.readyState == 1 || trackElementTwo.readyState == 1) {
+    setTimeout(run_tests, 0);
+    return;
+  }
 
-/**
- * The following are test helper functions.
- */
-function enableBothTracks() {
-  // All tracks are `disable` on default. As we won't start loading for disabled
-  // tracks, we have to change their mode in order to start loading.
+  // Set mode to hidden so that the active cue lists are being updated.
   trackElement.track.mode = "hidden";
   trackElementTwo.track.mode = "hidden";
-}
 
-async function waitUntilBothTracksLoaded() {
-  info(`wait until both tracks finish loading`);
-  await Promise.all([once(trackElement, "load"), once(trackElementTwo, "load")]);
-}
-
-function checkTrackReadyStateShouldBeLoaded() {
   is(trackElement.readyState, 2, "Track::ReadyState should be set to LOADED.");
   is(trackElementTwo.readyState, 2, "Track::ReadyState should be set to LOADED.");
-}
 
-function checkCuesAmount() {
   is(trackElement.track.cues.length, 2000, "Cue list length should be 2000.");
   is(trackElementTwo.track.cues.length, 2000, "Cue list length should be 2000.");
-}
+
+  SimpleTest.finish();
+});
 </script>
+</pre>
 </body>
 </html>
--- a/dom/media/test/test_texttrack.html
+++ b/dom/media/test/test_texttrack.html
@@ -1,158 +1,126 @@
 <!DOCTYPE HTML>
 <html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=833386
+-->
 <head>
+  <meta charset='utf-8'>
   <title>Test for Bug 833386 - TextTrackList</title>
+  <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
   <script src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="manifest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
-<video id="v">
-<script type="text/javascript">
-/**
- * This test is used to check different things.
- * (1) the default value of track element's attributes
- * (2) readonly attributes can't be modifted
- * (3) the order of tracks in the media element's track list
- */
-var enabledTrackElement = null;
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+SpecialPowers.pushPrefEnv({"set": [["media.webvtt.regions.enabled", true]]},
+  function() {
+    var video = document.createElement("video");
 
-async function runTest() {
-  addFourTextTrackElementsToVideo();
-  startLoadingVideo();
-  await waitUntilEnableTrackLoaded();
-  checkTracksStatus();
-  SimpleTest.finish();
-}
-
-SimpleTest.waitForExplicitFinish();
-onload = runTest;
+    isnot(video.textTracks, undefined, "HTMLMediaElement::TextTrack() property should be available.")
 
-/**
- * The following are test helper functions.
- */
-function addFourTextTrackElementsToVideo() {
-  let video = document.getElementById("v");
-  isnot(video.textTracks, undefined,
-        "HTMLMediaElement::TextTrack() property should be available.")
+    var trackList = video.textTracks;
+    is(trackList.length, 0, "Length should be 0.");
 
-  let trackList = video.textTracks;
-  is(trackList.length, 0, "Length should be 0.");
-
-  ok(typeof video.addTextTrack == "function",
-     "HTMLMediaElement::AddTextTrack() function should be available.")
+    ok(typeof video.addTextTrack == "function", "HTMLMediaElement::AddTextTrack() function should be available.")
+    video.addTextTrack("subtitles", "third", "en-CA");
+    is(trackList.length, 1, "Length should be 1.");
 
-  // Insert some tracks in an order that is not sorted, we will test if they
-  // are sorted later.
-  info(`- Add a track element with label 'third' -`);
-  video.addTextTrack("subtitles", "third", "en-CA");
-  is(trackList.length, 1, "Length should be 1.");
+    var textTrack = video.textTracks[0];
+    is(textTrack.label, "third", "Label should be set to third.");
+    is(textTrack.language, "en-CA", "Language should be en-CA.");
+    is(textTrack.kind, "subtitles", "Default kind should be subtitles.");
+    is(textTrack.mode, "hidden", "Default mode should be hidden.");
 
-  let textTrack = video.textTracks[0];
-  checkAttributesDefaultValue(textTrack);
-  checkTextTrackMode(textTrack);
-  checkReadOnlyAttributes(textTrack);
+    // Mode should not allow a bogus value.
+    textTrack.mode = 'bogus';
+    is(textTrack.mode, 'hidden', "Mode should be not allow a bogus value.");
+
+    // Should allow all these values for mode.
+    checkMode("showing", "Mode should allow \"showing\"");
+    checkMode("disabled", "Mode should allow \"disabled\"");
+    checkMode("hidden", "Mode should allow \"hidden\"");
 
-  info(`- Add a track element with label 'first' -`);
-  let trackOne = document.createElement("track");
-  video.appendChild(trackOne);
-  trackOne.label = "first";
-  trackOne.src = "basic.vtt";
-  trackOne.default = true;
-  trackOne.id = "2";
-  // The automatic track selection would choose the first track element with
-  // `default` attribute, so this track would be enable later.
-  enabledTrackElement = trackOne;
+    // All below are read-only properties and so should not allow setting.
+    textTrack.label = "French subtitles";
+    is(textTrack.label, "third", "Label is read-only so should still be \"label\".");
+
+    textTrack.language = "en";
+    is(textTrack.language, "en-CA", "Language is read-only so should still be \"en-CA\".");
 
-  info(`- Add a track element with label 'fourth' -`);
-  video.addTextTrack("subtitles", "fourth", "en-CA");
+    textTrack.kind = "captions";
+    is(textTrack.kind, "subtitles", "Kind is read-only so should still be \"subtitles\"");
 
-  info(`- Add a track element with label 'second' -`);
-  let trackTwo = document.createElement("track");
-  video.appendChild(trackTwo);
-  trackTwo.label = "second";
-  trackTwo.src = "basic.vtt";
-  // Although this track has `default` attribute as well, it won't be enable by
-  // the automatic track selection because it's not the first default track in
-  // the media element's track list.
-  trackTwo.default = true;
-}
+    function checkMode(value, message) {
+      textTrack.mode = value;
+      is(textTrack.mode, value, message);
+    }
 
-function checkAttributesDefaultValue(track) {
-  is(track.label, "third", "Label should be set to third.");
-  is(track.language, "en-CA", "Language should be en-CA.");
-  is(track.kind, "subtitles", "Default kind should be subtitles.");
-  is(track.mode, "hidden", "Default mode should be hidden.");
-}
+    // Insert some tracks in an order that is not sorted, we will test if they
+    // are sorted later.
+    var trackOne = document.createElement("track");
+    trackOne.label = "first";
+    trackOne.src = "basic.vtt";
+    trackOne.default = true;
+    trackOne.id = "2";
+    video.appendChild(trackOne);
 
-function checkTextTrackMode(track) {
-  // Mode should not allow a bogus value.
-  track.mode = 'bogus';
-  is(track.mode, 'hidden', "Mode should be not allow a bogus value.");
+    video.addTextTrack("subtitles", "fourth", "en-CA");
 
-  // Should allow all these values for mode.
-  changeTextTrackMode("showing");
-  changeTextTrackMode("disabled");
-  changeTextTrackMode("hidden");
+    var trackTwo = document.createElement("track");
+    trackTwo.label = "second";
+    trackTwo.src = "basic.vtt";
+    trackTwo.default = true;
+    video.appendChild(trackTwo);
 
-  function changeTextTrackMode(mode) {
-    track.mode = mode;
-    is(track.mode, mode, `Mode should allow \"${mode}\"`);
-  }
-}
+    video.src = "seek.webm";
+    video.preload = "metadata";
 
-function checkReadOnlyAttributes(track) {
-  // All below are read-only properties and so should not allow setting.
-  track.label = "French subtitles";
-  is(track.label, "third", "Label is read-only so should still be \"label\".");
-  track.language = "en";
-  is(track.language, "en-CA", "Language is read-only so should still be \"en-CA\".");
-  track.kind = "captions";
-  is(track.kind, "subtitles", "Kind is read-only so should still be \"subtitles\"");
-}
+    document.getElementById("content").appendChild(video);
 
-function startLoadingVideo() {
-  let video = document.getElementById("v");
-  video.src = "seek.webm";
-  video.preload = "metadata";
-}
-
-async function waitUntilEnableTrackLoaded() {
-  info(`wait until the enabled track finishes loading`);
-  await once(enabledTrackElement, "load");
-  is(enabledTrackElement.readyState, 2, "Track::ReadyState should be set to LOADED.");
-}
+    video.addEventListener("loadedmetadata", function run_tests() {
+      // Re-que run_tests() at the end of the event loop until the track
+      // element has loaded its data.
+      if (trackOne.readyState == 1 || trackTwo.readyState == 1) {
+        setTimeout(run_tests, 0);
+        return;
+      }
+      is(trackOne.readyState, 2, "First Track::ReadyState should be set to LOADED.");
+      is(trackTwo.readyState, 2, "Second Track::ReadyState should be set to LOADED.");
 
-function checkTracksStatus() {
-  // We're testing two things here,
-  // (1) the tracks created from a track element have a default mode 'disabled'
-  // and tracks created from 'addTextTrack' method have a default
-  // mode of 'hidden'.
-  // (2) we're testing that the tracks are sorted properly. For the tracks to
-  // be sorted the first two tracks, added through a TrackElement, must occupy
-  // the first two indexes in their TrackElement tree order. The second two
-  // tracks, added through the 'addTextTrack' method, will occupy the last two
-  // indexes in the order that they were added in.
-  let trackData = [
-    { label: "first", mode: "showing", id: "2" },
-    { label: "second", mode: "disabled", id: "" },
-    { label: "third", mode: "hidden", id: "" },
-    { label: "fourth", mode: "hidden", id: "" }
-  ];
-  let video = document.getElementById("v");
-  is(video.textTracks.length, trackData.length,
-     `TextTracks length should be ${trackData.length}`);
-  for (let i = 0; i < trackData.length; i++) {
-    let track = video.textTracks[i];
-    isnot(track, null, `Video should have a text track at index ${i}`);
-    let info = trackData[i];
-    for (let key in info) {
-      is(track[key], info[key],
-         `Track at index ${i} should have a '${key}' property with a value of '${info[key]}'.`);
-    }
-  }
-}
-
+      // We're testing two things here, firstly that tracks created from a track
+      // element have a default mode 'disabled' and tracks created with the
+      // 'addTextTrack' method have a default mode of 'hidden'.
+      // Secondly we're testing that the tracks are sorted properly.
+      // For the tracks to be sorted the first two tracks, added through a
+      // TrackElement, must occupy the first two indexes in their TrackElement
+      // tree order. The second two tracks, added through the 'addTextTrack'
+      // method, will occupy the last two indexes in the order that they were
+      // added in.
+      var trackData = [
+        { label: "first", mode: "showing", id: "2" },
+        { label: "second", mode: "disabled", id: "" },
+        { label: "third", mode: "hidden", id: "" },
+        { label: "fourth", mode: "hidden", id: "" }
+      ];
+      is(video.textTracks.length, trackData.length, "TextTracks length should be " + trackData.length);
+      for (var i = 0; i < trackData.length; i++) {
+        var track = video.textTracks[i];
+        isnot(track, null, "Video should have a text track at index " + i);
+        var info = trackData[i];
+        for (var key in info) {
+          is(track[key], info[key], "Track at index " + i + " should have a '" + key + "'' property " +
+                                    "with a value of '" + info[key] + "'.");
+        }
+      }
+      SimpleTest.finish();
+    });
+});
 </script>
+</pre>
 </body>
 </html>
--- a/dom/media/test/test_texttrack_moz.html
+++ b/dom/media/test/test_texttrack_moz.html
@@ -1,60 +1,66 @@
 <!DOCTYPE HTML>
 <html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=881976
+-->
 <head>
-  <title>Test for Bug 881976 - TextTrackList</title>
+  <meta charset='utf-8'>
+  <title>Test for Bug 881976 - TextTrackCue Computed Position</title>
+  <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
   <script src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="manifest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
-<video id="v" src="seek.webm" preload="metadata">
-<script type="text/javascript">
-/**
- * This test is used to ensure the text track list we got from video is as same
- * as the one in the text track.
- */
-var video = document.getElementById("v");
+<p id="display"></p>
+<div id="content">
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+  SimpleTest.waitForExplicitFinish();
+  SpecialPowers.pushPrefEnv({"set": [["media.webvtt.regions.enabled", true]]},
+    function() {
+      var video = document.createElement("video");
+
+      // Check if adding a text track manually sets the TextTrackList correctly.
 
-async function runTest() {
-  addTrackViaAddTrackAPI();
-  await addTrackViaTrackElement();
-  SimpleTest.finish();
-}
+      // HTMLTrackElement.textTrackList is an extension available only to
+      // privileged code, so we need to access it through the SpecialPowers
+      // object.
+      video.addTextTrack("subtitles", "", "");
+      is(SpecialPowers.unwrap(SpecialPowers.wrap(video.textTracks[0]).textTrackList),
+          video.textTracks,
+          "The Track's TextTrackList should be the Video's TextTrackList.");
 
-SimpleTest.waitForExplicitFinish();
-onload = runTest;
+
+      // Check if loading a Track via a TrackElement sets the TextTrackList correctly.
+      video.src = "seek.webm";
+      video.preload = "auto";
 
-/**
- * The following are test helper functions.
- */
-function addTrackViaAddTrackAPI() {
-  // Check if adding a text track manually sets the TextTrackList correctly.
-  video.addTextTrack("subtitles", "", "");
-  // TextTrack.textTrackList is an extension available only to privileged code,
-  // so we need to access it through the SpecialPowers object.
-  is(SpecialPowers.unwrap(SpecialPowers.wrap(video.textTracks[0]).textTrackList),
-     video.textTracks,
-     "The Track's TextTrackList should be the Video's TextTrackList.");
-}
+      var trackElement = document.createElement("track");
+      trackElement.src = "basic.vtt";
+      trackElement.kind = "subtitles";
+
+      video.appendChild(trackElement);
+      document.getElementById("content").appendChild(video);
 
-async function addTrackViaTrackElement() {
-  // Check if loading a Track via a TrackElement sets the TextTrackList correctly.
-  let trackElement = document.createElement("track");
-  trackElement.src = "basic.vtt";
-  trackElement.kind = "subtitles";
-  trackElement.default = true;
-  video.appendChild(trackElement);
+      video.addEventListener("loadedmetadata", function run_tests() {
+        // Re-que run_tests() at the end of the event loop until the track
+        // element has loaded its data.
+        if (trackElement.readyState == HTMLTrackElement.LOADING) {
+          setTimeout(run_tests, 0);
+          return;
+        }
+        is(trackElement.readyState, HTMLTrackElement.LOADED,
+            "Track::ReadyState should be set to LOADED.");
+        is(SpecialPowers.unwrap(SpecialPowers.wrap(trackElement.track).textTrackList),
+           video.textTracks,
+           "TrackElement's Track's TextTrackList should be the Video's TextTrackList.");
 
-  info(`wait until the track finishes loading`);
-  await once(trackElement, "load");
-
-  is(trackElement.readyState, HTMLTrackElement.LOADED,
-     "Track::ReadyState should be set to LOADED.");
-  is(SpecialPowers.unwrap(SpecialPowers.wrap(trackElement.track).textTrackList),
-     video.textTracks,
-     "TrackElement's Track's TextTrackList should be the Video's TextTrackList.");
-}
-
+        SimpleTest.finish();
+      });
+    }
+  );
 </script>
+</pre>
 </body>
 </html>
--- a/dom/media/test/test_texttrackcue.html
+++ b/dom/media/test/test_texttrackcue.html
@@ -1,299 +1,268 @@
 <!DOCTYPE HTML>
 <html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=833386
+-->
 <head>
+  <meta charset='utf-8'>
   <title>Test for Bug 833386 - HTMLTrackElement</title>
+  <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
   <script src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="manifest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
-<video id="v" src="seek.webm" preload="metadata">
-  <track src="basic.vtt" kind="subtitles" id="default" default>
-</video>
-<script type="text/javascript">
-/**
- * This test is used to test the VTTCue's different behaviors and check whether
- * cues would be activatived correctly during video playback.
- */
-var video = document.getElementById("v");
-var trackElement = document.getElementById("default");
-
-async function runTest() {
-  await waitUntiTrackLoaded();
-  checkCueDefinition();
-  checkFirstCueParsedContent();
-  checkCueStartTimeAndEndtime();
-  checkCueSizeAndPosition();
-  checkCueSnapToLines();
-  checkCueAlignmentAndWritingDirection();
-  checkCueLine();
-  checkCreatingNewCue();
-  checkRemoveNonExistCue();
-  checkActiveCues();
-  checkCueRegion();
-  await checkCActiveCuesDuringVideoPlaying();
-  SimpleTest.finish();
-}
-
+<p id="display"></p>
+<div id="content">
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
 SimpleTest.waitForExplicitFinish();
 SpecialPowers.pushPrefEnv({"set": [["media.webvtt.regions.enabled", true]]},
-                            runTest);
-/**
- * The following are test helper functions.
- */
-async function waitUntiTrackLoaded() {
-  if (trackElement.readyState != 2) {
-    info(`wait until the track finishes loading`);
-    await once(trackElement, "load");
-  }
-  is(trackElement.readyState, 2, "Track::ReadyState should be set to LOADED.");
-  is(trackElement.track.cues.length, 6, "Cue list length should be 6.");
-}
+  function() {
+    var video = document.createElement("video");
+    video.src = "seek.webm";
+    video.preload = "metadata";
+
+    var trackElement = document.createElement("track");
+    trackElement.src = "basic.vtt";
+    trackElement.kind = "subtitles";
+
+    document.getElementById("content").appendChild(video);
+    video.appendChild(trackElement);
+    video.addEventListener("loadedmetadata", function run_tests() {
+      // Re-que run_tests() at the end of the event loop until the track
+      // element has loaded its data.
+      if (trackElement.readyState == 1) {
+        setTimeout(run_tests, 0);
+        return;
+      }
+
+      is(trackElement.readyState, 2, "Track::ReadyState should be set to LOADED.");
+      // Set mode to hidden so that the active cue lists are being updated.
+      trackElement.track.mode = "hidden";
+
+      var cueList = trackElement.track.cues;
+      is(cueList.length, 6, "Cue list length should be 6.");
+
+      // Check that the typedef of TextTrackCue works in Gecko.
+      isnot(window.TextTrackCue, undefined, "TextTrackCue should be defined.");
+      isnot(window.VTTCue, undefined, "VTTCue should be defined.");
 
-function checkCueDefinition() {
-  // Check that the typedef of TextTrackCue works in Gecko.
-  isnot(window.TextTrackCue, undefined, "TextTrackCue should be defined.");
-  isnot(window.VTTCue, undefined, "VTTCue should be defined.");
-}
+      // Check if first cue was parsed correctly.
+      var cue = cueList[0];
+      ok(cue instanceof TextTrackCue, "Cue should be an instanceof TextTrackCue.");
+      ok(cue instanceof VTTCue, "Cue should be an instanceof VTTCue.");
+      is(cue.id, "1", "Cue's ID should be 1.");
+      is(cue.startTime, 0.5, "Cue's start time should be 0.5.");
+      is(cue.endTime, 0.7, "Cue's end time should be 0.7.");
+      is(cue.pauseOnExit, false, "Cue's pause on exit flag should be false.");
+      is(cue.text, "This", "Cue's text should be set correctly.");
+      is(cue.track, trackElement.track, "Cue's track should be defined.");
+
+      cue.track = null;
+      isnot(cue.track, null, "Cue's track should not be able to be set.");
 
-function checkFirstCueParsedContent() {
-  // Check if first cue was parsed correctly.
-  const cue = trackElement.track.cues[0];
-  ok(cue instanceof TextTrackCue, "Cue should be an instanceof TextTrackCue.");
-  ok(cue instanceof VTTCue, "Cue should be an instanceof VTTCue.");
-  is(cue.id, "1", "Cue's ID should be 1.");
-  is(cue.startTime, 0.5, "Cue's start time should be 0.5.");
-  is(cue.endTime, 0.7, "Cue's end time should be 0.7.");
-  is(cue.pauseOnExit, false, "Cue's pause on exit flag should be false.");
-  is(cue.text, "This", "Cue's text should be set correctly.");
-  is(cue.track, trackElement.track, "Cue's track should be defined.");
-  cue.track = null;
-  isnot(cue.track, null, "Cue's track should not be able to be set.");
-}
+      // Check that all cue times were not rounded
+      is(cueList[1].startTime, 1.2, "Second cue's start time should be 1.2.");
+      is(cueList[1].endTime, 2.4, "Second cue's end time should be 2.4.");
+      is(cueList[2].startTime, 2, "Third cue's start time should be 2.");
+      is(cueList[2].endTime, 3.5, "Third cue's end time should be 3.5.");
+      is(cueList[3].startTime, 2.71, "Fourth cue's start time should be 2.71.");
+      is(cueList[3].endTime, 2.91, "Fourth cue's end time should be 2.91.");
+      is(cueList[4].startTime, 3.217, "Fifth cue's start time should be 3.217.");
+      is(cueList[4].endTime, 3.989, "Fifth cue's end time should be 3.989.");
+      is(cueList[5].startTime, 3.217, "Sixth cue's start time should be 3.217.");
+      is(cueList[5].endTime, 3.989, "Sixth cue's end time should be 3.989.");
+
+      // Check that Cue setters are working correctly.
+      cue.id = "Cue 01";
+      is(cue.id, "Cue 01", "Cue's ID should be 'Cue 01'.");
+      cue.startTime = 0.51;
+      is(cue.startTime, 0.51, "Cue's start time should be 0.51.");
+      cue.endTime = 0.71;
+      is(cue.endTime, 0.71, "Cue's end time should be 0.71.");
+      cue.pauseOnExit = true;
+      is(cue.pauseOnExit, true, "Cue's pause on exit flag should be true.");
+      video.addEventListener("pause", function() {
+        video.play();
+      }, {once: true});
 
-function checkCueStartTimeAndEndtime() {
-  const cueList = trackElement.track.cues;
-  // Check that all cue times were not rounded
-  is(cueList[1].startTime, 1.2, "Second cue's start time should be 1.2.");
-  is(cueList[1].endTime, 2.4, "Second cue's end time should be 2.4.");
-  is(cueList[2].startTime, 2, "Third cue's start time should be 2.");
-  is(cueList[2].endTime, 3.5, "Third cue's end time should be 3.5.");
-  is(cueList[3].startTime, 2.71, "Fourth cue's start time should be 2.71.");
-  is(cueList[3].endTime, 2.91, "Fourth cue's end time should be 2.91.");
-  is(cueList[4].startTime, 3.217, "Fifth cue's start time should be 3.217.");
-  is(cueList[4].endTime, 3.989, "Fifth cue's end time should be 3.989.");
-  is(cueList[5].startTime, 3.217, "Sixth cue's start time should be 3.217.");
-  is(cueList[5].endTime, 3.989, "Sixth cue's end time should be 3.989.");
+      var exceptionHappened;
+      function checkPercentageValue(prop, initialVal) {
+        ok(prop in cue, prop + " should be a property on VTTCue.");
+        cue[prop] = initialVal;
+        is(cue[prop], initialVal, "Cue's " + prop + " should initially be " + initialVal);
+        [ 101, -1 ].forEach(function(val) {
+          exceptionHappened = false;
+          try {
+            cue[prop] = val;
+          } catch(e) {
+            exceptionHappened = true;
+            is(e.name, "IndexSizeError", "Should have thrown IndexSizeError.");
+          }
+          ok(exceptionHappened, "Exception should have happened.");
+        });
+      }
+
+      checkPercentageValue("size", 100.0);
+      cue.size = 50.5;
+      is(cue.size, 50.5, "Cue's size should be 50.5.")
+
+      // Check cue.position
+      checkPercentageValue("position", "auto");
+      cue.position = 50.5;
+      is(cue.position, 50.5, "Cue's position value should now be 50.5.");
+
+      ok(cue.snapToLines, "Cue's snapToLines should be set by set.");
+      cue.snapToLines = false;
+      ok(!cue.snapToLines, "Cue's snapToLines should not be set.");
+
+      function checkEnumValue(prop, initialVal, acceptedValues) {
+        ok(prop in cue, prop + " should be a property on VTTCue.");
+        is(cue[prop], initialVal, "Cue's " + prop + " should be " + initialVal);
+        cue[prop] = "bogus";
+        is(cue[prop], initialVal, "Cue's " + prop + " should be " + initialVal);
+        acceptedValues.forEach(function(val) {
+          cue[prop] = val;
+          is(cue[prop], val, "Cue's " + prop + " should be " + val);
+          if (typeof val === "string") {
+            cue[prop] = val.toUpperCase();
+            is(cue[prop], val, "Cue's " + prop + " should be " + val);
+          }
+        });
+      }
 
-  // Check that Cue setters are working correctly.
-  const cue = trackElement.track.cues[0];
-  cue.id = "Cue 01";
-  is(cue.id, "Cue 01", "Cue's ID should be 'Cue 01'.");
-  cue.startTime = 0.51;
-  is(cue.startTime, 0.51, "Cue's start time should be 0.51.");
-  cue.endTime = 0.71;
-  is(cue.endTime, 0.71, "Cue's end time should be 0.71.");
-  cue.pauseOnExit = true;
-  is(cue.pauseOnExit, true, "Cue's pause on exit flag should be true.");
-  video.addEventListener("pause", function() {
-    video.play();
-  }, {once: true});
-}
+      checkEnumValue("align", "center", [ "start", "left", "center", "right", "end" ]);
+      checkEnumValue("lineAlign", "start", [ "start", "center", "end" ]);
+      checkEnumValue("vertical", "", [ "", "lr", "rl" ]);
+
+      cue.lineAlign = "center";
+      is(cue.lineAlign, "center", "Cue's line align should be center.");
+      cue.lineAlign = "START";
+      is(cue.lineAlign, "center", "Cue's line align should be center.");
+      cue.lineAlign = "end";
+      is(cue.lineAlign, "end", "Cue's line align should be end.");
+
+      // Check that cue position align works properly
+      is(cue.positionAlign, "auto", "Cue's default position alignment should be auto.");
+
+      cue.positionAlign = "line-left";
+      is(cue.positionAlign, "line-left", "Cue's position align should be line-left.");
+      cue.positionAlign = "auto";
+      is(cue.positionAlign, "auto", "Cue's position align should be auto.");
+      cue.positionAlign = "line-right";
+      is(cue.positionAlign, "line-right", "Cue's position align should be line-right.");
 
-function checkCueSizeAndPosition() {
-  function checkPercentageValue(prop, initialVal) {
-    ok(prop in cue, prop + " should be a property on VTTCue.");
-    cue[prop] = initialVal;
-    is(cue[prop], initialVal, `Cue's ${prop} should initially be ${initialVal}`);
-    [ 101, -1 ].forEach(function(val) {
+      // Check cue.line
+      is(cue.line, "auto", "Cue's line value should initially be auto.");
+      cue.line = 0.5;
+      is(cue.line, 0.5, "Cue's line value should now be 0.5.");
+      cue.line = "auto";
+      is(cue.line, "auto", "Cue's line value should now be auto.");
+
+      // Check that we can create and add new VTTCues
+      var vttCue = new VTTCue(3.999, 4, "foo");
+      is(vttCue.track, null, "Cue's track should be null.");
+      trackElement.track.addCue(vttCue);
+      is(cue.track, trackElement.track, "Cue's track should be defined.");
+      is(cueList.length, 7, "Cue list length should now be 7.");
+
+      // Check that new VTTCue was added correctly
+      cue = cueList[6];
+      is(cue.startTime, 3.999, "Cue's start time should be 3.999.");
+      is(cue.endTime, 4, "Cue's end time should be 4.");
+      is(cue.text, "foo", "Cue's text should be foo.");
+
+      // Adding the same cue again should not increase the cue count.
+      trackElement.track.addCue(vttCue);
+      is(cueList.length, 7, "Cue list length should be 7.");
+
+      // Check that we are able to remove cues.
+      trackElement.track.removeCue(cue);
+      is(cueList.length, 6, "Cue list length should be 6.");
+
       exceptionHappened = false;
       try {
-        cue[prop] = val;
-      } catch(e) {
+        // We should not be able to remove a cue that is not in the list.
+        cue = new VTTCue(1, 2, "foo");
+        trackElement.track.removeCue(cue);
+      } catch (e) {
+        // "NotFoundError" should be thrown when trying to remove a cue that is
+        // not in the list.
+        is(e.name, "NotFoundError", "Should have thrown NotFoundError.");
         exceptionHappened = true;
-        is(e.name, "IndexSizeError", "Should have thrown IndexSizeError.");
       }
+      // If this is false then we did not throw an error and probably removed a cue
+      // when we shouln't have.
       ok(exceptionHappened, "Exception should have happened.");
-    });
-  }
+
+      is(cueList.length, 6, "Cue list length should be 6.");
 
-  const cue = trackElement.track.cues[0];
-  checkPercentageValue("size", 100.0);
-  cue.size = 50.5;
-  is(cue.size, 50.5, "Cue's size should be 50.5.")
+      video.currentTime = 2;
+      isnot(trackElement.track.activeCues, null);
+
+      trackElement.track.mode = "disabled";
+      is(trackElement.track.activeCues, null);
 
-  // Check cue.position
-  checkPercentageValue("position", "auto");
-  cue.position = 50.5;
-  is(cue.position, 50.5, "Cue's position value should now be 50.5.");
-}
+      trackElement.track.mode = "showing";
+      video.currentTime = 0;
+
+      var regionInfo = [
+        { lines: 2, width: 30 },
+        { lines: 4, width: 20 },
+        { lines: 2, width: 30 }
+      ];
 
-function checkCueSnapToLines() {
-  const cue = trackElement.track.cues[0];
-  ok(cue.snapToLines, "Cue's snapToLines should be set by set.");
-  cue.snapToLines = false;
-  ok(!cue.snapToLines, "Cue's snapToLines should not be set.");
-}
+      for (var i = 0; i < regionInfo.length; i++) {
+        var cue = cueList[i];
+        isnot(cue.region, null, "Cue at " + i + " should have a region.");
+        for (var key in regionInfo[i]) {
+          is(cue.region[key], regionInfo[i][key], "Region should have a " + key +
+                                                  " property with a value of " + regionInfo[i][key])
+        }
+      }
+
+      // Test TextTrack::ActiveCues.
+      var cueInfo = [
+        { startTime: 0.51, endTime: 0.71, ids: ["Cue 01"] },
+        { startTime: 0.72, endTime: 1.19, ids: [] },
+        { startTime: 1.2, endTime: 1.9, ids: [2] },
+        { startTime: 2, endTime: 2.4, ids: [2, 2.5] },
+        { startTime: 2.41, endTime: 2.70, ids: [2.5] },
+        { startTime: 2.71, endTime: 2.91, ids: [2.5, 3] },
+        { startTime: 2.92, endTime: 3.216, ids: [2.5] },
+        { startTime: 3.217, endTime: 3.5, ids: [2.5, 4, 5] },
+        { startTime: 3.51, endTime: 3.989, ids: [4, 5] },
+        { startTime: 3.99, endTime: 4, ids: [] }
+      ];
 
-function checkCueAlignmentAndWritingDirection() {
-  function checkEnumValue(prop, initialVal, acceptedValues) {
-    ok(prop in cue, `${prop} should be a property on VTTCue.`);
-    is(cue[prop], initialVal, `Cue's ${prop} should be ${initialVal}`);
-    cue[prop] = "bogus";
-    is(cue[prop], initialVal, `Cue's ${prop} should be ${initialVal}`);
-    acceptedValues.forEach(function(val) {
-      cue[prop] = val;
-      is(cue[prop], val, `Cue's ${prop} should be ${val}`);
-      if (typeof val === "string") {
-        cue[prop] = val.toUpperCase();
-        is(cue[prop], val, `Cue's ${prop} should be ${val}`);
-      }
+      video.addEventListener("timeupdate", function() {
+        var activeCues = trackElement.track.activeCues,
+            found = false,
+            playbackTime = video.currentTime;
+
+        for (var i = 0; i < cueInfo.length; i++) {
+          var cue = cueInfo[i];
+          if (playbackTime >= cue.startTime && playbackTime < cue.endTime) {
+            is(activeCues.length, cue.ids.length, "There should be " + cue.ids.length + " currently active cue(s).");
+            for (var j = 0; j < cue.ids.length; j++) {
+              isnot(activeCues.getCueById(cue.ids[j]), undefined, "The cue with ID " + cue.ids[j] + " should be active.");
+            }
+            break;
+          }
+        }
+      });
+
+      video.addEventListener("ended", function(){
+        SimpleTest.finish();
+      });
+
+      video.play();
     });
   }
-
-  const cue = trackElement.track.cues[0];
-  checkEnumValue("align", "center", [ "start", "left", "center", "right", "end" ]);
-  checkEnumValue("lineAlign", "start", [ "start", "center", "end" ]);
-  checkEnumValue("vertical", "", [ "", "lr", "rl" ]);
-
-  cue.lineAlign = "center";
-  is(cue.lineAlign, "center", "Cue's line align should be center.");
-  cue.lineAlign = "START";
-  is(cue.lineAlign, "center", "Cue's line align should be center.");
-  cue.lineAlign = "end";
-  is(cue.lineAlign, "end", "Cue's line align should be end.");
-
-  // Check that cue position align works properly
-  is(cue.positionAlign, "auto", "Cue's default position alignment should be auto.");
-
-  cue.positionAlign = "line-left";
-  is(cue.positionAlign, "line-left", "Cue's position align should be line-left.");
-  cue.positionAlign = "auto";
-  is(cue.positionAlign, "auto", "Cue's position align should be auto.");
-  cue.positionAlign = "line-right";
-  is(cue.positionAlign, "line-right", "Cue's position align should be line-right.");
-}
-
-function checkCueLine() {
-  const cue = trackElement.track.cues[0];
-  // Check cue.line
-  is(cue.line, "auto", "Cue's line value should initially be auto.");
-  cue.line = 0.5;
-  is(cue.line, 0.5, "Cue's line value should now be 0.5.");
-  cue.line = "auto";
-  is(cue.line, "auto", "Cue's line value should now be auto.");
-}
-
-function checkCreatingNewCue() {
-  const cueList = trackElement.track.cues;
-
-  // Check that we can create and add new VTTCues
-  let vttCue = new VTTCue(3.999, 4, "foo");
-  is(vttCue.track, null, "Cue's track should be null.");
-  trackElement.track.addCue(vttCue);
-  is(vttCue.track, trackElement.track, "Cue's track should be defined.");
-  is(cueList.length, 7, "Cue list length should now be 7.");
-
-  // Check that new VTTCue was added correctly
-  let cue = cueList[6];
-  is(cue.startTime, 3.999, "Cue's start time should be 3.999.");
-  is(cue.endTime, 4, "Cue's end time should be 4.");
-  is(cue.text, "foo", "Cue's text should be foo.");
-
-  // Adding the same cue again should not increase the cue count.
-  trackElement.track.addCue(vttCue);
-  is(cueList.length, 7, "Cue list length should be 7.");
-
-  // Check that we are able to remove cues.
-  trackElement.track.removeCue(cue);
-  is(cueList.length, 6, "Cue list length should be 6.");
-}
-
-function checkRemoveNonExistCue() {
-  is(trackElement.track.cues.length, 6, "Cue list length should be 6.");
-  let exceptionHappened = false;
-  try {
-    // We should not be able to remove a cue that is not in the list.
-    trackElement.track.removeCue(new VTTCue(1, 2, "foo"));
-  } catch (e) {
-    // "NotFoundError" should be thrown when trying to remove a cue that is
-    // not in the list.
-    is(e.name, "NotFoundError", "Should have thrown NotFoundError.");
-    exceptionHappened = true;
-  }
-  // If this is false then we did not throw an error and probably removed a cue
-  // when we shouln't have.
-  ok(exceptionHappened, "Exception should have happened.");
-  is(trackElement.track.cues.length, 6, "Cue list length should still be 6.");
-}
-
-function checkActiveCues() {
-  video.currentTime = 2;
-  isnot(trackElement.track.activeCues, null);
-
-  trackElement.track.mode = "disabled";
-  is(trackElement.track.activeCues, null, "No active cue when track is disabled.");
-  trackElement.track.mode = "showing";
-}
-
-function checkCueRegion() {
-  let regionInfo = [
-    { lines: 2, width: 30 },
-    { lines: 4, width: 20 },
-    { lines: 2, width: 30 }
-  ];
-
-  for (let i = 0; i < regionInfo.length; i++) {
-    let cue = trackElement.track.cues[i];
-    isnot(cue.region, null, `Cue at ${i} should have a region.`);
-    for (let key in regionInfo[i]) {
-      is(cue.region[key], regionInfo[i][key],
-         `Region should have a ${key} property with a value of ${regionInfo[i][key]}`);
-    }
-  }
-}
-
-async function checkCActiveCuesDuringVideoPlaying() {
-  // Test TextTrack::ActiveCues.
-  let cueInfo = [
-    { startTime: 0.51, endTime: 0.71, ids: ["Cue 01"] },
-    { startTime: 0.72, endTime: 1.19, ids: [] },
-    { startTime: 1.2, endTime: 1.9, ids: [2] },
-    { startTime: 2, endTime: 2.4, ids: [2, 2.5] },
-    { startTime: 2.41, endTime: 2.70, ids: [2.5] },
-    { startTime: 2.71, endTime: 2.91, ids: [2.5, 3] },
-    { startTime: 2.92, endTime: 3.216, ids: [2.5] },
-    { startTime: 3.217, endTime: 3.5, ids: [2.5, 4, 5] },
-    { startTime: 3.51, endTime: 3.989, ids: [4, 5] },
-    { startTime: 3.99, endTime: 4, ids: [] }
-  ];
-
-  video.addEventListener("timeupdate", function() {
-    let activeCues = trackElement.track.activeCues,
-        found = false,
-        playbackTime = video.currentTime;
-
-    for (let i = 0; i < cueInfo.length; i++) {
-      let cue = cueInfo[i];
-      if (playbackTime >= cue.startTime && playbackTime < cue.endTime) {
-        is(activeCues.length, cue.ids.length, `There should be ${cue.ids.length} currently active cue(s).`);
-        for (let j = 0; j < cue.ids.length; j++) {
-          isnot(activeCues.getCueById(cue.ids[j]), undefined,
-                `The cue with ID ${cue.ids[j]} should be active.`);
-        }
-        break;
-      }
-    }
-  });
-
-  info(`start video from 0s.`);
-  video.currentTime = 0;
-  video.play();
-  await once(video, "playing");
-  info(`video starts playing.`);
-  await once(video, "ended");
-}
+);
 
 </script>
+</pre>
 </body>
 </html>
--- a/dom/media/test/test_texttrackregion.html
+++ b/dom/media/test/test_texttrackregion.html
@@ -1,57 +1,64 @@
 <!DOCTYPE HTML>
 <html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=917945
+-->
 <head>
+  <meta charset='utf-8'>
   <title>Test for Bug 917945 - VTTRegion</title>
+  <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
   <script src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="manifest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
-<video id="v" src="seek.webm" preload="auto">
-  <track src="region.vtt" kind="subtitles" id="default" default>
-</video>
-<script type="text/javascript">
-/**
- * This test is used to ensure that we can parse VTT region attributes correctly
- * from vtt file.
- */
-var trackElement = document.getElementById("default");
-
-async function runTest() {
-  await waitUntiTrackLoaded();
-  checkRegionAttributes();
-  SimpleTest.finish();
-}
-
+<p id="display"></p>
+<div id="content">
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
 SimpleTest.waitForExplicitFinish();
 SpecialPowers.pushPrefEnv({"set": [["media.webvtt.regions.enabled", true]]},
-                            runTest);
-/**
- * The following are test helper functions.
- */
-async function waitUntiTrackLoaded() {
-  if (trackElement.readyState != 2) {
-    info(`wait until the track finishes loading`);
-    await once(trackElement, "load");
-  }
-  is(trackElement.readyState, 2, "Track::ReadyState should be set to LOADED.");
-}
+  function() {
+    var video = document.createElement("video");
+    video.src = "seek.webm";
+    video.preload = "auto";
+
+    var trackElement = document.createElement("track");
+    trackElement.src = "region.vtt";
+    trackElement.kind = "subtitles";
+
+    document.getElementById("content").appendChild(video);
+    video.appendChild(trackElement);
+    video.addEventListener("loadedmetadata", function run_tests() {
+      // Re-que run_tests() at the end of the event loop until the track
+      // element has loaded its data.
+      if (trackElement.readyState == 1) {
+        setTimeout(run_tests, 0);
+        return;
+      }
+      is(trackElement.readyState, 2, "Track::ReadyState should be set to LOADED.");
 
-function checkRegionAttributes() {
-  let cues = trackElement.track.cues;
-  is(cues.length, 1, "Cue list length should be 1.");
+      // Set mode to hidden so that the active cue lists are being updated.
+      trackElement.track.mode = "hidden";
+
+      var cues = trackElement.track.cues;
+      is(cues.length, 1, "Cue list length should be 1.");
 
-  let region = cues[0].region;
-  isnot(region, null, "Region should not be null.");
-  is(region.width, 62, "Region width should be 50.");
-  is(region.lines, 5, "Region lines should be 5.");
-  is(region.regionAnchorX, 4, "Region regionAnchorX should be 4.");
-  is(region.regionAnchorY, 78, "Region regionAnchorY should be 78.");
-  is(region.viewportAnchorX, 10, "Region viewportAnchorX should be 10.");
-  is(region.viewportAnchorY, 90, "Region viewportAnchorY should be 90.");
-  is(region.scroll, "up", "Region scroll should be 'up'");
-}
+      var region = cues[0].region;
+      isnot(region, null, "Region should not be null.");
+      is(region.width, 62, "Region width should be 50.");
+      is(region.lines, 5, "Region lines should be 5.");
+      is(region.regionAnchorX, 4, "Region regionAnchorX should be 4.");
+      is(region.regionAnchorY, 78, "Region regionAnchorY should be 78.");
+      is(region.viewportAnchorX, 10, "Region viewportAnchorX should be 10.");
+      is(region.viewportAnchorY, 90, "Region viewportAnchorY should be 90.");
+      is(region.scroll, "up", "Region scroll should be 'up'");
 
+      SimpleTest.finish();
+    });
+  }
+);
 </script>
+</pre>
 </body>
 </html>
--- a/dom/media/test/test_trackelementevent.html
+++ b/dom/media/test/test_trackelementevent.html
@@ -1,77 +1,69 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <title>Test for Bug 882677 - Implement the 'sourcing out of band text tracks' algorithm</title>
+  <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
   <script src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="manifest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
-<video id="v" src="seek.webm" preload="auto">
-<script type="text/javascript">
-/**
- * This test is used to ensure that we can load resource from vtt files correctly
- * and will dispatch `error` event for invalid vtt files.
- */
-var video = document.getElementById("v");
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+SpecialPowers.pushPrefEnv({"set": [["media.webvtt.regions.enabled", true]]},
+  function() {
+    var video = document.createElement("video");
+    video.src = "seek.webm";
+    video.preload = "auto";
 
-async function runTest() {
-  let tracks = createTextTrackElements();
-  appendTracksToVideo(tracks);
-  await waitUntilsTrackLoadedOrGetError(tracks);
-  SimpleTest.finish()
-}
-
-SimpleTest.waitForExplicitFinish();
-onload = runTest;
+    var trackOne = document.createElement("track");
+    trackOne.src = "basic.vtt";
+    trackOne.kind = "subtitles";
 
-/**
- * The following are test helper functions.
- */
-function createTextTrackElements() {
-  // Only first track has valid vtt resource, other tracks should get the error
-  // event because of invalid vtt resources.
-  let trackOne = document.createElement("track");
-  trackOne.src = "basic.vtt";
-  trackOne.kind = "subtitles";
-  trackOne.expectedLoaded = true;
+    var trackTwo = document.createElement("track");
+    trackTwo.src = "bad-signature.vtt";
+    trackTwo.kind = "captions";
+
+    var trackThree = document.createElement("track");
+    trackThree.src = "bad.vtt";
+    trackThree.kind = "chapters";
 
-  let trackTwo = document.createElement("track");
-  trackTwo.src = "bad-signature.vtt";
-  trackTwo.kind = "captions";
-  trackTwo.expectedLoaded = false;
-
-  let trackThree = document.createElement("track");
-  trackThree.src = "bad.vtt";
-  trackThree.kind = "chapters";
-  trackThree.expectedLoaded = false;
-
-  return [trackOne, trackTwo, trackThree];
-}
-
-function appendTracksToVideo(tracks) {
-  for (let track of tracks) {
-    video.appendChild(track);
-  }
-}
+    var events = 0;
+    function trackOneEvent() {
+      ok(true, "A load event for trackOne should have happened.");
+      events++ && events == 3 && SimpleTest.finish();
+    }
+    function trackTwoEvent() {
+      ok(true, "An error event for trackTwo should have happened.");
+      events++ && events == 3 && SimpleTest.finish();
+    }
+    function trackThreeEvent() {
+      ok(true, "An error event for trackThree should have happened.");
+      events++ && events == 3 && SimpleTest.finish();
+    }
 
-async function waitUntilsTrackLoadedOrGetError(tracks) {
-  let promises = [];
-  for (let track of tracks) {
-    // explictly enable those track in order to start loading.
-    track.track.mode = "hidden";
-    if (track.expectedLoaded) {
-      info(`adding 'load' event to wait list.`);
-      promises.push(once(track, "load"));
-    } else {
-      info(`adding 'error' event to wait list.`);
-      promises.push(once(track, "error"));
+    function shouldNotBeCalled() {
+      ok(false, "Event should not have been called.");
     }
+
+    trackOne.addEventListener("load", trackOneEvent);
+    trackOne.addEventListener("error", shouldNotBeCalled)
+    trackTwo.addEventListener("load", shouldNotBeCalled);
+    trackTwo.addEventListener("error", trackTwoEvent);
+    trackThree.addEventListener("load", shouldNotBeCalled);
+    trackThree.addEventListener("error", trackThreeEvent);
+
+    document.getElementById("content").appendChild(video);
+    video.appendChild(trackOne);
+    video.appendChild(trackTwo);
+    video.appendChild(trackThree);
   }
-  info(`wait until tracks finish loading or get error.`);
-  await Promise.all(promises);
-  ok(true, "all tracks finish loading or get error.");
-}
+);
 </script>
+</pre>
 </body>
 </html>
+
--- a/testing/profiles/web-platform/user.js
+++ b/testing/profiles/web-platform/user.js
@@ -29,11 +29,8 @@ user_pref("network.http.phishy-userpass-
 // Disable safebrowsing components
 user_pref("browser.safebrowsing.blockedURIs.enabled", false);
 user_pref("browser.safebrowsing.downloads.enabled", false);
 user_pref("browser.safebrowsing.passwords.enabled", false);
 user_pref("browser.safebrowsing.malware.enabled", false);
 user_pref("browser.safebrowsing.phishing.enabled", false);
 // Automatically unload beforeunload alerts
 user_pref("dom.disable_beforeunload", true);
-// sometime wpt runs test even before the document becomes visible, which would
-// delay video.play() and cause play() running in wrong order.
-user_pref("media.block-autoplay-until-in-foreground", false);
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/html/semantics/embedded-content/media-elements/autoplay-with-broken-track.html.ini
@@ -0,0 +1,13 @@
+[autoplay-with-broken-track.html]
+  expected: TIMEOUT
+  disabled:
+    if debug and (os == "linux") and (processor == "x86"): https://bugzilla.mozilla.org/show_bug.cgi?id=1482405
+  [<video autoplay> with <track src="invalid://url" default=""> child]
+    expected:
+      if (os == "android") and not e10s: PASS
+      if (os == "android") and e10s: PASS
+      TIMEOUT
+
+  [<video autoplay> with <track src="" default=""> child]
+    expected: TIMEOUT
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/html/semantics/embedded-content/media-elements/track/track-element/src-clear-cues.html.ini
@@ -0,0 +1,10 @@
+[src-clear-cues.html]
+  [track element changing "track URL" and clearing cues, set mode, add cue, set src]
+    expected: FAIL
+
+  [track element changing "track URL" and clearing cues, set mode, set src, add cue, change src]
+    expected: FAIL
+
+  [track element changing "track URL" and clearing cues, set mode, add cue, change mode to disabled, set src]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/html/semantics/embedded-content/media-elements/track/track-element/src-empty-string.html.ini
@@ -0,0 +1,5 @@
+[src-empty-string.html]
+  expected: TIMEOUT
+  [Setting HTMLTrackElement.src to the empty string fires 'error' and sets readyState to ERROR]
+    expected: TIMEOUT
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/html/semantics/embedded-content/media-elements/track/track-element/track-default-attribute.html.ini
@@ -0,0 +1,4 @@
+[track-default-attribute.html]
+  [A track with the "default" attribute loads automatically]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/html/semantics/embedded-content/media-elements/track/track-element/track-element-src-change-error.html.ini
@@ -0,0 +1,4 @@
+[track-element-src-change-error.html]
+  [HTMLTrackElement 'src' attribute mutations]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/html/semantics/embedded-content/media-elements/track/track-element/track-element-src-change.html.ini
@@ -0,0 +1,4 @@
+[track-element-src-change.html]
+  [HTMLTrackElement 'src' attribute mutations]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/html/semantics/embedded-content/media-elements/track/track-element/track-mode-not-changed-by-new-track.html.ini
@@ -0,0 +1,4 @@
+[track-mode-not-changed-by-new-track.html]
+  [A track appended after the initial track configuration does not change other tracks]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/html/semantics/embedded-content/media-elements/track/track-element/track-mode-triggers-loading.html.ini
@@ -0,0 +1,4 @@
+[track-mode-triggers-loading.html]
+  [A "metadata" track does not load automatically, but it does load when the mode is changed]
+    expected: FAIL
+
--- a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/track-element-src-change-error.html
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/track-element-src-change-error.html
@@ -16,71 +16,77 @@
                     cues = testTrack.track.cues;
                     assert_equals(testTrack.readyState, HTMLTrackElement.LOADED, "readyState after first loading of the track");
                     assert_equals(cues.length, 4, "Number of cues after first loading of the track");
                     ++stage;
                     testTrack.src = "resources/non-existing-file.vtt"; // this should fail
                     break;
                 case 1:
                 case 3:
-                case 4:
+                case 5:
                     assert_unreached("'error' event did not fire, stage = " + stage);
                     break;
                 case 2:
                     assert_equals(testTrack.readyState, HTMLTrackElement.LOADED, "readyState after loading of the second track");
                     assert_equals(cues.length, 4, "Number of cues after loading of the second track");
                     assert_equals(cues[cues.length-1].text, 'I said Bear is coming now!!!! Tab separators.', "Last cue content check");
                     ++stage;
                     testTrack.src = ""; // this should fail
-                    assert_equals(cues.length, 0, "cues list is reset immediately after 'src' mutation with the new URL");
+                    // CuesList will be cleared in the next tick. Spec claims that this should happen immediately,
+                    // but all implementations are doing this asynchronously.
+                    assert_equals(cues.length, 4, "Number of cues immediately after 'src' mutation with the empty URL");
                     // This should raise onError event. If no, we'll know about this after some time.
                     timer = t.step_timeout(t.unreached_func("'error' event is not fired when an empty URL is set"), 100);
                     break;
+                case 4:
+                    assert_equals(testTrack.readyState, HTMLTrackElement.LOADED, "readyState after loading of the second track");
+                    assert_equals(cues.length, 4, "Number of cues after loading of the second track");
+                    assert_equals(cues[cues.length-1].text, 'I said Bear is coming now!!!! Tab separators.', "Last cue content check");
+                    ++stage;
+                    testTrack.removeAttribute('src');
+                    // This should raise onError event, so we'll wait for it for some time
+                    timer = t.step_timeout(t.unreached_func("'error' event is not fired when an empty URL is set"), 100);
+                    break;
                 default:
                     assert_unreached("unexpected stage number = " + stage);
                     break;
             }
         }
 
         function step_onError() {
             switch (stage) {
                 case 0:
                 case 2:
+                case 4:
                     assert_unreached("'error' event fired, stage = " + stage);
                     break;
                 case 1:
                     assert_equals(cues, testTrack.track.cues, ".cues object are the same after 'src' attr mutation");
                     assert_equals(cues.length, 0, "Number of cues after trying to load non-existing url");
                     assert_equals(testTrack.readyState, HTMLTrackElement.ERROR, "readyState after trying to load non-existing url");
                     ++stage;
                     testTrack.src = "resources/settings.vtt";
                     break;
                 case 3:
                     clearTimeout(timer);
                     assert_equals(testTrack.readyState, HTMLTrackElement.ERROR, "readyState after setting an empty URL");
                     assert_equals(cues, testTrack.track.cues, ".cues object are the same after 'src' attr mutation");
                     assert_equals(cues.length, 0, "Number of cues with an empty URL set");
                     ++stage;
                     testTrack.src = "resources/settings.vtt";
-                    // error should happen when we remove `src` during loading, so we have to wait a task because loading starts asynchronously.
-                    t.step_timeout(() => {
-                        testTrack.removeAttribute('src');
-                        // This should raise onError event, so we'll wait for it for some time
-                        timer = t.step_timeout(t.unreached_func("'error' event is not fired when an empty URL is set"), 100);
-                    }, 0);
                     break;
-                case 4:
+                case 5:
                     clearTimeout(timer);
                     assert_equals(testTrack.readyState, HTMLTrackElement.ERROR, "readyState after removing 'src' attr");
                     assert_equals(cues.length, 0, "Number of cues after removing 'src' attr");
                     t.done();
                     break;
                 default:
                     assert_unreached("unexpected stage number = " + stage);
                     break;
             }
         }
 
         testTrack.onload = t.step_func(step_onLoad);
         testTrack.onerror = t.step_func(step_onError);
     });
     </script>
-</video>
+</video>
\ No newline at end of file
--- a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/track-element-src-change.html
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/track-element-src-change.html
@@ -13,17 +13,19 @@
             switch (stage) {
                 case 0:
                     cues = testTrack.track.cues;
                     assert_equals(testTrack.readyState, HTMLTrackElement.LOADED, "readyState after first loading of the track");
                     assert_equals(cues.length, 4, "Number of cues after first loading of the track");
                     assert_equals(cues[cues.length-1].text, 'I said Bear is coming now!!!! Tab separators.', "Last cue content check");
                     ++stage;
                     testTrack.src = "resources/entities.vtt";
-                    assert_equals(cues.length, 0, "cues list is reset immediately after 'src' mutation with the new URL");
+                    // CuesList will be cleared in a microtask. Spec claims that this should happen immediately,
+                    // but all known implementations are doing this asynchronously.
+                    assert_equals(cues.length, 4, "Number of cues immediately after 'src' mutation with the new URL");
                     break;
                 case 1:
                     assert_equals(testTrack.readyState, HTMLTrackElement.LOADED), "readyState after loading of the second track";
                     assert_equals(cues, testTrack.track.cues, ".cues object are the same after 'src' attr mutation");
                     assert_equals(cues.length, 7, "Number of cues after loading of the second track");
                     assert_equals(cues[cues.length-1].text, 'This & is parsed to the same as &amp;.', "Last cue content check");
                     ++stage;
                     testTrack.src = "resources/settings.vtt";
@@ -47,9 +49,9 @@
                     break;
             }
         }
 
         testTrack.onload = t.step_func(step_onLoad);
         testTrack.onerror = t.unreached_func("'error' event should not fire");
     });
     </script>
-</video>
+</video>
\ No newline at end of file
--- a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/track-mode-not-changed-by-new-track.html
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/track-mode-not-changed-by-new-track.html
@@ -28,22 +28,21 @@ async_test(function(t) {
 
     function metadataTrackLoaded() {
         // check metadata track state.
         assert_equals(track1.readyState, HTMLTrackElement.LOADED);
         assert_equals(track1.track.mode, 'hidden');
         assert_equals(track1.track.cues.length, 12);
         assert_equals(track1.track.cues[11].startTime, 22);
 
-        // Add a caption track, and explicitly enable it.
+        // Add a caption track, configured to load automatically.
         track2 = document.createElement('track');
         track2.setAttribute('kind', 'captions');
         track2.setAttribute('default', 'default');
         track2.setAttribute('src', 'resources/webvtt-file.vtt');
-        track2.track.mode = 'showing';
         track2.onload = t.step_func(captionsTrackLoaded);
         video.appendChild(track2);
     }
 
     function captionsTrackLoaded() {
         // Check that metadata track state has not changed.
         assert_equals(track1.readyState, HTMLTrackElement.LOADED);
         assert_equals(track1.track.mode, 'hidden');
@@ -52,17 +51,17 @@ async_test(function(t) {
         assert_equals(track2.track.mode, 'showing');
 
         video.textTracks.onaddtrack = t.step_func_done(trackAdded);
         // add a subtitle track with video.addTextTrack().
         track3 = video.addTextTrack('subtitles', 'Subtitle Track', 'en');
         track3.mode = 'showing';
     }
 
-    function trackAdded(event) {
+    function trackAdded() {
         // Check that metadata track state has not changed.
         assert_equals(track1.readyState, HTMLTrackElement.LOADED);
         assert_equals(track1.track.mode, 'hidden');
         // and that the caption track state has not changed.
         assert_equals(track2.readyState, HTMLTrackElement.LOADED);
         assert_equals(track2.track.mode, 'showing');
         // and that the subtitle track state is correct.
         assert_equals(event.target, video.textTracks);
deleted file mode 100644
--- a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/track-selection-task-order.html
+++ /dev/null
@@ -1,36 +0,0 @@
-<!DOCTYPE html>
-<title>HTMLTrackElement Text Track Selection Task Order</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script>
-/**
- * This test is used to ensure that we queue 'honor user preferences for automatic
- * text track selection' as a macro task, not a micro task. In this test, we
- * trigger a media event before queuing a text track selection task, and check
- * the text track's mode to know whether the text track selection runs after the
- * task for media event.
- */
-async_test(function(t) {
-    let video = document.createElement("video");
-    video.play();
-    video.onplay = t.step_func(startedPlay);
-
-    // When we create a text track element, it queue a task to run automatic
-    // text track selection later.
-    let track = document.createElement("track");
-    track.default = true;
-    video.appendChild(track);
-    assert_equals(track.track.mode, "disabled", "Text track's mode is disabled by default.");
-
-    function startedPlay() {
-        assert_equals(track.track.mode, "disabled", "Text track selection hasn't started yet.");
-        track.onerror = t.step_func_done(trackError);
-    }
-
-    function trackError() {
-        assert_equals(track.track.mode, "showing", "Text track selection modified track's mode.");
-        t.done();
-    }
-});
-
-</script>