Bug 1354349 - Add nsIChannel.isDocument that checks if LOAD_DOCUMENT_URI is set, or if LOAD_HTML_OBJECT_DATA and the channel has the appropriate MIME type r=mcmanus,mystor
authorValentin Gosu <valentin.gosu@gmail.com>
Thu, 20 Apr 2017 10:15:06 +0800
changeset 354024 b01181410a8a8dcc757f39fad165d22e927ef3c0
parent 354023 b06e3d6c2f783a505108f677fa773fc60f2cc2bb
child 354025 8a42c7e1f799ea8c48aaa4166764ce681b9ad523
push id31685
push userkwierso@gmail.com
push dateThu, 20 Apr 2017 21:45:29 +0000
treeherdermozilla-central@5e3dc7e1288a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmcmanus, mystor
bugs1354349
milestone55.0a1
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
Bug 1354349 - Add nsIChannel.isDocument that checks if LOAD_DOCUMENT_URI is set, or if LOAD_HTML_OBJECT_DATA and the channel has the appropriate MIME type r=mcmanus,mystor MozReview-Commit-ID: K28Opd9JTr2
dom/ipc/TabParent.cpp
dom/jsurl/nsJSProtocolHandler.cpp
image/decoders/icon/mac/nsIconChannel.h
image/decoders/icon/mac/nsIconChannelCocoa.mm
image/decoders/icon/win/nsIconChannel.cpp
modules/libjar/nsJARChannel.cpp
netwerk/base/nsBaseChannel.cpp
netwerk/base/nsIChannel.idl
netwerk/base/nsNetUtil.cpp
netwerk/base/nsNetUtil.h
netwerk/protocol/about/nsAboutCache.h
netwerk/protocol/http/HttpBaseChannel.cpp
netwerk/protocol/http/HttpBaseChannel.h
netwerk/protocol/http/NullHttpChannel.cpp
netwerk/protocol/http/nsIHttpChannel.idl
netwerk/protocol/viewsource/nsViewSourceChannel.cpp
netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp
netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp
netwerk/streamconv/converters/nsMultiMixedConv.cpp
uriloader/exthandler/ExternalHelperAppParent.cpp
uriloader/exthandler/nsExternalProtocolHandler.cpp
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -2951,16 +2951,17 @@ public:
   NS_IMETHOD GetStatus(nsresult*) NO_IMPL
   NS_IMETHOD Cancel(nsresult) NO_IMPL
   NS_IMETHOD Suspend() NO_IMPL
   NS_IMETHOD Resume() NO_IMPL
   NS_IMETHOD GetLoadGroup(nsILoadGroup**) NO_IMPL
   NS_IMETHOD SetLoadGroup(nsILoadGroup*) NO_IMPL
   NS_IMETHOD SetLoadFlags(nsLoadFlags) NO_IMPL
   NS_IMETHOD GetLoadFlags(nsLoadFlags*) NO_IMPL
+  NS_IMETHOD GetIsDocument(bool *) NO_IMPL
   NS_IMETHOD GetOriginalURI(nsIURI**) NO_IMPL
   NS_IMETHOD SetOriginalURI(nsIURI*) NO_IMPL
   NS_IMETHOD GetURI(nsIURI** aUri) override
   {
     nsCOMPtr<nsIURI> copy = mUri;
     copy.forget(aUri);
     return NS_OK;
   }
--- a/dom/jsurl/nsJSProtocolHandler.cpp
+++ b/dom/jsurl/nsJSProtocolHandler.cpp
@@ -437,16 +437,22 @@ nsresult nsJSChannel::Init(nsIURI* aURI,
             writableBag->SetPropertyAsInterface(NS_LITERAL_STRING("baseURI"),
                                                 jsURI->GetBaseURI());
         }
     }
 
     return rv;
 }
 
