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=mystor,mcmanus draft
authorValentin Gosu <valentin.gosu@gmail.com>
Thu, 20 Apr 2017 10:15:06 +0800
changeset 565538 eaebc1f5621df7654b4165929e55544fadbf59e3
parent 562168 ec0e2532c1b00acee8852611a9e4d543ae41c9cb
child 565539 b2c5f8ac671ba1a1acae77dd09e019a76e19555c
push id54903
push uservalentin.gosu@gmail.com
push dateThu, 20 Apr 2017 02:15:38 +0000
reviewersmystor, mcmanus
bugs1354349
milestone55.0a1
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=mystor,mcmanus 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;