LCOV - code coverage report
Current view: top level - dom/html - MediaDocument.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 195 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 23 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 "nsRect.h"
      10             : #include "nsPresContext.h"
      11             : #include "nsIPresShell.h"
      12             : #include "nsIScrollable.h"
      13             : #include "nsViewManager.h"
      14             : #include "nsITextToSubURI.h"
      15             : #include "nsIURL.h"
      16             : #include "nsIContentViewer.h"
      17             : #include "nsIDocShell.h"
      18             : #include "nsCharsetSource.h" // kCharsetFrom* macro definition
      19             : #include "nsNodeInfoManager.h"
      20             : #include "nsContentUtils.h"
      21             : #include "nsDocElementCreatedNotificationRunner.h"
      22             : #include "mozilla/Services.h"
      23             : #include "nsServiceManagerUtils.h"
      24             : #include "nsIPrincipal.h"
      25             : #include "nsIMultiPartChannel.h"
      26             : 
      27             : namespace mozilla {
      28             : namespace dom {
      29             : 
      30           0 : MediaDocumentStreamListener::MediaDocumentStreamListener(MediaDocument *aDocument)
      31             : {
      32           0 :   mDocument = aDocument;
      33           0 : }
      34             : 
      35           0 : MediaDocumentStreamListener::~MediaDocumentStreamListener()
      36             : {
      37           0 : }
      38             : 
      39             : 
      40           0 : NS_IMPL_ISUPPORTS(MediaDocumentStreamListener,
      41             :                   nsIRequestObserver,
      42             :                   nsIStreamListener)
      43             : 
      44             : 
      45             : void
      46           0 : MediaDocumentStreamListener::SetStreamListener(nsIStreamListener *aListener)
      47             : {
      48           0 :   mNextStream = aListener;
      49           0 : }
      50             : 
      51             : NS_IMETHODIMP
      52           0 : MediaDocumentStreamListener::OnStartRequest(nsIRequest* request, nsISupports *ctxt)
      53             : {
      54           0 :   NS_ENSURE_TRUE(mDocument, NS_ERROR_FAILURE);
      55             : 
      56           0 :   mDocument->StartLayout();
      57             : 
      58           0 :   if (mNextStream) {
      59           0 :     return mNextStream->OnStartRequest(request, ctxt);
      60             :   }
      61             : 
      62           0 :   return NS_ERROR_PARSED_DATA_CACHED;
      63             : }
      64             : 
      65             : NS_IMETHODIMP
      66           0 : MediaDocumentStreamListener::OnStopRequest(nsIRequest* request,
      67             :                                            nsISupports *ctxt,
      68             :                                            nsresult status)
      69             : {
      70           0 :   nsresult rv = NS_OK;
      71           0 :   if (mNextStream) {
      72           0 :     rv = mNextStream->OnStopRequest(request, ctxt, status);
      73             :   }
      74             : 
      75             :   // Don't release mDocument here if we're in the middle of a multipart response.
      76           0 :   bool lastPart = true;
      77           0 :   nsCOMPtr<nsIMultiPartChannel> mpchan(do_QueryInterface(request));
      78           0 :   if (mpchan) {
      79           0 :     mpchan->GetIsLastPart(&lastPart);
      80             :   }
      81             : 
      82           0 :   if (lastPart) {
      83           0 :     mDocument = nullptr;
      84             :   }
      85           0 :   return rv;
      86             : }
      87             : 
      88             : NS_IMETHODIMP
      89           0 : MediaDocumentStreamListener::OnDataAvailable(nsIRequest* request,
      90             :                                              nsISupports *ctxt,
      91             :                                              nsIInputStream *inStr,
      92             :                                              uint64_t sourceOffset,
      93             :                                              uint32_t count)
      94             : {
      95           0 :   if (mNextStream) {
      96           0 :     return mNextStream->OnDataAvailable(request, ctxt, inStr, sourceOffset, count);
      97             :   }
      98             : 
      99           0 :   return NS_OK;
     100             : }
     101             : 
     102             : // default format names for MediaDocument.
     103             : const char* const MediaDocument::sFormatNames[4] =
     104             : {
     105             :   "MediaTitleWithNoInfo",    // eWithNoInfo
     106             :   "MediaTitleWithFile",      // eWithFile
     107             :   "",                        // eWithDim
     108             :   ""                         // eWithDimAndFile
     109             : };
     110             : 
     111           0 : MediaDocument::MediaDocument()
     112             :     : nsHTMLDocument(),
     113           0 :       mDocumentElementInserted(false)
     114             : {
     115           0 : }
     116           0 : MediaDocument::~MediaDocument()
     117             : {
     118           0 : }
     119             : 
     120             : nsresult
     121           0 : MediaDocument::Init()
     122             : {
     123           0 :   nsresult rv = nsHTMLDocument::Init();
     124           0 :   NS_ENSURE_SUCCESS(rv, rv);
     125             : 
     126             :   // Create a bundle for the localization
     127             :   nsCOMPtr<nsIStringBundleService> stringService =
     128           0 :     mozilla::services::GetStringBundleService();
     129           0 :   if (stringService) {
     130           0 :     stringService->CreateBundle(NSMEDIADOCUMENT_PROPERTIES_URI,
     131           0 :                                 getter_AddRefs(mStringBundle));
     132             :   }
     133             : 
     134           0 :   mIsSyntheticDocument = true;
     135             : 
     136           0 :   return NS_OK;
     137             : }
     138             : 
     139             : nsresult
     140           0 : MediaDocument::StartDocumentLoad(const char*         aCommand,
     141             :                                  nsIChannel*         aChannel,
     142             :                                  nsILoadGroup*       aLoadGroup,
     143             :                                  nsISupports*        aContainer,
     144             :                                  nsIStreamListener** aDocListener,
     145             :                                  bool                aReset,
     146             :                                  nsIContentSink*     aSink)
     147             : {
     148           0 :   nsresult rv = nsDocument::StartDocumentLoad(aCommand, aChannel, aLoadGroup,
     149             :                                               aContainer, aDocListener, aReset,
     150           0 :                                               aSink);
     151           0 :   if (NS_FAILED(rv)) {
     152           0 :     return rv;
     153             :   }
     154             : 
     155             :   // We try to set the charset of the current document to that of the
     156             :   // 'genuine' (as opposed to an intervening 'chrome') parent document
     157             :   // that may be in a different window/tab. Even if we fail here,
     158             :   // we just return NS_OK because another attempt is made in
     159             :   // |UpdateTitleAndCharset| and the worst thing possible is a mangled
     160             :   // filename in the titlebar and the file picker.
     161             : 
     162             :   // Note that we
     163             :   // exclude UTF-8 as 'invalid' because UTF-8 is likely to be the charset
     164             :   // of a chrome document that has nothing to do with the actual content
     165             :   // whose charset we want to know. Even if "the actual content" is indeed
     166             :   // in UTF-8, we don't lose anything because the default empty value is
     167             :   // considered synonymous with UTF-8.
     168             : 
     169           0 :   nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aContainer));
     170             : 
     171             :   // not being able to set the charset is not critical.
     172           0 :   NS_ENSURE_TRUE(docShell, NS_OK);
     173             : 
     174             :   const Encoding* encoding;
     175             :   int32_t source;
     176           0 :   nsCOMPtr<nsIPrincipal> principal;
     177             :   // opening in a new tab
     178           0 :   docShell->GetParentCharset(encoding, &source, getter_AddRefs(principal));
     179             : 
     180           0 :   if (encoding && encoding != UTF_8_ENCODING &&
     181           0 :       NodePrincipal()->Equals(principal)) {
     182           0 :     SetDocumentCharacterSetSource(source);
     183           0 :     SetDocumentCharacterSet(WrapNotNull(encoding));
     184             :   }
     185             : 
     186           0 :   return NS_OK;
     187             : }
     188             : 
     189             : void
     190           0 : MediaDocument::BecomeInteractive()
     191             : {
     192             :   // Even though our readyState code isn't really reliable, here we pretend
     193             :   // that it is and conclude that we are restoring from the b/f cache if
     194             :   // GetReadyStateEnum() == nsIDocument::READYSTATE_COMPLETE.
     195           0 :   if (GetReadyStateEnum() != nsIDocument::READYSTATE_COMPLETE) {
     196           0 :     MOZ_ASSERT(GetReadyStateEnum() == nsIDocument::READYSTATE_LOADING,
     197             :                "Bad readyState");
     198           0 :     SetReadyStateInternal(nsIDocument::READYSTATE_INTERACTIVE);
     199             :   }
     200           0 : }
     201             : 
     202             : nsresult
     203           0 : MediaDocument::CreateSyntheticDocument()
     204             : {
     205             :   // Synthesize an empty html document
     206             :   nsresult rv;
     207             : 
     208           0 :   RefPtr<mozilla::dom::NodeInfo> nodeInfo;
     209           0 :   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::html, nullptr,
     210             :                                            kNameSpaceID_XHTML,
     211           0 :                                            nsIDOMNode::ELEMENT_NODE);
     212             : 
     213           0 :   RefPtr<nsGenericHTMLElement> root = NS_NewHTMLHtmlElement(nodeInfo.forget());
     214           0 :   NS_ENSURE_TRUE(root, NS_ERROR_OUT_OF_MEMORY);
     215             : 
     216           0 :   NS_ASSERTION(GetChildCount() == 0, "Shouldn't have any kids");
     217           0 :   rv = AppendChildTo(root, false);
     218           0 :   NS_ENSURE_SUCCESS(rv, rv);
     219             : 
     220           0 :   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::head, nullptr,
     221             :                                            kNameSpaceID_XHTML,
     222           0 :                                            nsIDOMNode::ELEMENT_NODE);
     223             : 
     224             :   // Create a <head> so our title has somewhere to live
     225           0 :   RefPtr<nsGenericHTMLElement> head = NS_NewHTMLHeadElement(nodeInfo.forget());
     226           0 :   NS_ENSURE_TRUE(head, NS_ERROR_OUT_OF_MEMORY);
     227             : 
     228           0 :   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::meta, nullptr,
     229             :                                            kNameSpaceID_XHTML,
     230           0 :                                            nsIDOMNode::ELEMENT_NODE);
     231             : 
     232           0 :   RefPtr<nsGenericHTMLElement> metaContent = NS_NewHTMLMetaElement(nodeInfo.forget());
     233           0 :   NS_ENSURE_TRUE(metaContent, NS_ERROR_OUT_OF_MEMORY);
     234           0 :   metaContent->SetAttr(kNameSpaceID_None, nsGkAtoms::name,
     235           0 :                        NS_LITERAL_STRING("viewport"),
     236           0 :                        true);
     237             : 
     238           0 :   metaContent->SetAttr(kNameSpaceID_None, nsGkAtoms::content,
     239           0 :                        NS_LITERAL_STRING("width=device-width; height=device-height;"),
     240           0 :                        true);
     241           0 :   head->AppendChildTo(metaContent, false);
     242             : 
     243           0 :   root->AppendChildTo(head, false);
     244             : 
     245           0 :   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::body, nullptr,
     246             :                                            kNameSpaceID_XHTML,
     247           0 :                                            nsIDOMNode::ELEMENT_NODE);
     248             : 
     249           0 :   RefPtr<nsGenericHTMLElement> body = NS_NewHTMLBodyElement(nodeInfo.forget());
     250           0 :   NS_ENSURE_TRUE(body, NS_ERROR_OUT_OF_MEMORY);
     251             : 
     252           0 :   root->AppendChildTo(body, false);
     253             : 
     254           0 :   return NS_OK;
     255             : }
     256             : 
     257             : nsresult
     258           0 : MediaDocument::StartLayout()
     259             : {
     260           0 :   mMayStartLayout = true;
     261           0 :   nsCOMPtr<nsIPresShell> shell = GetShell();
     262             :   // Don't mess with the presshell if someone has already handled
     263             :   // its initial reflow.
     264           0 :   if (shell && !shell->DidInitialize()) {
     265           0 :     nsRect visibleArea = shell->GetPresContext()->GetVisibleArea();
     266           0 :     nsresult rv = shell->Initialize(visibleArea.width, visibleArea.height);
     267           0 :     NS_ENSURE_SUCCESS(rv, rv);
     268             :   }
     269             : 
     270           0 :   return NS_OK;
     271             : }
     272             : 
     273             : void
     274           0 : MediaDocument::GetFileName(nsAString& aResult, nsIChannel* aChannel)
     275             : {
     276           0 :   aResult.Truncate();
     277             : 
     278           0 :   if (aChannel) {
     279           0 :     aChannel->GetContentDispositionFilename(aResult);
     280           0 :     if (!aResult.IsEmpty())
     281           0 :       return;
     282             :   }
     283             : 
     284           0 :   nsCOMPtr<nsIURL> url = do_QueryInterface(mDocumentURI);
     285           0 :   if (!url)
     286           0 :     return;
     287             : 
     288           0 :   nsAutoCString fileName;
     289           0 :   url->GetFileName(fileName);
     290           0 :   if (fileName.IsEmpty())
     291           0 :     return;
     292             : 
     293           0 :   nsAutoCString docCharset;
     294             :   // Now that the charset is set in |StartDocumentLoad| to the charset of
     295             :   // the document viewer instead of a bogus value ("windows-1252" set in
     296             :   // |nsDocument|'s ctor), the priority is given to the current charset.
     297             :   // This is necessary to deal with a media document being opened in a new
     298             :   // window or a new tab, in which case |originCharset| of |nsIURI| is not
     299             :   // reliable.
     300           0 :   if (mCharacterSetSource != kCharsetUninitialized) {
     301           0 :     mCharacterSet->Name(docCharset);
     302             :   } else {
     303             :     // resort to |originCharset|
     304           0 :     url->GetOriginCharset(docCharset);
     305           0 :     auto encoding = Encoding::ForLabelNoReplacement(docCharset);
     306           0 :     if (encoding) {
     307           0 :       SetDocumentCharacterSet(WrapNotNull(encoding));
     308             :     }
     309             :   }
     310             : 
     311             :   nsresult rv;
     312             :   nsCOMPtr<nsITextToSubURI> textToSubURI =
     313           0 :     do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv);
     314           0 :   if (NS_SUCCEEDED(rv)) {
     315             :     // UnEscapeURIForUI always succeeds
     316           0 :     textToSubURI->UnEscapeURIForUI(docCharset, fileName, aResult);
     317             :   } else {
     318           0 :     CopyUTF8toUTF16(fileName, aResult);
     319             :   }
     320             : }
     321             : 
     322             : nsresult
     323           0 : MediaDocument::LinkStylesheet(const nsAString& aStylesheet)
     324             : {
     325           0 :   RefPtr<mozilla::dom::NodeInfo> nodeInfo;
     326           0 :   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::link, nullptr,
     327             :                                            kNameSpaceID_XHTML,
     328           0 :                                            nsIDOMNode::ELEMENT_NODE);
     329             : 
     330           0 :   RefPtr<nsGenericHTMLElement> link = NS_NewHTMLLinkElement(nodeInfo.forget());
     331           0 :   NS_ENSURE_TRUE(link, NS_ERROR_OUT_OF_MEMORY);
     332             : 
     333           0 :   link->SetAttr(kNameSpaceID_None, nsGkAtoms::rel,
     334           0 :                 NS_LITERAL_STRING("stylesheet"), true);
     335             : 
     336           0 :   link->SetAttr(kNameSpaceID_None, nsGkAtoms::href, aStylesheet, true);
     337             : 
     338           0 :   Element* head = GetHeadElement();
     339           0 :   return head->AppendChildTo(link, false);
     340             : }
     341             : 
     342             : nsresult
     343           0 : MediaDocument::LinkScript(const nsAString& aScript)
     344             : {
     345           0 :   RefPtr<mozilla::dom::NodeInfo> nodeInfo;
     346           0 :   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::script, nullptr,
     347             :                                            kNameSpaceID_XHTML,
     348           0 :                                            nsIDOMNode::ELEMENT_NODE);
     349             : 
     350           0 :   RefPtr<nsGenericHTMLElement> script = NS_NewHTMLScriptElement(nodeInfo.forget());
     351           0 :   NS_ENSURE_TRUE(script, NS_ERROR_OUT_OF_MEMORY);
     352             : 
     353           0 :   script->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
     354           0 :                   NS_LITERAL_STRING("text/javascript"), true);
     355             : 
     356           0 :   script->SetAttr(kNameSpaceID_None, nsGkAtoms::src, aScript, true);
     357             : 
     358           0 :   Element* head = GetHeadElement();
     359           0 :   return head->AppendChildTo(script, false);
     360             : }
     361             : 
     362             : void
     363           0 : MediaDocument::UpdateTitleAndCharset(const nsACString& aTypeStr,
     364             :                                      nsIChannel* aChannel,
     365             :                                      const char* const* aFormatNames,
     366             :                                      int32_t aWidth, int32_t aHeight,
     367             :                                      const nsAString& aStatus)
     368             : {
     369           0 :   nsXPIDLString fileStr;
     370           0 :   GetFileName(fileStr, aChannel);
     371             : 
     372           0 :   NS_ConvertASCIItoUTF16 typeStr(aTypeStr);
     373           0 :   nsXPIDLString title;
     374             : 
     375           0 :   if (mStringBundle) {
     376             :     // if we got a valid size (not all media have a size)
     377           0 :     if (aWidth != 0 && aHeight != 0) {
     378           0 :       nsAutoString widthStr;
     379           0 :       nsAutoString heightStr;
     380           0 :       widthStr.AppendInt(aWidth);
     381           0 :       heightStr.AppendInt(aHeight);
     382             :       // If we got a filename, display it
     383           0 :       if (!fileStr.IsEmpty()) {
     384           0 :         const char16_t *formatStrings[4]  = {fileStr.get(), typeStr.get(),
     385           0 :           widthStr.get(), heightStr.get()};
     386           0 :         NS_ConvertASCIItoUTF16 fmtName(aFormatNames[eWithDimAndFile]);
     387           0 :         mStringBundle->FormatStringFromName(fmtName.get(), formatStrings, 4,
     388           0 :                                             getter_Copies(title));
     389             :       }
     390             :       else {
     391           0 :         const char16_t *formatStrings[3]  = {typeStr.get(), widthStr.get(),
     392           0 :           heightStr.get()};
     393           0 :         NS_ConvertASCIItoUTF16 fmtName(aFormatNames[eWithDim]);
     394           0 :         mStringBundle->FormatStringFromName(fmtName.get(), formatStrings, 3,
     395           0 :                                             getter_Copies(title));
     396           0 :       }
     397             :     }
     398             :     else {
     399             :     // If we got a filename, display it
     400           0 :       if (!fileStr.IsEmpty()) {
     401           0 :         const char16_t *formatStrings[2] = {fileStr.get(), typeStr.get()};
     402           0 :         NS_ConvertASCIItoUTF16 fmtName(aFormatNames[eWithFile]);
     403           0 :         mStringBundle->FormatStringFromName(fmtName.get(), formatStrings, 2,
     404           0 :                                             getter_Copies(title));
     405             :       }
     406             :       else {
     407           0 :         const char16_t *formatStrings[1] = {typeStr.get()};
     408           0 :         NS_ConvertASCIItoUTF16 fmtName(aFormatNames[eWithNoInfo]);
     409           0 :         mStringBundle->FormatStringFromName(fmtName.get(), formatStrings, 1,
     410           0 :                                             getter_Copies(title));
     411             :       }
     412             :     }
     413             :   }
     414             : 
     415             :   // set it on the document
     416           0 :   if (aStatus.IsEmpty()) {
     417           0 :     SetTitle(title);
     418             :   }
     419             :   else {
     420           0 :     nsXPIDLString titleWithStatus;
     421           0 :     const nsPromiseFlatString& status = PromiseFlatString(aStatus);
     422           0 :     const char16_t *formatStrings[2] = {title.get(), status.get()};
     423           0 :     mStringBundle->FormatStringFromName(u"TitleWithStatus", formatStrings, 2,
     424           0 :                                         getter_Copies(titleWithStatus));
     425           0 :     SetTitle(titleWithStatus);
     426             :   }
     427           0 : }
     428             : 
     429             : void
     430           0 : MediaDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aGlobalObject)
     431             : {
     432           0 :     nsHTMLDocument::SetScriptGlobalObject(aGlobalObject);
     433           0 :     if (!mDocumentElementInserted && aGlobalObject) {
     434           0 :         mDocumentElementInserted = true;
     435             :         nsContentUtils::AddScriptRunner(
     436           0 :             new nsDocElementCreatedNotificationRunner(this));
     437             :     }
     438           0 : }
     439             : 
     440             : } // namespace dom
     441             : } // namespace mozilla

Generated by: LCOV version 1.13