+NS_IMETHODIMP
+nsJSChannel::GetIsDocument(bool *aIsDocument)
+{
+  return NS_GetIsDocumentChannel(this, aIsDocument);
+}
+
 //
 // nsISupports implementation...
 //
 
 NS_IMPL_ISUPPORTS(nsJSChannel, nsIChannel, nsIRequest, nsIRequestObserver,
                   nsIStreamListener, nsIScriptChannel, nsIPropertyBag,
                   nsIPropertyBag2)
 
--- a/image/decoders/icon/mac/nsIconChannel.h
+++ b/image/decoders/icon/mac/nsIconChannel.h
@@ -14,16 +14,17 @@
 #include "nsIChannel.h"
 #include "nsILoadGroup.h"
 #include "nsILoadInfo.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIInputStreamPump.h"
 #include "nsIStreamListener.h"
 #include "nsIURI.h"
+#include "nsNetUtil.h"
 
 class nsIFile;
 
 class nsIconChannel final : public nsIChannel, public nsIStreamListener
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIREQUEST
--- a/image/decoders/icon/mac/nsIconChannelCocoa.mm
+++ b/image/decoders/icon/mac/nsIconChannelCocoa.mm
@@ -22,16 +22,17 @@
 #include "nsIMIMEService.h"
 #include "nsCExternalHandlerService.h"
 #include "nsILocalFileMac.h"
 #include "nsIFileURL.h"
 #include "nsTArray.h"
 #include "nsObjCExceptions.h"
 #include "nsProxyRelease.h"
 #include "nsContentSecurityManager.h"
+#include "nsNetUtil.h"
 
 #include <Cocoa/Cocoa.h>
 
 // nsIconChannel methods
 nsIconChannel::nsIconChannel()
 {
 }
 
