Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/html/VideoDocument.cpp
Line
Count
Source (jump to first uncovered line)
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/. */
6
7
#include "MediaDocument.h"
8
#include "nsGkAtoms.h"
9
#include "nsNodeInfoManager.h"
10
#include "nsContentCreatorFunctions.h"
11
#include "mozilla/dom/HTMLMediaElement.h"
12
#include "nsIDocumentInlines.h"
13
#include "nsContentUtils.h"
14
#include "mozilla/dom/Element.h"
15
16
namespace mozilla {
17
namespace dom {
18
19
class VideoDocument final : public MediaDocument
20
{
21
public:
22
  enum MediaDocumentKind MediaDocumentKind() const override
23
0
  {
24
0
    return MediaDocumentKind::Video;
25
0
  }
26
27
  virtual nsresult StartDocumentLoad(const char*         aCommand,
28
                                     nsIChannel*         aChannel,
29
                                     nsILoadGroup*       aLoadGroup,
30
                                     nsISupports*        aContainer,
31
                                     nsIStreamListener** aDocListener,
32
                                     bool                aReset = true,
33
                                     nsIContentSink*     aSink = nullptr) override;
34
  virtual void SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject) override;
35
36
  virtual void Destroy() override
37
0
  {
38
0
    if (mStreamListener) {
39
0
      mStreamListener->DropDocumentRef();
40
0
    }
41
0
    MediaDocument::Destroy();
42
0
  }
43
44
protected:
45
46
  // Sets document <title> to reflect the file name and description.
47
  void UpdateTitle(nsIChannel* aChannel);
48
49
  nsresult CreateSyntheticVideoDocument();
50
51
  RefPtr<MediaDocumentStreamListener> mStreamListener;
52
};
53
54
nsresult
55
VideoDocument::StartDocumentLoad(const char*         aCommand,
56
                                 nsIChannel*         aChannel,
57
                                 nsILoadGroup*       aLoadGroup,
58
                                 nsISupports*        aContainer,
59
                                 nsIStreamListener** aDocListener,
60
                                 bool                aReset,
61
                                 nsIContentSink*     aSink)
62
0
{
63
0
  nsresult rv =
64
0
    MediaDocument::StartDocumentLoad(aCommand, aChannel, aLoadGroup, aContainer,
65
0
                                     aDocListener, aReset, aSink);
66
0
  NS_ENSURE_SUCCESS(rv, rv);
67
0
68
0
  mStreamListener = new MediaDocumentStreamListener(this);
69
0
  NS_ADDREF(*aDocListener = mStreamListener);
70
0
  return rv;
71
0
}
72
73
void
74
VideoDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject)
75
0
{
76
0
  // Set the script global object on the superclass before doing
77
0
  // anything that might require it....
78
0
  MediaDocument::SetScriptGlobalObject(aScriptGlobalObject);
79
0
80
0
  if (aScriptGlobalObject && !InitialSetupHasBeenDone()) {
81
0
    // Create synthetic document
82
#ifdef DEBUG
83
    nsresult rv =
84
#endif
85
      CreateSyntheticVideoDocument();
86
0
    NS_ASSERTION(NS_SUCCEEDED(rv), "failed to create synthetic video document");
87
0
88
0
    if (!nsContentUtils::IsChildOfSameType(this)) {
89
0
      LinkStylesheet(NS_LITERAL_STRING("resource://content-accessible/TopLevelVideoDocument.css"));
90
0
      LinkStylesheet(NS_LITERAL_STRING("chrome://global/skin/media/TopLevelVideoDocument.css"));
91
0
      LinkScript(NS_LITERAL_STRING("chrome://global/content/TopLevelVideoDocument.js"));
92
0
    }
93
0
    InitialSetupDone();
94
0
  }
95
0
}
96
97
nsresult
98
VideoDocument::CreateSyntheticVideoDocument()
99
0
{
100
0
  // make our generic document
101
0
  nsresult rv = MediaDocument::CreateSyntheticDocument();
102
0
  NS_ENSURE_SUCCESS(rv, rv);
103
0
104
0
  Element* body = GetBodyElement();
105
0
  if (!body) {
106
0
    NS_WARNING("no body on video document!");
107
0
    return NS_ERROR_FAILURE;
108
0
  }
109
0
110
0
  // make content
111
0
  RefPtr<mozilla::dom::NodeInfo> nodeInfo;
112
0
  nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::video, nullptr,
113
0
                                           kNameSpaceID_XHTML,
114
0
                                           nsINode::ELEMENT_NODE);
115
0
116
0
  RefPtr<HTMLMediaElement> element =
117
0
    static_cast<HTMLMediaElement*>(NS_NewHTMLVideoElement(nodeInfo.forget(),
118
0
                                                          NOT_FROM_PARSER));
119
0
  if (!element)
120
0
    return NS_ERROR_OUT_OF_MEMORY;
121
0
  element->SetAutoplay(true, IgnoreErrors());
122
0
  element->SetControls(true, IgnoreErrors());
123
0
  element->LoadWithChannel(mChannel,
124
0
                           getter_AddRefs(mStreamListener->mNextStream));
125
0
  UpdateTitle(mChannel);
126
0
127
0
  if (nsContentUtils::IsChildOfSameType(this)) {
128
0
    // Video documents that aren't toplevel should fill their frames and
129
0
    // not have margins
130
0
    element->SetAttr(kNameSpaceID_None, nsGkAtoms::style,
131
0
        NS_LITERAL_STRING("position:absolute; top:0; left:0; width:100%; height:100%"),
132
0
        true);
133
0
  }
134
0
135
0
  return body->AppendChildTo(element, false);
136
0
}
137
138
void
139
VideoDocument::UpdateTitle(nsIChannel* aChannel)
140
0
{
141
0
  if (!aChannel)
142
0
    return;
143
0
144
0
  nsAutoString fileName;
145
0
  GetFileName(fileName, aChannel);
146
0
  IgnoredErrorResult ignored;
147
0
  SetTitle(fileName, ignored);
148
0
}
149
150
} // namespace dom
151
} // namespace mozilla
152
153
nsresult
154
NS_NewVideoDocument(nsIDocument** aResult)
155
0
{
156
0
  mozilla::dom::VideoDocument* doc = new mozilla::dom::VideoDocument();
157
0
158
0
  NS_ADDREF(doc);
159
0
  nsresult rv = doc->Init();
160
0
161
0
  if (NS_FAILED(rv)) {
162
0
    NS_RELEASE(doc);
163
0
  }
164
0
165
0
  *aResult = doc;
166
0
167
0
  return rv;
168
0
}