Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / dom / html / VideoDocument.cpp
blob00b5bf53089a30e0d9b545ddc1f7fbc14ae343c4
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "MediaDocument.h"
8 #include "nsGkAtoms.h"
9 #include "nsNodeInfoManager.h"
10 #include "nsContentCreatorFunctions.h"
11 #include "mozilla/dom/HTMLMediaElement.h"
12 #include "DocumentInlines.h"
13 #include "nsContentUtils.h"
14 #include "mozilla/dom/Element.h"
16 namespace mozilla::dom {
18 class VideoDocument final : public MediaDocument {
19 public:
20 enum MediaDocumentKind MediaDocumentKind() const override {
21 return MediaDocumentKind::Video;
24 virtual nsresult StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
25 nsILoadGroup* aLoadGroup,
26 nsISupports* aContainer,
27 nsIStreamListener** aDocListener,
28 bool aReset = true) override;
29 virtual void SetScriptGlobalObject(
30 nsIScriptGlobalObject* aScriptGlobalObject) override;
32 virtual void Destroy() override {
33 if (mStreamListener) {
34 mStreamListener->DropDocumentRef();
36 MediaDocument::Destroy();
39 nsresult StartLayout() override;
41 protected:
42 nsresult CreateVideoElement();
43 // Sets document <title> to reflect the file name and description.
44 void UpdateTitle(nsIChannel* aChannel);
46 RefPtr<MediaDocumentStreamListener> mStreamListener;
49 nsresult VideoDocument::StartDocumentLoad(
50 const char* aCommand, nsIChannel* aChannel, nsILoadGroup* aLoadGroup,
51 nsISupports* aContainer, nsIStreamListener** aDocListener, bool aReset) {
52 nsresult rv = MediaDocument::StartDocumentLoad(
53 aCommand, aChannel, aLoadGroup, aContainer, aDocListener, aReset);
54 NS_ENSURE_SUCCESS(rv, rv);
56 mStreamListener = new MediaDocumentStreamListener(this);
57 NS_ADDREF(*aDocListener = mStreamListener);
58 return rv;
61 nsresult VideoDocument::StartLayout() {
62 // Create video element, and begin loading the media resource. Note we
63 // delay creating the video element until now (we're called from
64 // MediaDocumentStreamListener::OnStartRequest) as the PresShell is likely
65 // to have been created by now, so the MediaDecoder will be able to tell
66 // what kind of compositor we have, so the video element knows whether
67 // it can create a hardware accelerated video decoder or not.
68 nsresult rv = CreateVideoElement();
69 NS_ENSURE_SUCCESS(rv, rv);
71 rv = MediaDocument::StartLayout();
72 NS_ENSURE_SUCCESS(rv, rv);
74 return NS_OK;
77 void VideoDocument::SetScriptGlobalObject(
78 nsIScriptGlobalObject* aScriptGlobalObject) {
79 // Set the script global object on the superclass before doing
80 // anything that might require it....
81 MediaDocument::SetScriptGlobalObject(aScriptGlobalObject);
83 if (aScriptGlobalObject && !InitialSetupHasBeenDone()) {
84 DebugOnly<nsresult> rv = CreateSyntheticDocument();
85 NS_ASSERTION(NS_SUCCEEDED(rv), "failed to create synthetic video document");
87 if (!nsContentUtils::IsChildOfSameType(this)) {
88 LinkStylesheet(nsLiteralString(
89 u"resource://content-accessible/TopLevelVideoDocument.css"));
90 LinkScript(u"chrome://global/content/TopLevelVideoDocument.js"_ns);
92 InitialSetupDone();
96 nsresult VideoDocument::CreateVideoElement() {
97 RefPtr<Element> body = GetBodyElement();
98 if (!body) {
99 NS_WARNING("no body on video document!");
100 return NS_ERROR_FAILURE;
103 // make content
104 RefPtr<mozilla::dom::NodeInfo> nodeInfo;
105 nodeInfo = mNodeInfoManager->GetNodeInfo(
106 nsGkAtoms::video, nullptr, kNameSpaceID_XHTML, nsINode::ELEMENT_NODE);
108 RefPtr<HTMLMediaElement> element = static_cast<HTMLMediaElement*>(
109 NS_NewHTMLVideoElement(nodeInfo.forget(), NOT_FROM_PARSER));
110 if (!element) return NS_ERROR_OUT_OF_MEMORY;
111 element->SetAutoplay(true, IgnoreErrors());
112 element->SetControls(true, IgnoreErrors());
113 element->LoadWithChannel(mChannel,
114 getter_AddRefs(mStreamListener->mNextStream));
115 UpdateTitle(mChannel);
117 if (nsContentUtils::IsChildOfSameType(this)) {
118 // Video documents that aren't toplevel should fill their frames and
119 // not have margins
120 element->SetAttr(
121 kNameSpaceID_None, nsGkAtoms::style,
122 nsLiteralString(
123 u"position:absolute; top:0; left:0; width:100%; height:100%"),
124 true);
127 ErrorResult rv;
128 body->AppendChildTo(element, false, rv);
129 return rv.StealNSResult();
132 void VideoDocument::UpdateTitle(nsIChannel* aChannel) {
133 if (!aChannel) return;
135 nsAutoString fileName;
136 GetFileName(fileName, aChannel);
137 IgnoredErrorResult ignored;
138 SetTitle(fileName, ignored);
141 } // namespace mozilla::dom
143 nsresult NS_NewVideoDocument(mozilla::dom::Document** aResult,
144 nsIPrincipal* aPrincipal,
145 nsIPrincipal* aPartitionedPrincipal) {
146 auto* doc = new mozilla::dom::VideoDocument();
148 NS_ADDREF(doc);
149 nsresult rv = doc->Init(aPrincipal, aPartitionedPrincipal);
151 if (NS_FAILED(rv)) {
152 NS_RELEASE(doc);
155 *aResult = doc;
157 return rv;