/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// 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) {
RefPtr<mozilla::dom::NodeInfo> nodeInfo(aNodeInfo); auto* nim = nodeInfo->NodeInfoManager(); returnnew (nim) mozilla::dom::HTMLTrackElement(nodeInfo.forget());
}
// 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];
class WindowDestroyObserver final : public nsIObserver {
NS_DECL_ISUPPORTS
HTMLTrackElement::~HTMLTrackElement() { if (mWindowDestroyObserver) {
mWindowDestroyObserver->UnRegisterWindowDestroyObserver();
} // Track element is being destroyed, cancel without checking for RFP.
CancelChannelAndListener(false);
}
TextTrackKind kind; if (const nsAttrValue* value = GetParsedAttr(nsGkAtoms::kind)) {
kind = static_cast<TextTrackKind>(value->GetEnumValue());
} else {
kind = TextTrackKind::Subtitles;
}
MOZ_ASSERT(!mTrack, "No need to recreate a text track!");
mTrack = new TextTrack(window, kind, label, srcLang, TextTrackMode::Disabled,
TextTrackReadyState::NotLoaded, TextTrackSource::Track);
mTrack->SetTrackElement(this);
}
bool HTMLTrackElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute, const nsAString& aValue,
nsIPrincipal* aMaybeScriptedPrincipal,
nsAttrValue& aResult) { if (aNamespaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::kind) { // Case-insensitive lookup, with the first element as the default. return aResult.ParseEnumValue(aValue, kKindTable, false,
kKindTableInvalidValueDefault);
}
// 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. bool resistFingerprinting = ShouldResistFingerprinting(RFPTarget::WebVTT); if (mTrack->Mode() == TextTrackMode::Disabled && !resistFingerprinting) {
LOG("Do not load resource for disable track"); return;
}
// We need to do this check in order to prevent // HonorUserPreferencesForTrackSelection from loading the text track twice. if (resistFingerprinting && ReadyState() == TextTrackReadyState::Loading) { 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;
}
// step5, await a stable state and run the rest of steps. 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;
}
}
nsAutoString src; if (!GetAttr(nsGkAtoms::src, src) || src.IsEmpty()) {
LOG("Fail to load because no src");
SetReadyState(TextTrackReadyState::FailedToLoad); 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());
// Prevent canceling the channel and listener if RFP is enabled.
CancelChannelAndListener(true);
// According to // https://www.w3.org/TR/html5/embedded-content-0.html#sourcing-out-of-band-text-tracks // // "8: If the track element's parent is a media element then let CORS mode // be the state of the parent media element's crossorigin content attribute. // Otherwise, let CORS mode be No CORS." //
CORSMode corsMode =
mMediaParent ? AttrValueToCORSMode(
mMediaParent->GetParsedAttr(nsGkAtoms::crossorigin))
: CORS_NONE;
// Determine the security flag based on corsMode.
nsSecurityFlags secFlags; if (CORS_NONE == corsMode) { // Same-origin is required for track element.
secFlags = nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_INHERITS_SEC_CONTEXT;
} else {
secFlags = nsILoadInfo::SEC_REQUIRE_CORS_INHERITS_SEC_CONTEXT; if (CORS_ANONYMOUS == corsMode) {
secFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
} elseif (CORS_USE_CREDENTIALS == corsMode) {
secFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
} else {
NS_WARNING("Unknown CORS mode.");
secFlags = nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_INHERITS_SEC_CONTEXT;
}
}
mListener = std::move(aWebVTTListener); // This will do 6. Set the text track readiness state to loading.
rv = mListener->LoadResource();
NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));
LOG("Track Element bound to tree."); auto* parent = HTMLMediaElement::FromNode(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.");
// 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();
} // As `CreateTextTrack()` might fail, so we have to check it again. if (mTrack) {
LOG("Add text track to media parent");
mMediaParent->AddTextTrack(mTrack);
}
MaybeDispatchLoadResource();
}
return NS_OK;
}
void HTMLTrackElement::UnbindFromTree(UnbindContext& aContext) { if (mMediaParent && aContext.IsUnbindRoot(this)) { // mTrack can be null if HTMLTrackElement::LoadResource has never been // called. if (mTrack) {
mMediaParent->RemoveTextTrack(mTrack);
mMediaParent->UpdateReadyState();
}
mMediaParent = nullptr;
}
nsGenericHTMLElement::UnbindFromTree(aContext);
}
TextTrackReadyState HTMLTrackElement::ReadyState() const { if (!mTrack) { return TextTrackReadyState::NotLoaded;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.