Bug 883968. Give <object>/<embed>/<applet> channels notification callbacks that can actually be used from script. r=johns
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 19 Jun 2013 10:24:37 -0400
changeset 135956 798c709e591fd4000f80eb90e9d98a74fc7b1dc5
parent 135955 aa768b37b1c8ff88b30ba1913534a94177efaef1
child 135957 192cecc0111e5a7c30fe2a0c83aed53d444dce91
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersjohns
bugs883968
milestone24.0a1
Bug 883968. Give <object>/<embed>/<applet> channels notification callbacks that can actually be used from script. r=johns
content/base/src/nsObjectLoadingContent.cpp
content/base/src/nsObjectLoadingContent.h
content/html/content/src/HTMLObjectElement.cpp
content/html/content/src/HTMLSharedObjectElement.cpp
content/html/content/test/test_bug389797.html
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -1056,18 +1056,50 @@ NS_IMETHODIMP
 nsObjectLoadingContent::GetContentTypeForMIMEType(const nsACString& aMIMEType,
                                                   uint32_t* aType)
 {
   *aType = GetTypeOfContent(PromiseFlatCString(aMIMEType));
   return NS_OK;
 }
 
 // nsIInterfaceRequestor
+// We use a shim class to implement this so that JS consumers still
+// see an interface requestor even though WebIDL bindings don't expose
+// that stuff.
+class ObjectInterfaceRequestorShim MOZ_FINAL : public nsIInterfaceRequestor,
+                                               public nsIChannelEventSink
+{
+public:
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(ObjectInterfaceRequestorShim,
+                                           nsIInterfaceRequestor)
+  NS_DECL_NSIINTERFACEREQUESTOR
+  NS_FORWARD_NSICHANNELEVENTSINK(mContent->)
+
+  ObjectInterfaceRequestorShim(nsIChannelEventSink* aContent)
+    : mContent(aContent)
+  {}
+
+protected:
+  nsRefPtr<nsIChannelEventSink> mContent;
+};
+
+NS_IMPL_CYCLE_COLLECTION_1(ObjectInterfaceRequestorShim, mContent)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ObjectInterfaceRequestorShim)
+  NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
+  NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInterfaceRequestor)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(ObjectInterfaceRequestorShim)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(ObjectInterfaceRequestorShim)
+
 NS_IMETHODIMP