@@ -425,16 +426,22 @@ nsIconChannel::GetLoadFlags(uint32_t* aL
 
 NS_IMETHODIMP
 nsIconChannel::SetLoadFlags(uint32_t aLoadAttributes)
 {
   return mPump->SetLoadFlags(aLoadAttributes);
 }
 
 NS_IMETHODIMP
+nsIconChannel::GetIsDocument(bool *aIsDocument)
+{
+  return NS_GetIsDocumentChannel(this, aIsDocument);
+}
+
+NS_IMETHODIMP
 nsIconChannel::GetContentType(nsACString& aContentType)
 {
   aContentType.AssignLiteral(IMAGE_ICON_MS);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsIconChannel::SetContentType(const nsACString& aContentType)
--- a/image/decoders/icon/win/nsIconChannel.cpp
+++ b/image/decoders/icon/win/nsIconChannel.cpp
@@ -23,16 +23,17 @@
 #include "nsIFile.h"
 #include "nsIFileURL.h"
 #include "nsIMIMEService.h"
 #include "nsCExternalHandlerService.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsProxyRelease.h"
 #include "nsContentSecurityManager.h"
 #include "nsContentUtils.h"
+#include "nsNetUtil.h"
 
 // we need windows.h to read out registry information...
 #include <windows.h>
 #include <shellapi.h>
 #include <shlobj.h>
 #include <objbase.h>
 #include <wchar.h>
 
@@ -152,16 +153,22 @@ nsIconChannel::GetLoadFlags(uint32_t* aL
 }
 
 NS_IMETHODIMP
 nsIconChannel::SetLoadFlags(uint32_t aLoadAttributes)
 {
   return mPump->SetLoadFlags(aLoadAttributes);
 }
 
+NS_IMETHODIMP
+nsIconChannel::GetIsDocument(bool *aIsDocument)
+{
+  return NS_GetIsDocumentChannel(this, aIsDocument);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // nsIChannel methods:
 
 NS_IMETHODIMP
 nsIconChannel::GetOriginalURI(nsIURI** aURI)
 {
   *aURI = mOriginalURI;
   NS_ADDREF(*aURI);
--- a/modules/libjar/nsJARChannel.cpp
+++ b/modules/libjar/nsJARChannel.cpp
@@ -482,16 +482,22 @@ nsJARChannel::GetLoadFlags(nsLoadFlags *
 NS_IMETHODIMP
 nsJARChannel::SetLoadFlags(nsLoadFlags aLoadFlags)
 {
     mLoadFlags = aLoadFlags;
     return NS_OK;
 }
 
 NS_IMETHODIMP
+nsJARChannel::GetIsDocument(bool *aIsDocument)
+{
+    return NS_GetIsDocumentChannel(this, aIsDocument);
+}
+
+NS_IMETHODIMP
 nsJARChannel::GetLoadGroup(nsILoadGroup **aLoadGroup)
 {
     NS_IF_ADDREF(*aLoadGroup = mLoadGroup);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsJARChannel::SetLoadGroup(nsILoadGroup *aLoadGroup)
--- a/netwerk/base/nsBaseChannel.cpp
+++ b/netwerk/base/nsBaseChannel.cpp
@@ -499,16 +499,22 @@ nsBaseChannel::SetLoadInfo(nsILoadInfo* 
 NS_IMETHODIMP
 nsBaseChannel::GetLoadInfo(nsILoadInfo** aLoadInfo)
 {
   NS_IF_ADDREF(*aLoadInfo = mLoadInfo);
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsBaseChannel::GetIsDocument(bool *aIsDocument)
+{
+  return NS_GetIsDocumentChannel(this, aIsDocument);
+}
+
+NS_IMETHODIMP
 nsBaseChannel::GetNotificationCallbacks(nsIInterfaceRequestor **aCallbacks)
 {
   NS_IF_ADDREF(*aCallbacks = mCallbacks);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsBaseChannel::SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks)
--- a/netwerk/base/nsIChannel.idl
+++ b/netwerk/base/nsIChannel.idl
@@ -203,16 +203,19 @@ interface nsIChannel : nsIRequest
      *
      * Bits 26-31 are reserved for future use by this interface or one of its
      * derivatives (e.g., see nsICachingChannel).
      */
 
     /**
      * Set (e.g., by the docshell) to indicate whether or not the channel
      * corresponds to a document URI.
+     * While setting this flag is sufficient to mark a channel as a document
+     * load, _checking_ whether the channel is a document load requires the use
+     * of the new channel.isDocument
      */
     const unsigned long LOAD_DOCUMENT_URI = 1 << 16;
 
     /** 
      * If the end consumer for this load has been retargeted after discovering 
      * its content, this flag will be set:
      */
     const unsigned long LOAD_RETARGETED_DOCUMENT_URI = 1 << 17;
@@ -339,17 +342,36 @@ interface nsIChannel : nsIRequest
      * If a network request is redirected, the new channel will receive a new
      * LoadInfo object. The new object will contain mostly the same
      * information as the pre-redirect one, but updated as appropriate.
      * For detailed information about what parts of LoadInfo are updated on
      * redirect, see documentation on individual properties.
      */
     attribute nsILoadInfo loadInfo;
 
+    /**
+     * Returns true if the channel is used to create a document.
+     * It returns true if the loadFlags have LOAD_DOCUMENT_URI set, or if
+     * LOAD_HTML_OBJECT_DATA is set and the channel has the appropriate
+     * MIME type.
+     * Note: May have the wrong value if called before OnStartRequest as we
+     * don't know the MIME type yet.
+     */
+    readonly attribute bool isDocument;
+
 %{ C++
+  inline bool IsDocument()
+  {
+    bool isDocument = false;
+    if (NS_SUCCEEDED(GetIsDocument(&isDocument)) && isDocument) {
+      return true;
+    }
+    return false;
+  }
+
   inline already_AddRefed<nsILoadInfo> GetLoadInfo()
   {
     nsCOMPtr<nsILoadInfo> result;
     mozilla::DebugOnly<nsresult> rv = GetLoadInfo(getter_AddRefs(result));
     MOZ_ASSERT(NS_SUCCEEDED(rv) || !result);
     return result.forget();
   }
 %}
--- a/netwerk/base/nsNetUtil.cpp
+++ b/netwerk/base/nsNetUtil.cpp
@@ -31,16 +31,17 @@
 #include "nsIIDNService.h"
 #include "nsIInputStreamChannel.h"
 #include "nsIInputStreamPump.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsILoadContext.h"
 #include "nsIMIMEHeaderParam.h"
 #include "nsIMutable.h"
 #include "nsINode.h"
+#include "nsIObjectLoadingContent.h"
 #include "nsIOfflineCacheUpdate.h"
 #include "nsIPersistentProperties2.h"
 #include "nsIPrivateBrowsingChannel.h"
 #include "nsIPropertyBag2.h"
 #include "nsIProtocolProxyService.h"
 #include "nsIRedirectChannelRegistrar.h"
 #include "nsIRequestObserverProxy.h"
 #include "nsIScriptSecurityManager.h"
@@ -353,16 +354,55 @@ NS_NewChannel(nsIChannel           **out
                                aContentPolicyType,
                                aLoadGroup,
                                aCallbacks,
                                aLoadFlags,
                                aIoService);
 }
 
 nsresult
+NS_GetIsDocumentChannel(nsIChannel * aChannel, bool *aIsDocument)
+{
+  // Check if this channel is going to be used to create a document. If it has
+  // LOAD_DOCUMENT_URI set it is trivially creating a document. If
+  // LOAD_HTML_OBJECT_DATA is set it may or may not be used to create a
+  // document, depending on its MIME type.
+
+  *aIsDocument = false;
+  if (!aChannel || !aIsDocument) {
+      return NS_ERROR_NULL_POINTER;
+  }
+  nsLoadFlags loadFlags;
+  nsresult rv = aChannel->GetLoadFlags(&loadFlags);
+  if (NS_FAILED(rv)) {
+      return rv;
+  }
+  if (loadFlags & nsIChannel::LOAD_DOCUMENT_URI) {
+      *aIsDocument = true;
+      return NS_OK;
+  }
+  if (!(loadFlags & nsIRequest::LOAD_HTML_OBJECT_DATA)) {
+      *aIsDocument = false;
+      return NS_OK;
+  }
+  nsAutoCString mimeType;
+  rv = aChannel->GetContentType(mimeType);
+  if (NS_FAILED(rv)) {
+      return rv;
+  }
+  if (nsContentUtils::HtmlObjectContentTypeForMIMEType(mimeType, nullptr) ==
+      nsIObjectLoadingContent::TYPE_DOCUMENT) {
+      *aIsDocument = true;
+      return NS_OK;
+  }
+  *aIsDocument = false;
+  return NS_OK;
+}
+
+nsresult
 NS_MakeAbsoluteURI(nsACString       &result,
                    const nsACString &spec,
                    nsIURI           *baseURI)
 {
     nsresult rv;
     if (!baseURI) {
         NS_WARNING("It doesn't make sense to not supply a base URI");
         result = spec;
--- a/netwerk/base/nsNetUtil.h
+++ b/netwerk/base/nsNetUtil.h
@@ -185,16 +185,18 @@ NS_NewChannel(nsIChannel           **out
               nsIPrincipal          *aLoadingPrincipal,
               nsSecurityFlags        aSecurityFlags,
               nsContentPolicyType    aContentPolicyType,
               nsILoadGroup          *aLoadGroup = nullptr,
               nsIInterfaceRequestor *aCallbacks = nullptr,
               nsLoadFlags            aLoadFlags = nsIRequest::LOAD_NORMAL,
               nsIIOService          *aIoService = nullptr);
 
+nsresult NS_GetIsDocumentChannel(nsIChannel * aChannel, bool *aIsDocument);
+
 nsresult NS_MakeAbsoluteURI(nsACString       &result,
                             const nsACString &spec,
                             nsIURI           *baseURI);
 
 nsresult NS_MakeAbsoluteURI(char        **result,
                             const char   *spec,
                             nsIURI       *baseURI);
 
--- a/netwerk/protocol/about/nsAboutCache.h
+++ b/netwerk/protocol/about/nsAboutCache.h
@@ -34,16 +34,17 @@
   NS_IMETHOD SetContentLength(int64_t aContentLength) override { return !_to ? NS_ERROR_NULL_POINTER : _to->SetContentLength(aContentLength); } \
   NS_IMETHOD GetContentDisposition(uint32_t *aContentDisposition) override { return !_to ? NS_ERROR_NULL_POINTER : _to->GetContentDisposition(aContentDisposition); } \
   NS_IMETHOD SetContentDisposition(uint32_t aContentDisposition) override { return !_to ? NS_ERROR_NULL_POINTER : _to->SetContentDisposition(aContentDisposition); } \
   NS_IMETHOD GetContentDispositionFilename(nsAString & aContentDispositionFilename) override { return !_to ? NS_ERROR_NULL_POINTER : _to->GetContentDispositionFilename(aContentDispositionFilename); } \
   NS_IMETHOD SetContentDispositionFilename(const nsAString & aContentDispositionFilename) override { return !_to ? NS_ERROR_NULL_POINTER : _to->SetContentDispositionFilename(aContentDispositionFilename); } \
   NS_IMETHOD GetContentDispositionHeader(nsACString & aContentDispositionHeader) override { return !_to ? NS_ERROR_NULL_POINTER : _to->GetContentDispositionHeader(aContentDispositionHeader); } \
   NS_IMETHOD GetLoadInfo(nsILoadInfo * *aLoadInfo) override { return !_to ? NS_ERROR_NULL_POINTER : _to->GetLoadInfo(aLoadInfo); } \
   NS_IMETHOD SetLoadInfo(nsILoadInfo *aLoadInfo) override { return !_to ? NS_ERROR_NULL_POINTER : _to->SetLoadInfo(aLoadInfo); } \
+  NS_IMETHOD GetIsDocument(bool *aIsDocument) override { return !_to ? NS_ERROR_NULL_POINTER : _to->GetIsDocument(aIsDocument); }; \
 
 class nsAboutCache final : public nsIAboutModule
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIABOUTMODULE
 
     nsAboutCache() {}
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -531,16 +531,22 @@ HttpBaseChannel::SetLoadInfo(nsILoadInfo
 NS_IMETHODIMP
 HttpBaseChannel::GetLoadInfo(nsILoadInfo **aLoadInfo)
 {
   NS_IF_ADDREF(*aLoadInfo = mLoadInfo);
   return NS_OK;
 }
 
 NS_IMETHODIMP
+HttpBaseChannel::GetIsDocument(bool *aIsDocument)
+{
+  return NS_GetIsDocumentChannel(this, aIsDocument);
+}
+
+NS_IMETHODIMP
 HttpBaseChannel::GetNotificationCallbacks(nsIInterfaceRequestor **aCallbacks)
 {
   *aCallbacks = mCallbacks;
   NS_IF_ADDREF(*aCallbacks);
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/netwerk/protocol/http/HttpBaseChannel.h
+++ b/netwerk/protocol/http/HttpBaseChannel.h
@@ -130,16 +130,17 @@ public:
   // nsIChannel
   NS_IMETHOD GetOriginalURI(nsIURI **aOriginalURI) override;
   NS_IMETHOD SetOriginalURI(nsIURI *aOriginalURI) override;
   NS_IMETHOD GetURI(nsIURI **aURI) override;
   NS_IMETHOD GetOwner(nsISupports **aOwner) override;
   NS_IMETHOD SetOwner(nsISupports *aOwner) override;
   NS_IMETHOD GetLoadInfo(nsILoadInfo **aLoadInfo) override;
   NS_IMETHOD SetLoadInfo(nsILoadInfo *aLoadInfo) override;
+  NS_IMETHOD GetIsDocument(bool *aIsDocument) override;
   NS_IMETHOD GetNotificationCallbacks(nsIInterfaceRequestor **aCallbacks) override;
   NS_IMETHOD SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks) override;
   NS_IMETHOD GetContentType(nsACString& aContentType) override;
   NS_IMETHOD SetContentType(const nsACString& aContentType) override;
   NS_IMETHOD GetContentCharset(nsACString& aContentCharset) override;
   NS_IMETHOD SetContentCharset(const nsACString& aContentCharset) override;
   NS_IMETHOD GetContentDisposition(uint32_t *aContentDisposition) override;
   NS_IMETHOD SetContentDisposition(uint32_t aContentDisposition) override;
--- a/netwerk/protocol/http/NullHttpChannel.cpp
+++ b/netwerk/protocol/http/NullHttpChannel.cpp
@@ -534,16 +534,22 @@ NullHttpChannel::GetLoadFlags(nsLoadFlag
 }
 
 NS_IMETHODIMP
 NullHttpChannel::SetLoadFlags(nsLoadFlags aLoadFlags)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
+NS_IMETHODIMP
+NullHttpChannel::GetIsDocument(bool *aIsDocument)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
 //-----------------------------------------------------------------------------
 // NullHttpChannel::nsITimedChannel
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 NullHttpChannel::GetTimingEnabled(bool *aTimingEnabled)
 {
   *aTimingEnabled = true;
--- a/netwerk/protocol/http/nsIHttpChannel.idl
+++ b/netwerk/protocol/http/nsIHttpChannel.idl
@@ -281,17 +281,17 @@ interface nsIHttpChannel : nsIChannel
      *
      * @throws NS_ERROR_NOT_AVAILABLE if called before the response
      *         has been received (before onStartRequest).
      */
     [must_use] readonly attribute boolean requestSucceeded;
 
    /** Indicates whether channel should be treated as the main one for the
     *  current document.  If manually set to true, will always remain true.  Otherwise,
-    *  will be true iff LOAD_DOCUMENT_URI is set in the channel's loadflags.
+    *  will be true if LOAD_DOCUMENT_URI is set in the channel's loadflags.
     */
     [must_use] attribute boolean isMainDocumentChannel;
 
     /**
      * Get the value of a particular response header.
      *
      * @param aHeader
      *        The case-insensitive name of the response header to query (e.g.,
--- a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
+++ b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
@@ -569,16 +569,24 @@ NS_IMETHODIMP
 nsViewSourceChannel::SetLoadInfo(nsILoadInfo* aLoadInfo)
 {
     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
 
     return mChannel->SetLoadInfo(aLoadInfo);
 }
 
 NS_IMETHODIMP
+nsViewSourceChannel::GetIsDocument(bool *aIsDocument)
+{
+    NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
+
+    return mChannel->GetIsDocument(aIsDocument);
+}
+
+NS_IMETHODIMP
 nsViewSourceChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
 {
     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
 
     return mChannel->GetNotificationCallbacks(aNotificationCallbacks);
 }
 
 NS_IMETHODIMP
--- a/netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp
+++ b/netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp
@@ -489,16 +489,22 @@ WyciwygChannelChild::GetLoadInfo(nsILoad
 NS_IMETHODIMP
 WyciwygChannelChild::SetLoadInfo(nsILoadInfo* aLoadInfo)
 {
   mLoadInfo = aLoadInfo;
   return NS_OK;
 }
 
 NS_IMETHODIMP
+WyciwygChannelChild::GetIsDocument(bool *aIsDocument)
+{
+  return NS_GetIsDocumentChannel(this, aIsDocument);
+}
+
+NS_IMETHODIMP
 WyciwygChannelChild::GetNotificationCallbacks(nsIInterfaceRequestor * *aCallbacks)
 {
   *aCallbacks = mCallbacks;
   NS_IF_ADDREF(*aCallbacks);
   return NS_OK;
 }
 NS_IMETHODIMP
 WyciwygChannelChild::SetNotificationCallbacks(nsIInterfaceRequestor * aCallbacks)
--- a/netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp
+++ b/netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp
@@ -161,16 +161,22 @@ nsWyciwygChannel::SetLoadFlags(uint32_t 
 
 NS_IMETHODIMP
 nsWyciwygChannel::GetLoadFlags(uint32_t * aLoadFlags)
 {
   *aLoadFlags = mLoadFlags;
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsWyciwygChannel::GetIsDocument(bool *aIsDocument)
+{
+  return NS_GetIsDocumentChannel(this, aIsDocument);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // nsIChannel methods:
 ///////////////////////////////////////////////////////////////////////////////
 
 NS_IMETHODIMP
 nsWyciwygChannel::GetOriginalURI(nsIURI* *aURI)
 {
   *aURI = mOriginalURI;
--- a/netwerk/streamconv/converters/nsMultiMixedConv.cpp
+++ b/netwerk/streamconv/converters/nsMultiMixedConv.cpp
@@ -223,16 +223,22 @@ nsPartChannel::GetLoadFlags(nsLoadFlags 
 NS_IMETHODIMP
 nsPartChannel::SetLoadFlags(nsLoadFlags aLoadFlags)
 {
     mLoadFlags = aLoadFlags;
     return NS_OK;
 }
 
 NS_IMETHODIMP
+nsPartChannel::GetIsDocument(bool *aIsDocument)
+{
+    return NS_GetIsDocumentChannel(this, aIsDocument);
+}
+
+NS_IMETHODIMP
 nsPartChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
 {
     *aLoadGroup = mLoadGroup;
     NS_IF_ADDREF(*aLoadGroup);
 
     return NS_OK;
 }
 
--- a/uriloader/exthandler/ExternalHelperAppParent.cpp
+++ b/uriloader/exthandler/ExternalHelperAppParent.cpp
@@ -346,16 +346,22 @@ ExternalHelperAppParent::GetLoadFlags(ns
 NS_IMETHODIMP
 ExternalHelperAppParent::SetLoadFlags(nsLoadFlags aLoadFlags)
 {
   mLoadFlags = aLoadFlags;
   return NS_OK;
 }
 
 NS_IMETHODIMP
+ExternalHelperAppParent::GetIsDocument(bool *aIsDocument)
+{
+  return NS_GetIsDocumentChannel(this, aIsDocument);
+}
+
+NS_IMETHODIMP
 ExternalHelperAppParent::GetLoadGroup(nsILoadGroup* *aLoadGroup)
 {
   *aLoadGroup = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 ExternalHelperAppParent::SetLoadGroup(nsILoadGroup* aLoadGroup)
--- a/uriloader/exthandler/nsExternalProtocolHandler.cpp
+++ b/uriloader/exthandler/nsExternalProtocolHandler.cpp
@@ -240,16 +240,21 @@ NS_IMETHODIMP nsExtProtocolChannel::GetL
 }
 
 NS_IMETHODIMP nsExtProtocolChannel::SetLoadFlags(nsLoadFlags aLoadFlags)
 {
   mLoadFlags = aLoadFlags;
   return NS_OK;
 }
 
+NS_IMETHODIMP nsExtProtocolChannel::GetIsDocument(bool *aIsDocument)
+{
+  return NS_GetIsDocumentChannel(this, aIsDocument);
+}
+
 NS_IMETHODIMP nsExtProtocolChannel::GetContentType(nsACString &aContentType)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP nsExtProtocolChannel::SetContentType(const nsACString &aContentType)
 {
   return NS_ERROR_FAILURE;