зеркало из https://github.com/mozilla/gecko-dev.git
Fix for 38495, nsbeta+.
Reinstate previously backed-out fix, now that the nsIScriptablePlugin interface it needs is building successfully on the mac. a=beard,r=jst
This commit is contained in:
Родитель
098648d866
Коммит
75d2952834
|
@ -41,6 +41,7 @@
|
||||||
#include "xptinfo.h"
|
#include "xptinfo.h"
|
||||||
#include "nsIInterfaceInfoManager.h"
|
#include "nsIInterfaceInfoManager.h"
|
||||||
#include "nsIPluginInstance.h"
|
#include "nsIPluginInstance.h"
|
||||||
|
#include "nsIScriptablePlugin.h"
|
||||||
#include "nsIXPConnect.h"
|
#include "nsIXPConnect.h"
|
||||||
#include "nsIServiceManager.h"
|
#include "nsIServiceManager.h"
|
||||||
#include "nsIDOMHTMLEmbedElement.h"
|
#include "nsIDOMHTMLEmbedElement.h"
|
||||||
|
@ -69,7 +70,10 @@ public:
|
||||||
NS_DECL_IDOMHTMLEMBEDELEMENT
|
NS_DECL_IDOMHTMLEMBEDELEMENT
|
||||||
|
|
||||||
// nsIJSScriptObject
|
// nsIJSScriptObject
|
||||||
NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC(mInner)
|
NS_IMETHOD GetScriptObject(nsIScriptContext* aContext,
|
||||||
|
void** aScriptObject);
|
||||||
|
NS_IMETHOD SetScriptObject(void *aScriptObject);
|
||||||
|
|
||||||
virtual PRBool AddProperty(JSContext *aContext, JSObject *aObj,
|
virtual PRBool AddProperty(JSContext *aContext, JSObject *aObj,
|
||||||
jsval aID, jsval *aVp);
|
jsval aID, jsval *aVp);
|
||||||
virtual PRBool DeleteProperty(JSContext *aContext, JSObject *aObj,
|
virtual PRBool DeleteProperty(JSContext *aContext, JSObject *aObj,
|
||||||
|
@ -94,6 +98,7 @@ protected:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsGenericHTMLLeafElement mInner;
|
nsGenericHTMLLeafElement mInner;
|
||||||
|
PRBool mReflectedPlugin;
|
||||||
};
|
};
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -114,6 +119,7 @@ nsHTMLEmbedElement::nsHTMLEmbedElement(nsINodeInfo *aNodeInfo)
|
||||||
{
|
{
|
||||||
NS_INIT_REFCNT();
|
NS_INIT_REFCNT();
|
||||||
mInner.Init(this, aNodeInfo);
|
mInner.Init(this, aNodeInfo);
|
||||||
|
mReflectedPlugin = PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsHTMLEmbedElement::~nsHTMLEmbedElement()
|
nsHTMLEmbedElement::~nsHTMLEmbedElement()
|
||||||
|
@ -296,6 +302,109 @@ nsHTMLEmbedElement::GetPluginInstance(nsIPluginInstance** aPluginInstance)
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For plugins, we want to expose both attributes of the plugin tag
|
||||||
|
* and any scriptable methods that the plugin itself exposes. To do
|
||||||
|
* this, we get the plugin object itself (the XPCOM object) and wrap
|
||||||
|
* it as a scriptable object via xpconnect. We then set the original
|
||||||
|
* node element, which exposes the DOM node methods, as the javascript
|
||||||
|
* prototype object of that object. Then we get both sets of methods, and
|
||||||
|
* plugin methods can potentially override DOM methods.
|
||||||
|
*/
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHTMLEmbedElement::GetScriptObject(nsIScriptContext* aContext,
|
||||||
|
void** aScriptObject)
|
||||||
|
{
|
||||||
|
if (mReflectedPlugin)
|
||||||
|
return mInner.GetScriptObject(aContext, aScriptObject);
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
*aScriptObject = nsnull;
|
||||||
|
|
||||||
|
// Get the JS object corresponding to this dom node. This will become
|
||||||
|
// the javascript prototype object of the object we eventually reflect to the
|
||||||
|
// DOM.
|
||||||
|
JSObject* elementObject = nsnull;
|
||||||
|
rv = mInner.GetScriptObject(aContext, (void**)&elementObject);
|
||||||
|
if (NS_FAILED(rv) || !elementObject)
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIPluginInstance> pi;
|
||||||
|
rv = GetPluginInstance(getter_AddRefs(pi));
|
||||||
|
|
||||||
|
// Check that the plugin object has the nsIScriptablePlugin
|
||||||
|
// interface, describing how to expose it to JavaScript. Given this
|
||||||
|
// interface, use it to get the scriptable peer object (possibly the
|
||||||
|
// plugin object itself) and the scriptable interface to expose it
|
||||||
|
// with.
|
||||||
|
nsIID *scriptableInterface = nsnull;
|
||||||
|
nsCOMPtr<nsISupports> scriptablePeer;
|
||||||
|
if (NS_SUCCEEDED(rv) && pi) {
|
||||||
|
nsCOMPtr<nsIScriptablePlugin> spi(do_QueryInterface(pi, &rv));
|
||||||
|
if (NS_SUCCEEDED(rv) && spi) {
|
||||||
|
rv = spi->GetScriptableInterface(&scriptableInterface);
|
||||||
|
if (NS_SUCCEEDED(rv) && scriptableInterface)
|
||||||
|
rv = spi->GetScriptablePeer(getter_AddRefs(scriptablePeer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NS_FAILED(rv) || !scriptableInterface || !scriptablePeer) {
|
||||||
|
// Fall back to returning the element object.
|
||||||
|
*aScriptObject = elementObject;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find an appropriate parent object to use when wrapping.
|
||||||
|
JSObject* parentObject;
|
||||||
|
nsCOMPtr<nsIScriptObjectOwner> owner;
|
||||||
|
if (mInner.mParent) {
|
||||||
|
owner = do_QueryInterface(mInner.mParent, &rv);
|
||||||
|
} else if (mInner.mDocument) {
|
||||||
|
owner = do_QueryInterface(mInner.mDocument, &rv);
|
||||||
|
}
|
||||||
|
if (NS_SUCCEEDED(rv) && owner) {
|
||||||
|
rv = owner->GetScriptObject(aContext, (void **)&parentObject);
|
||||||
|
}
|
||||||
|
if (NS_FAILED(rv) || !parentObject) // Fall back to using element object.
|
||||||
|
parentObject = elementObject;
|
||||||
|
|
||||||
|
// Wrap it.
|
||||||
|
JSObject* interfaceObject; // XPConnect-wrapped peer object, when we get it.
|
||||||
|
JSContext *cx = (JSContext *)aContext->GetNativeContext();
|
||||||
|
nsCOMPtr<nsIXPConnect> xpc =
|
||||||
|
do_GetService(nsIXPConnect::GetCID());
|
||||||
|
if (cx && xpc) {
|
||||||
|
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
|
||||||
|
if (NS_SUCCEEDED(xpc->WrapNative(cx, parentObject,
|
||||||
|
scriptablePeer, *scriptableInterface,
|
||||||
|
getter_AddRefs(holder))) && holder &&
|
||||||
|
NS_SUCCEEDED(holder->GetJSObject(&interfaceObject)) && interfaceObject) {
|
||||||
|
*aScriptObject = interfaceObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we got an xpconnect-wrapped plugin object, set its' prototype to the
|
||||||
|
// element object.
|
||||||
|
if (!*aScriptObject || !JS_SetPrototype(cx, interfaceObject, elementObject)) {
|
||||||
|
*aScriptObject = elementObject; // fall back
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache it.
|
||||||
|
if (NS_SUCCEEDED(mInner.SetScriptObject(*aScriptObject)))
|
||||||
|
mReflectedPlugin = PR_TRUE;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: if this method ever gets called, it will destroy the
|
||||||
|
// prototype chain.
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHTMLEmbedElement::SetScriptObject(void *aScriptObject)
|
||||||
|
{
|
||||||
|
return mInner.SetScriptObject(aScriptObject);
|
||||||
|
}
|
||||||
|
|
||||||
// nsIJSScriptObject
|
// nsIJSScriptObject
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
|
@ -310,6 +419,8 @@ nsHTMLEmbedElement::DeleteProperty(JSContext *aContext, JSObject *aObj, jsval aI
|
||||||
return mInner.DeleteProperty(aContext, aObj, aID, aVp);
|
return mInner.DeleteProperty(aContext, aObj, aID, aVp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allow access to arbitrary XPCOM interfaces supported by the plugin
|
||||||
|
// via a pluginObject.nsISomeInterface notation.
|
||||||
PRBool
|
PRBool
|
||||||
nsHTMLEmbedElement::GetProperty(JSContext *aContext, JSObject *aObj, jsval aID, jsval *aVp)
|
nsHTMLEmbedElement::GetProperty(JSContext *aContext, JSObject *aObj, jsval aID, jsval *aVp)
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "xptinfo.h"
|
#include "xptinfo.h"
|
||||||
#include "nsIInterfaceInfoManager.h"
|
#include "nsIInterfaceInfoManager.h"
|
||||||
#include "nsIPluginInstance.h"
|
#include "nsIPluginInstance.h"
|
||||||
|
#include "nsIScriptablePlugin.h"
|
||||||
#include "nsIXPConnect.h"
|
#include "nsIXPConnect.h"
|
||||||
#include "nsIServiceManager.h"
|
#include "nsIServiceManager.h"
|
||||||
#include "nsIDOMHTMLEmbedElement.h"
|
#include "nsIDOMHTMLEmbedElement.h"
|
||||||
|
@ -69,7 +70,10 @@ public:
|
||||||
NS_DECL_IDOMHTMLEMBEDELEMENT
|
NS_DECL_IDOMHTMLEMBEDELEMENT
|
||||||
|
|
||||||
// nsIJSScriptObject
|
// nsIJSScriptObject
|
||||||
NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC(mInner)
|
NS_IMETHOD GetScriptObject(nsIScriptContext* aContext,
|
||||||
|
void** aScriptObject);
|
||||||
|
NS_IMETHOD SetScriptObject(void *aScriptObject);
|
||||||
|
|
||||||
virtual PRBool AddProperty(JSContext *aContext, JSObject *aObj,
|
virtual PRBool AddProperty(JSContext *aContext, JSObject *aObj,
|
||||||
jsval aID, jsval *aVp);
|
jsval aID, jsval *aVp);
|
||||||
virtual PRBool DeleteProperty(JSContext *aContext, JSObject *aObj,
|
virtual PRBool DeleteProperty(JSContext *aContext, JSObject *aObj,
|
||||||
|
@ -94,6 +98,7 @@ protected:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsGenericHTMLLeafElement mInner;
|
nsGenericHTMLLeafElement mInner;
|
||||||
|
PRBool mReflectedPlugin;
|
||||||
};
|
};
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -114,6 +119,7 @@ nsHTMLEmbedElement::nsHTMLEmbedElement(nsINodeInfo *aNodeInfo)
|
||||||
{
|
{
|
||||||
NS_INIT_REFCNT();
|
NS_INIT_REFCNT();
|
||||||
mInner.Init(this, aNodeInfo);
|
mInner.Init(this, aNodeInfo);
|
||||||
|
mReflectedPlugin = PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsHTMLEmbedElement::~nsHTMLEmbedElement()
|
nsHTMLEmbedElement::~nsHTMLEmbedElement()
|
||||||
|
@ -296,6 +302,109 @@ nsHTMLEmbedElement::GetPluginInstance(nsIPluginInstance** aPluginInstance)
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For plugins, we want to expose both attributes of the plugin tag
|
||||||
|
* and any scriptable methods that the plugin itself exposes. To do
|
||||||
|
* this, we get the plugin object itself (the XPCOM object) and wrap
|
||||||
|
* it as a scriptable object via xpconnect. We then set the original
|
||||||
|
* node element, which exposes the DOM node methods, as the javascript
|
||||||
|
* prototype object of that object. Then we get both sets of methods, and
|
||||||
|
* plugin methods can potentially override DOM methods.
|
||||||
|
*/
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHTMLEmbedElement::GetScriptObject(nsIScriptContext* aContext,
|
||||||
|
void** aScriptObject)
|
||||||
|
{
|
||||||
|
if (mReflectedPlugin)
|
||||||
|
return mInner.GetScriptObject(aContext, aScriptObject);
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
*aScriptObject = nsnull;
|
||||||
|
|
||||||
|
// Get the JS object corresponding to this dom node. This will become
|
||||||
|
// the javascript prototype object of the object we eventually reflect to the
|
||||||
|
// DOM.
|
||||||
|
JSObject* elementObject = nsnull;
|
||||||
|
rv = mInner.GetScriptObject(aContext, (void**)&elementObject);
|
||||||
|
if (NS_FAILED(rv) || !elementObject)
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIPluginInstance> pi;
|
||||||
|
rv = GetPluginInstance(getter_AddRefs(pi));
|
||||||
|
|
||||||
|
// Check that the plugin object has the nsIScriptablePlugin
|
||||||
|
// interface, describing how to expose it to JavaScript. Given this
|
||||||
|
// interface, use it to get the scriptable peer object (possibly the
|
||||||
|
// plugin object itself) and the scriptable interface to expose it
|
||||||
|
// with.
|
||||||
|
nsIID *scriptableInterface = nsnull;
|
||||||
|
nsCOMPtr<nsISupports> scriptablePeer;
|
||||||
|
if (NS_SUCCEEDED(rv) && pi) {
|
||||||
|
nsCOMPtr<nsIScriptablePlugin> spi(do_QueryInterface(pi, &rv));
|
||||||
|
if (NS_SUCCEEDED(rv) && spi) {
|
||||||
|
rv = spi->GetScriptableInterface(&scriptableInterface);
|
||||||
|
if (NS_SUCCEEDED(rv) && scriptableInterface)
|
||||||
|
rv = spi->GetScriptablePeer(getter_AddRefs(scriptablePeer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NS_FAILED(rv) || !scriptableInterface || !scriptablePeer) {
|
||||||
|
// Fall back to returning the element object.
|
||||||
|
*aScriptObject = elementObject;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find an appropriate parent object to use when wrapping.
|
||||||
|
JSObject* parentObject;
|
||||||
|
nsCOMPtr<nsIScriptObjectOwner> owner;
|
||||||
|
if (mInner.mParent) {
|
||||||
|
owner = do_QueryInterface(mInner.mParent, &rv);
|
||||||
|
} else if (mInner.mDocument) {
|
||||||
|
owner = do_QueryInterface(mInner.mDocument, &rv);
|
||||||
|
}
|
||||||
|
if (NS_SUCCEEDED(rv) && owner) {
|
||||||
|
rv = owner->GetScriptObject(aContext, (void **)&parentObject);
|
||||||
|
}
|
||||||
|
if (NS_FAILED(rv) || !parentObject) // Fall back to using element object.
|
||||||
|
parentObject = elementObject;
|
||||||
|
|
||||||
|
// Wrap it.
|
||||||
|
JSObject* interfaceObject; // XPConnect-wrapped peer object, when we get it.
|
||||||
|
JSContext *cx = (JSContext *)aContext->GetNativeContext();
|
||||||
|
nsCOMPtr<nsIXPConnect> xpc =
|
||||||
|
do_GetService(nsIXPConnect::GetCID());
|
||||||
|
if (cx && xpc) {
|
||||||
|
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
|
||||||
|
if (NS_SUCCEEDED(xpc->WrapNative(cx, parentObject,
|
||||||
|
scriptablePeer, *scriptableInterface,
|
||||||
|
getter_AddRefs(holder))) && holder &&
|
||||||
|
NS_SUCCEEDED(holder->GetJSObject(&interfaceObject)) && interfaceObject) {
|
||||||
|
*aScriptObject = interfaceObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we got an xpconnect-wrapped plugin object, set its' prototype to the
|
||||||
|
// element object.
|
||||||
|
if (!*aScriptObject || !JS_SetPrototype(cx, interfaceObject, elementObject)) {
|
||||||
|
*aScriptObject = elementObject; // fall back
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache it.
|
||||||
|
if (NS_SUCCEEDED(mInner.SetScriptObject(*aScriptObject)))
|
||||||
|
mReflectedPlugin = PR_TRUE;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: if this method ever gets called, it will destroy the
|
||||||
|
// prototype chain.
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHTMLEmbedElement::SetScriptObject(void *aScriptObject)
|
||||||
|
{
|
||||||
|
return mInner.SetScriptObject(aScriptObject);
|
||||||
|
}
|
||||||
|
|
||||||
// nsIJSScriptObject
|
// nsIJSScriptObject
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
|
@ -310,6 +419,8 @@ nsHTMLEmbedElement::DeleteProperty(JSContext *aContext, JSObject *aObj, jsval aI
|
||||||
return mInner.DeleteProperty(aContext, aObj, aID, aVp);
|
return mInner.DeleteProperty(aContext, aObj, aID, aVp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allow access to arbitrary XPCOM interfaces supported by the plugin
|
||||||
|
// via a pluginObject.nsISomeInterface notation.
|
||||||
PRBool
|
PRBool
|
||||||
nsHTMLEmbedElement::GetProperty(JSContext *aContext, JSObject *aObj, jsval aID, jsval *aVp)
|
nsHTMLEmbedElement::GetProperty(JSContext *aContext, JSObject *aObj, jsval aID, jsval *aVp)
|
||||||
{
|
{
|
||||||
|
|
Загрузка…
Ссылка в новой задаче