-nsObjectLoadingContent::GetInterface(const nsIID & aIID, void **aResult)
+ObjectInterfaceRequestorShim::GetInterface(const nsIID & aIID, void **aResult)
 {
   if (aIID.Equals(NS_GET_IID(nsIChannelEventSink))) {
     nsIChannelEventSink* sink = this;
     *aResult = sink;
     NS_ADDREF(sink);
     return NS_OK;
   }
   return NS_NOINTERFACE;
@@ -2074,17 +2106,19 @@ nsObjectLoadingContent::OpenChannel()
   nsCOMPtr<nsIContentSecurityPolicy> csp;
   rv = doc->NodePrincipal()->GetCsp(getter_AddRefs(csp));
   NS_ENSURE_SUCCESS(rv, rv);
   if (csp) {
     channelPolicy = do_CreateInstance("@mozilla.org/nschannelpolicy;1");
     channelPolicy->SetContentSecurityPolicy(csp);
     channelPolicy->SetLoadType(nsIContentPolicy::TYPE_OBJECT);
   }
-  rv = NS_NewChannel(getter_AddRefs(chan), mURI, nullptr, group, this,
+  nsRefPtr<ObjectInterfaceRequestorShim> shim =
+    new ObjectInterfaceRequestorShim(this);
+  rv = NS_NewChannel(getter_AddRefs(chan), mURI, nullptr, group, shim,
                      nsIChannel::LOAD_CALL_CONTENT_SNIFFERS |
                      nsIChannel::LOAD_CLASSIFY_URI,
                      channelPolicy);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Referrer
   nsCOMPtr<nsIHttpChannel> httpChan(do_QueryInterface(chan));
   if (httpChan) {
--- a/content/base/src/nsObjectLoadingContent.h
+++ b/content/base/src/nsObjectLoadingContent.h
@@ -11,17 +11,16 @@
  */
 
 #ifndef NSOBJECTLOADINGCONTENT_H_
 #define NSOBJECTLOADINGCONTENT_H_
 
 #include "mozilla/Attributes.h"
 #include "nsImageLoadingContent.h"
 #include "nsIStreamListener.h"
-#include "nsIInterfaceRequestor.h"
 #include "nsIChannelEventSink.h"
 #include "nsIObjectLoadingContent.h"
 #include "nsIRunnable.h"
 #include "nsPluginInstanceOwner.h"
 #include "nsIThreadInternal.h"
 #include "nsIFrame.h"
 #include "nsIFrameLoader.h"
 
@@ -31,17 +30,16 @@ class AutoSetInstantiatingToFalse;
 class nsObjectFrame;
 class nsFrameLoader;
 class nsXULElement;
 
 class nsObjectLoadingContent : public nsImageLoadingContent
                              , public nsIStreamListener
                              , public nsIFrameLoaderOwner
                              , public nsIObjectLoadingContent
-                             , public nsIInterfaceRequestor
                              , public nsIChannelEventSink
 {
   friend class AutoSetInstantiatingToFalse;
   friend class AutoSetLoadingToFalse;
   friend class CheckPluginStopEvent;
   friend class nsStopPluginRunnable;
   friend class nsAsyncInstantiateEvent;
 
@@ -95,17 +93,16 @@ class nsObjectLoadingContent : public ns
 
     nsObjectLoadingContent();
     virtual ~nsObjectLoadingContent();
 
     NS_DECL_NSIREQUESTOBSERVER
     NS_DECL_NSISTREAMLISTENER
     NS_DECL_NSIFRAMELOADEROWNER
     NS_DECL_NSIOBJECTLOADINGCONTENT
-    NS_DECL_NSIINTERFACEREQUESTOR
     NS_DECL_NSICHANNELEVENTSINK
 
     /**
      * Object state. This is a bitmask of NS_EVENT_STATEs epresenting the
      * current state of the object.
      */
     nsEventStates ObjectState() const;
 
--- a/content/html/content/src/HTMLObjectElement.cpp
+++ b/content/html/content/src/HTMLObjectElement.cpp
@@ -75,26 +75,25 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_IN
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mValidity)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_ADDREF_INHERITED(HTMLObjectElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLObjectElement, Element)
 
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLObjectElement)
   NS_HTML_CONTENT_INTERFACES(nsGenericHTMLFormElement)
-  NS_INTERFACE_TABLE_INHERITED11(HTMLObjectElement,
+  NS_INTERFACE_TABLE_INHERITED10(HTMLObjectElement,
                                  nsIDOMHTMLObjectElement,
                                  imgINotificationObserver,
                                  nsIRequestObserver,
                                  nsIStreamListener,
                                  nsIFrameLoaderOwner,
                                  nsIObjectLoadingContent,
                                  nsIImageLoadingContent,
                                  imgIOnloadBlocker,
-                                 nsIInterfaceRequestor,
                                  nsIChannelEventSink,
                                  nsIConstraintValidation)
   NS_INTERFACE_TABLE_TO_MAP_SEGUE
 NS_ELEMENT_INTERFACE_MAP_END
 
 NS_IMPL_ELEMENT_CLONE(HTMLObjectElement)
 
 // nsIConstraintValidation
--- a/content/html/content/src/HTMLSharedObjectElement.cpp
+++ b/content/html/content/src/HTMLSharedObjectElement.cpp
@@ -88,25 +88,24 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_ADDREF_INHERITED(HTMLSharedObjectElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLSharedObjectElement, Element)
 
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLSharedObjectElement)
   NS_HTML_CONTENT_INTERFACES_AMBIGUOUS(nsGenericHTMLElement,
                                        nsIDOMHTMLAppletElement)
-  NS_INTERFACE_TABLE_INHERITED9(HTMLSharedObjectElement,
+  NS_INTERFACE_TABLE_INHERITED8(HTMLSharedObjectElement,
                                 nsIRequestObserver,
                                 nsIStreamListener,
                                 nsIFrameLoaderOwner,
                                 nsIObjectLoadingContent,
                                 imgINotificationObserver,
                                 nsIImageLoadingContent,
                                 imgIOnloadBlocker,
-                                nsIInterfaceRequestor,
                                 nsIChannelEventSink)
   NS_INTERFACE_TABLE_TO_MAP_SEGUE
   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLAppletElement, applet)
   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLEmbedElement, embed)
 NS_ELEMENT_INTERFACE_MAP_END
 
 NS_IMPL_ELEMENT_CLONE(HTMLSharedObjectElement)
 
--- a/content/html/content/test/test_bug389797.html
+++ b/content/html/content/test/test_bug389797.html
@@ -67,18 +67,17 @@ function HTML_TAG(aTagName, aImplClass) 
     for (i = 0; i < arguments[3].length; ++i) {
       interfacesNonClassinfo[aTagName].push(arguments[3][i]);
     }
   }
 }
 
 const objectIfaces = [
     "imgINotificationObserver", "nsIRequestObserver", "nsIStreamListener",
-    "nsIFrameLoaderOwner", "nsIObjectLoadingContent", "nsIInterfaceRequestor",
-    "nsIChannelEventSink"
+    "nsIFrameLoaderOwner", "nsIObjectLoadingContent", "nsIChannelEventSink"
   ];
 
 var objectIfaces2 = [];
 for (var iface of objectIfaces) {
   objectIfaces2.push(iface);
 }
 objectIfaces2.push("nsIImageLoadingContent");