Fixing the way we pass attributes and parameters to plugins, bug 103940 r=av sr=beard

This commit is contained in:
peterlubczynski%netscape.com 2001-12-11 15:53:07 +00:00
Родитель 742f7d9a11
Коммит 99254c4720
3 изменённых файлов: 440 добавлений и 649 удалений

Просмотреть файл

@ -73,6 +73,9 @@
#include "nsIDocShellTreeOwner.h" #include "nsIDocShellTreeOwner.h"
#include "nsIWebBrowserChrome.h" #include "nsIWebBrowserChrome.h"
#include "nsIDOMElement.h" #include "nsIDOMElement.h"
#include "nsIDOMNodeList.h"
#include "nsIDOMHTMLObjectElement.h"
#include "nsIDOMHTMLAppletElement.h"
#include "nsContentPolicyUtils.h" #include "nsContentPolicyUtils.h"
#include "nsIDOMWindow.h" #include "nsIDOMWindow.h"
#include "nsIDOMMouseListener.h" #include "nsIDOMMouseListener.h"
@ -283,12 +286,6 @@ private:
nsPluginWindow mPluginWindow; nsPluginWindow mPluginWindow;
nsIPluginInstance *mInstance; nsIPluginInstance *mInstance;
nsObjectFrame *mOwner; nsObjectFrame *mOwner;
PRInt32 mNumAttrs;
char **mAttrNames;
char **mAttrVals;
PRInt32 mNumParams;
char **mParamNames;
char **mParamVals;
char *mDocumentBase; char *mDocumentBase;
char *mTagText; char *mTagText;
nsIWidget *mWidget; nsIWidget *mWidget;
@ -296,10 +293,16 @@ private:
nsCOMPtr<nsITimer> mPluginTimer; nsCOMPtr<nsITimer> mPluginTimer;
nsIPluginHost *mPluginHost; nsIPluginHost *mPluginHost;
PRPackedBool mContentFocused; PRPackedBool mContentFocused;
PRUint16 mNumCachedAttrs;
PRUint16 mNumCachedParams;
char **mCachedAttrParamNames;
char **mCachedAttrParamValues;
nsresult DispatchKeyToPlugin(nsIDOMEvent* aKeyEvent); nsresult DispatchKeyToPlugin(nsIDOMEvent* aKeyEvent);
nsresult DispatchMouseToPlugin(nsIDOMEvent* aMouseEvent); nsresult DispatchMouseToPlugin(nsIDOMEvent* aMouseEvent);
nsresult DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent); nsresult DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent);
nsresult EnsureCachedAttrParamArrays();
}; };
// Mac specific code to fix up port position and clip during paint // Mac specific code to fix up port position and clip during paint
@ -1929,18 +1932,16 @@ nsPluginInstanceOwner::nsPluginInstanceOwner()
memset(&mPluginWindow, 0, sizeof(mPluginWindow)); memset(&mPluginWindow, 0, sizeof(mPluginWindow));
mInstance = nsnull; mInstance = nsnull;
mOwner = nsnull; mOwner = nsnull;
mNumAttrs = 0;
mAttrNames = nsnull;
mAttrVals = nsnull;
mWidget = nsnull; mWidget = nsnull;
mContext = nsnull; mContext = nsnull;
mNumParams = 0;
mParamNames = nsnull;
mParamVals = nsnull;
mDocumentBase = nsnull; mDocumentBase = nsnull;
mTagText = nsnull; mTagText = nsnull;
mPluginHost = nsnull; mPluginHost = nsnull;
mContentFocused = PR_FALSE; mContentFocused = PR_FALSE;
mNumCachedAttrs = 0;
mNumCachedParams = 0;
mCachedAttrParamNames = nsnull;
mCachedAttrParamValues = nsnull;
} }
nsPluginInstanceOwner::~nsPluginInstanceOwner() nsPluginInstanceOwner::~nsPluginInstanceOwner()
@ -1956,68 +1957,34 @@ nsPluginInstanceOwner::~nsPluginInstanceOwner()
NS_IF_RELEASE(mPluginHost); NS_IF_RELEASE(mPluginHost);
mOwner = nsnull; mOwner = nsnull;
for (cnt = 0; cnt < mNumAttrs; cnt++) for (cnt = 0; cnt < (mNumCachedAttrs + 1 + mNumCachedParams); cnt++) {
{ if ((nsnull != mCachedAttrParamNames) && (nsnull != mCachedAttrParamNames[cnt])) {
if ((nsnull != mAttrNames) && (nsnull != mAttrNames[cnt])) PR_Free(mCachedAttrParamNames[cnt]);
{ mCachedAttrParamNames[cnt] = nsnull;
PR_Free(mAttrNames[cnt]);
mAttrNames[cnt] = nsnull;
} }
if ((nsnull != mAttrVals) && (nsnull != mAttrVals[cnt])) if ((nsnull != mCachedAttrParamValues) && (nsnull != mCachedAttrParamValues[cnt])) {
{ PR_Free(mCachedAttrParamValues[cnt]);
PR_Free(mAttrVals[cnt]); mCachedAttrParamValues[cnt] = nsnull;
mAttrVals[cnt] = nsnull;
} }
} }
if (nsnull != mAttrNames) if (nsnull != mCachedAttrParamNames) {
{ PR_Free(mCachedAttrParamNames);
PR_Free(mAttrNames); mCachedAttrParamNames = nsnull;
mAttrNames = nsnull;
} }
if (nsnull != mAttrVals) if (nsnull != mCachedAttrParamValues) {
{ PR_Free(mCachedAttrParamValues);
PR_Free(mAttrVals); mCachedAttrParamValues = nsnull;
mAttrVals = nsnull;
} }
for (cnt = 0; cnt < mNumParams; cnt++) if (nsnull != mDocumentBase) {
{
if ((nsnull != mParamNames) && (nsnull != mParamNames[cnt]))
{
PR_Free(mParamNames[cnt]);
mParamNames[cnt] = nsnull;
}
if ((nsnull != mParamVals) && (nsnull != mParamVals[cnt]))
{
PR_Free(mParamVals[cnt]);
mParamVals[cnt] = nsnull;
}
}
if (nsnull != mParamNames)
{
PR_Free(mParamNames);
mParamNames = nsnull;
}
if (nsnull != mParamVals)
{
PR_Free(mParamVals);
mParamVals = nsnull;
}
if (nsnull != mDocumentBase)
{
nsCRT::free(mDocumentBase); nsCRT::free(mDocumentBase);
mDocumentBase = nsnull; mDocumentBase = nsnull;
} }
if (nsnull != mTagText) if (nsnull != mTagText) {
{
nsCRT::free(mTagText); nsCRT::free(mTagText);
mTagText = nsnull; mTagText = nsnull;
} }
@ -2063,90 +2030,12 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetAttributes(PRUint16& n,
const char*const*& names, const char*const*& names,
const char*const*& values) const char*const*& values)
{ {
nsresult rv; nsresult rv = EnsureCachedAttrParamArrays();
nsIContent* iContent; NS_ENSURE_SUCCESS(rv, rv);
if ((nsnull == mAttrNames) && (nsnull != mOwner)) { n = mNumCachedAttrs;
rv = mOwner->GetContent(&iContent); names = (const char **)mCachedAttrParamNames;
values = (const char **)mCachedAttrParamValues;
if (NS_SUCCEEDED(rv)) {
PRInt32 count;
if (NS_SUCCEEDED(iContent->GetAttrCount(count))) {
PRInt32 index;
mAttrNames = (char **)PR_Calloc(sizeof(char *) * count, 1);
mAttrVals = (char **)PR_Calloc(sizeof(char *) * count, 1);
mNumAttrs = 0;
if ((nsnull != mAttrNames) && (nsnull != mAttrVals)) {
for (index = 0; index < count; index++) {
PRInt32 nameSpaceID;
nsCOMPtr<nsIAtom> atom;
nsCOMPtr<nsIAtom> prefix;
iContent->GetAttrNameAt(index, nameSpaceID,
*getter_AddRefs(atom),
*getter_AddRefs(prefix));
nsAutoString value;
if (NS_CONTENT_ATTR_HAS_VALUE ==
iContent->GetAttr(nameSpaceID, atom, value)) {
nsAutoString name;
atom->ToString(name);
/* Changing to ToNewUTF8String addressing 17169, 39789
mAttrNames[mNumAttrs] = (char *)PR_Malloc(name.Length() + 1);
mAttrVals[mNumAttrs] = (char *)PR_Malloc(value.Length() + 1);
if ((nsnull != mAttrNames[mNumAttrs]) &&
(nsnull != mAttrVals[mNumAttrs]))
{
name.ToCString(mAttrNames[mNumAttrs], name.Length() + 1);
value.ToCString(mAttrVals[mNumAttrs], value.Length() + 1);
mNumAttrs++;
}
else
{
if (nsnull != mAttrNames[mNumAttrs])
{
PR_Free(mAttrNames[mNumAttrs]);
mAttrNames[mNumAttrs] = nsnull;
}
if (nsnull != mAttrVals[mNumAttrs])
{
PR_Free(mAttrVals[mNumAttrs]);
mAttrVals[mNumAttrs] = nsnull;
}
}
*/
mAttrNames[mNumAttrs] = ToNewUTF8String(name);
mAttrVals[mNumAttrs] = ToNewUTF8String(value);
mNumAttrs++;
}
}
}
else {
rv = NS_ERROR_OUT_OF_MEMORY;
if (nsnull != mAttrVals) {
PR_Free(mAttrVals);
mAttrVals = nsnull;
}
if (nsnull != mAttrNames) {
PR_Free(mAttrNames);
mAttrNames = nsnull;
}
}
}
NS_RELEASE(iContent);
}
}
else {
rv = NS_OK;
}
n = mNumAttrs;
names = (const char **)mAttrNames;
values = (const char **)mAttrVals;
return rv; return rv;
} }
@ -2155,18 +2044,15 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetAttribute(const char* name, const char*
{ {
NS_ENSURE_ARG_POINTER(name); NS_ENSURE_ARG_POINTER(name);
NS_ENSURE_ARG_POINTER(result); NS_ENSURE_ARG_POINTER(result);
if (nsnull == mAttrNames) {
PRUint16 numattrs; nsresult rv = EnsureCachedAttrParamArrays();
const char * const *names, * const *vals; NS_ENSURE_SUCCESS(rv, rv);
GetAttributes(numattrs, names, vals); *result = nsnull;
}
*result = NULL; for (int i = 0; i < mNumCachedAttrs; i++) {
if (0 == PL_strcasecmp(mCachedAttrParamNames[i], name)) {
for (int i = 0; i < mNumAttrs; i++) { *result = mCachedAttrParamValues[i];
if (0 == PL_strcasecmp(mAttrNames[i], name)) {
*result = mAttrVals[i];
return NS_OK; return NS_OK;
} }
} }
@ -2527,148 +2413,16 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetTagText(const char* *result)
NS_IMETHODIMP nsPluginInstanceOwner::GetParameters(PRUint16& n, const char*const*& names, const char*const*& values) NS_IMETHODIMP nsPluginInstanceOwner::GetParameters(PRUint16& n, const char*const*& names, const char*const*& values)
{ {
nsresult rv = NS_ERROR_FAILURE; nsresult rv = EnsureCachedAttrParamArrays();
NS_ENSURE_SUCCESS(rv, rv);
if ((nsnull == mParamNames) && (nsnull != mOwner)) // make sure we have at least one param tag because embed's don't have any
{ if (!mNumCachedParams)
nsIContent *cont; return NS_ERROR_FAILURE;
mOwner->GetContent(&cont); n = mNumCachedParams;
names = (const char **)(mCachedAttrParamNames + mNumCachedAttrs + 1);
if (nsnull != cont) values = (const char **)(mCachedAttrParamValues + mNumCachedAttrs + 1);
{
PRBool haskids = PR_FALSE;
cont->CanContainChildren(haskids);
if (PR_TRUE == haskids)
{
PRInt32 numkids, idx, numparams = 0;
cont->ChildCount(numkids);
//first pass, count number of param tags...
for (idx = 0; idx < numkids; idx++)
{
nsIContent *kid;
cont->ChildAt(idx, kid);
if (nsnull != kid)
{
nsIAtom *atom;
kid->GetTag(atom);
if (nsnull != atom)
{
if (atom == nsHTMLAtoms::param)
numparams++;
NS_RELEASE(atom);
}
NS_RELEASE(kid);
}
}
if (numparams > 0)
{
//now we need to create arrays
//representing the parameter name/value pairs...
mParamNames = (char **)PR_Calloc(sizeof(char *) * numparams, 1);
mParamVals = (char **)PR_Calloc(sizeof(char *) * numparams, 1);
if ((nsnull != mParamNames) && (nsnull != mParamVals))
{
for (idx = 0; idx < numkids; idx++)
{
nsIContent *kid;
cont->ChildAt(idx, kid);
if (nsnull != kid)
{
nsIAtom *atom;
kid->GetTag(atom);
if (nsnull != atom)
{
if (atom == nsHTMLAtoms::param)
{
nsAutoString val, name;
//add param to list...
if ((NS_CONTENT_ATTR_HAS_VALUE == kid->GetAttr(kNameSpaceID_HTML, nsHTMLAtoms::name, name)) &&
(NS_CONTENT_ATTR_HAS_VALUE == kid->GetAttr(kNameSpaceID_HTML, nsHTMLAtoms::value, val)))
{
/* Changing to ToNewUTF8String addressing 17169, 39789
mParamNames[mNumParams] = (char *)PR_Malloc(name.Length() + 1);
mParamVals[mNumParams] = (char *)PR_Malloc(val.Length() + 1);
if ((nsnull != mParamNames[mNumParams]) &&
(nsnull != mParamVals[mNumParams]))
{
name.ToCString(mParamNames[mNumParams], name.Length() + 1);
val.ToCString(mParamVals[mNumParams], val.Length() + 1);
mNumParams++;
}
else
{
if (nsnull != mParamNames[mNumParams])
{
PR_Free(mParamNames[mNumParams]);
mParamNames[mNumParams] = nsnull;
}
if (nsnull != mParamVals[mNumParams])
{
PR_Free(mParamVals[mNumParams]);
mParamVals[mNumParams] = nsnull;
}
}
*/
/* According to the HTML 4.01 spec, at
* http://www.w3.org/TR/html4/types.html#type-cdata
* ''User agents may ignore leading and trailing
* white space in CDATA attribute values (e.g., "
* myval " may be interpreted as "myval"). Authors
* should not declare attribute values with
* leading or trailing white space.''
*/
name.CompressWhitespace();
val.CompressWhitespace();
mParamNames[mNumParams] = ToNewUTF8String(name);
mParamVals[mNumParams] = ToNewUTF8String(val);
mNumParams++;
}
}
NS_RELEASE(atom);
}
}
NS_RELEASE(kid);
}
}
}
}
rv = NS_OK;
NS_RELEASE(cont);
}
}
n = mNumParams;
names = (const char **)mParamNames;
values = (const char **)mParamVals;
return rv; return rv;
} }
@ -2677,32 +2431,20 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetParameter(const char* name, const char*
{ {
NS_ENSURE_ARG_POINTER(name); NS_ENSURE_ARG_POINTER(name);
NS_ENSURE_ARG_POINTER(result); NS_ENSURE_ARG_POINTER(result);
nsresult rv;
PRInt32 count; nsresult rv = EnsureCachedAttrParamArrays();
NS_ENSURE_SUCCESS(rv, rv);
if (nsnull == mParamNames) *result = nsnull;
{
PRUint16 numattrs;
const char * const *names, * const *vals;
rv = GetParameters(numattrs, names, vals); for (int i = mNumCachedAttrs + 1; i < (mNumCachedParams + 1 + mNumCachedAttrs); i++) {
} if (0 == PL_strcasecmp(mCachedAttrParamNames[i], name)) {
*result = mCachedAttrParamValues[i];
for (count = 0; count < mNumParams; count++) return NS_OK;
{
if (0 == PL_strcasecmp(mParamNames[count], name))
{
*result = mParamVals[count];
break;
} }
} }
if (count >= mNumParams) { return NS_ERROR_FAILURE;
*result = "";
rv = NS_ERROR_FAILURE;
}
return rv;
} }
NS_IMETHODIMP nsPluginInstanceOwner::GetDocumentBase(const char* *result) NS_IMETHODIMP nsPluginInstanceOwner::GetDocumentBase(const char* *result)
@ -3000,6 +2742,155 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetMayScript(PRBool *result)
return NS_OK; return NS_OK;
} }
// Cache the attributes and/or parameters of our tag into a single set of arrays
// to be compatible with 4.x. The attributes go first, followed by a PARAM/null and
// then any PARAM tags. Also, hold the cached array around for the duration
// of the life of the instance because 4.x did. See bug 111008.
nsresult nsPluginInstanceOwner::EnsureCachedAttrParamArrays()
{
if (mCachedAttrParamValues)
return NS_OK;
NS_PRECONDITION((((mNumCachedAttrs + mNumCachedParams) == 0) && !mCachedAttrParamNames),
"re-cache of attrs/params not implemented! use the DOM node directy instead");
NS_ENSURE_TRUE(mOwner, NS_ERROR_NULL_POINTER);
// first, we need to find out how much we need to allocate for our arrays
// count up attributes
mNumCachedAttrs = 0;
nsCOMPtr<nsIContent> content;
nsresult rv = mOwner->GetContent(getter_AddRefs(content));
NS_ENSURE_TRUE(content, rv);
rv = content->GetAttrCount((PRInt32&)mNumCachedAttrs); // signed 32 bits to unsigned 16 bits conversion
NS_ENSURE_SUCCESS(rv, rv);
// now, we need to find all the PARAM tags that are children of us
// however, be carefull NOT to include any PARAMs that don't have us as a direct
// parent. For nested object (or applet) tags, be sure to only round up the
// param tags that coorespond with THIS instance. And also, weed out any bogus
// tags that may get in the way, see bug 39609. Then, with any param tag that meet our
// qualification, temporarly cache them in an nsISupportsArray until we can figure out
// what size to make our fixed char* array.
mNumCachedParams = 0;
nsCOMPtr<nsISupportsArray> ourParams;
rv = NS_NewISupportsArray(getter_AddRefs(ourParams));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMNode> mydomNode = do_QueryInterface(content);
NS_ENSURE_TRUE(mydomNode, NS_ERROR_NO_INTERFACE);
// use the DOM to get us ALL our dependant PARAM tags, even if not ours
nsCOMPtr<nsIDOMElement> mydomElement = do_QueryInterface(mydomNode);
NS_ENSURE_TRUE(mydomElement, NS_ERROR_NO_INTERFACE);
nsCOMPtr<nsIDOMNodeList> allParams;
mydomElement->GetElementsByTagName(NS_LITERAL_STRING("PARAM"), getter_AddRefs(allParams));
if (allParams) {
PRUint32 numAllParams;
allParams->GetLength(&numAllParams);
// loop through every so called dependant PARAM tag to check if it "belongs" to us
for (PRUint32 i = 0; i < numAllParams; i++) {
nsCOMPtr<nsIDOMNode> pnode;
allParams->Item(i, getter_AddRefs(pnode));
if (pnode) {
nsCOMPtr<nsIDOMElement> domelement = do_QueryInterface(pnode);
if (domelement) {
// let's NOT count up param tags that don't have a name attribute
nsAutoString name;
domelement->GetAttribute(NS_LITERAL_STRING("name"), name);
if (name.Length() > 0) {
nsCOMPtr<nsIDOMNode> parent;
nsCOMPtr<nsIDOMHTMLObjectElement> domobject;
nsCOMPtr<nsIDOMHTMLAppletElement> domapplet;
pnode->GetParentNode(getter_AddRefs(parent));
// walk up the parents of this PARAM until we find an object (or applet) tag
while (!(domobject || domapplet) && parent) {
domobject = do_QueryInterface(parent);
domapplet = do_QueryInterface(parent);
nsCOMPtr<nsIDOMNode> temp;
parent->GetParentNode(getter_AddRefs(temp));
parent = temp;
}
if (domapplet || domobject) {
parent = domapplet ? do_QueryInterface(domapplet) : do_QueryInterface(domobject);
// now check to see if this PARAM's parent is us. if so, cache it for later
if (parent.get() == mydomNode.get()) {
nsCOMPtr<nsISupports> sup = do_QueryInterface(pnode);
NS_ASSERTION(sup, "lame! DOM node does doesn't QI to nsISupports");
ourParams->AppendElement(sup);
}
}
}
}
}
}
}
ourParams->Count((PRUint32*)&mNumCachedParams); // unsigned 32 bits to unsigned 16 bits conversion
// now lets make the arrays
mCachedAttrParamNames = (char **)PR_Calloc(sizeof(char *) * (mNumCachedAttrs + 1 + mNumCachedParams), 1);
NS_ENSURE_TRUE(mCachedAttrParamNames, NS_ERROR_OUT_OF_MEMORY);
mCachedAttrParamValues = (char **)PR_Calloc(sizeof(char *) * (mNumCachedAttrs + 1 + mNumCachedParams), 1);
NS_ENSURE_TRUE(mCachedAttrParamValues, NS_ERROR_OUT_OF_MEMORY);
// let's fill in our attributes
PRInt16 c = 0;
for (PRInt16 index = 0; index < mNumCachedAttrs; index++) {
PRInt32 nameSpaceID;
nsCOMPtr<nsIAtom> atom;
nsCOMPtr<nsIAtom> prefix;
content->GetAttrNameAt(index, nameSpaceID,
*getter_AddRefs(atom),
*getter_AddRefs(prefix));
nsAutoString value;
if (NS_CONTENT_ATTR_NOT_THERE != content->GetAttr(nameSpaceID, atom, value)) {
nsAutoString name;
atom->ToString(name);
mCachedAttrParamNames [c] = ToNewUTF8String(name);
mCachedAttrParamValues[c] = ToNewUTF8String(value);
c++;
}
}
// add our PARAM and null seperator
mCachedAttrParamNames [mNumCachedAttrs + 1] = "PARAM";
mCachedAttrParamValues[mNumCachedAttrs + 1] = nsnull;
// now fill in the PARAM name/value pairs from the cached DOM nodes
c = 0;
for (PRInt16 idx = 0; idx < mNumCachedParams; idx++) {
nsCOMPtr<nsISupports> sup = ourParams->ElementAt(idx);
if (sup) {
nsCOMPtr<nsIDOMElement> param = do_QueryInterface(sup);
if (param) {
nsAutoString name;
nsAutoString value;
param->GetAttribute(NS_LITERAL_STRING("name"), name); // check for empty done above
param->GetAttribute(NS_LITERAL_STRING("value"), value);
/*
* According to the HTML 4.01 spec, at
* http://www.w3.org/TR/html4/types.html#type-cdata
* ''User agents may ignore leading and trailing
* white space in CDATA attribute values (e.g., "
* myval " may be interpreted as "myval"). Authors
* should not declare attribute values with
* leading or trailing white space.''
*/
name.CompressWhitespace(); // XXX right function?
value.CompressWhitespace();
mCachedAttrParamNames [mNumCachedAttrs + 1 + c] = ToNewUTF8String(name);
mCachedAttrParamValues[mNumCachedAttrs + 1 + c] = ToNewUTF8String(value);
c++; // rules!
}
}
}
return NS_OK;
}
// Here's where we forward events to plugins. // Here's where we forward events to plugins.
#ifdef XP_MAC #ifdef XP_MAC

Просмотреть файл

@ -73,6 +73,9 @@
#include "nsIDocShellTreeOwner.h" #include "nsIDocShellTreeOwner.h"
#include "nsIWebBrowserChrome.h" #include "nsIWebBrowserChrome.h"
#include "nsIDOMElement.h" #include "nsIDOMElement.h"
#include "nsIDOMNodeList.h"
#include "nsIDOMHTMLObjectElement.h"
#include "nsIDOMHTMLAppletElement.h"
#include "nsContentPolicyUtils.h" #include "nsContentPolicyUtils.h"
#include "nsIDOMWindow.h" #include "nsIDOMWindow.h"
#include "nsIDOMMouseListener.h" #include "nsIDOMMouseListener.h"
@ -283,12 +286,6 @@ private:
nsPluginWindow mPluginWindow; nsPluginWindow mPluginWindow;
nsIPluginInstance *mInstance; nsIPluginInstance *mInstance;
nsObjectFrame *mOwner; nsObjectFrame *mOwner;
PRInt32 mNumAttrs;
char **mAttrNames;
char **mAttrVals;
PRInt32 mNumParams;
char **mParamNames;
char **mParamVals;
char *mDocumentBase; char *mDocumentBase;
char *mTagText; char *mTagText;
nsIWidget *mWidget; nsIWidget *mWidget;
@ -296,10 +293,16 @@ private:
nsCOMPtr<nsITimer> mPluginTimer; nsCOMPtr<nsITimer> mPluginTimer;
nsIPluginHost *mPluginHost; nsIPluginHost *mPluginHost;
PRPackedBool mContentFocused; PRPackedBool mContentFocused;
PRUint16 mNumCachedAttrs;
PRUint16 mNumCachedParams;
char **mCachedAttrParamNames;
char **mCachedAttrParamValues;
nsresult DispatchKeyToPlugin(nsIDOMEvent* aKeyEvent); nsresult DispatchKeyToPlugin(nsIDOMEvent* aKeyEvent);
nsresult DispatchMouseToPlugin(nsIDOMEvent* aMouseEvent); nsresult DispatchMouseToPlugin(nsIDOMEvent* aMouseEvent);
nsresult DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent); nsresult DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent);
nsresult EnsureCachedAttrParamArrays();
}; };
// Mac specific code to fix up port position and clip during paint // Mac specific code to fix up port position and clip during paint
@ -1929,18 +1932,16 @@ nsPluginInstanceOwner::nsPluginInstanceOwner()
memset(&mPluginWindow, 0, sizeof(mPluginWindow)); memset(&mPluginWindow, 0, sizeof(mPluginWindow));
mInstance = nsnull; mInstance = nsnull;
mOwner = nsnull; mOwner = nsnull;
mNumAttrs = 0;
mAttrNames = nsnull;
mAttrVals = nsnull;
mWidget = nsnull; mWidget = nsnull;
mContext = nsnull; mContext = nsnull;
mNumParams = 0;
mParamNames = nsnull;
mParamVals = nsnull;
mDocumentBase = nsnull; mDocumentBase = nsnull;
mTagText = nsnull; mTagText = nsnull;
mPluginHost = nsnull; mPluginHost = nsnull;
mContentFocused = PR_FALSE; mContentFocused = PR_FALSE;
mNumCachedAttrs = 0;
mNumCachedParams = 0;
mCachedAttrParamNames = nsnull;
mCachedAttrParamValues = nsnull;
} }
nsPluginInstanceOwner::~nsPluginInstanceOwner() nsPluginInstanceOwner::~nsPluginInstanceOwner()
@ -1956,68 +1957,34 @@ nsPluginInstanceOwner::~nsPluginInstanceOwner()
NS_IF_RELEASE(mPluginHost); NS_IF_RELEASE(mPluginHost);
mOwner = nsnull; mOwner = nsnull;
for (cnt = 0; cnt < mNumAttrs; cnt++) for (cnt = 0; cnt < (mNumCachedAttrs + 1 + mNumCachedParams); cnt++) {
{ if ((nsnull != mCachedAttrParamNames) && (nsnull != mCachedAttrParamNames[cnt])) {
if ((nsnull != mAttrNames) && (nsnull != mAttrNames[cnt])) PR_Free(mCachedAttrParamNames[cnt]);
{ mCachedAttrParamNames[cnt] = nsnull;
PR_Free(mAttrNames[cnt]);
mAttrNames[cnt] = nsnull;
} }
if ((nsnull != mAttrVals) && (nsnull != mAttrVals[cnt])) if ((nsnull != mCachedAttrParamValues) && (nsnull != mCachedAttrParamValues[cnt])) {
{ PR_Free(mCachedAttrParamValues[cnt]);
PR_Free(mAttrVals[cnt]); mCachedAttrParamValues[cnt] = nsnull;
mAttrVals[cnt] = nsnull;
} }
} }
if (nsnull != mAttrNames) if (nsnull != mCachedAttrParamNames) {
{ PR_Free(mCachedAttrParamNames);
PR_Free(mAttrNames); mCachedAttrParamNames = nsnull;
mAttrNames = nsnull;
} }
if (nsnull != mAttrVals) if (nsnull != mCachedAttrParamValues) {
{ PR_Free(mCachedAttrParamValues);
PR_Free(mAttrVals); mCachedAttrParamValues = nsnull;
mAttrVals = nsnull;
} }
for (cnt = 0; cnt < mNumParams; cnt++) if (nsnull != mDocumentBase) {
{
if ((nsnull != mParamNames) && (nsnull != mParamNames[cnt]))
{
PR_Free(mParamNames[cnt]);
mParamNames[cnt] = nsnull;
}
if ((nsnull != mParamVals) && (nsnull != mParamVals[cnt]))
{
PR_Free(mParamVals[cnt]);
mParamVals[cnt] = nsnull;
}
}
if (nsnull != mParamNames)
{
PR_Free(mParamNames);
mParamNames = nsnull;
}
if (nsnull != mParamVals)
{
PR_Free(mParamVals);
mParamVals = nsnull;
}
if (nsnull != mDocumentBase)
{
nsCRT::free(mDocumentBase); nsCRT::free(mDocumentBase);
mDocumentBase = nsnull; mDocumentBase = nsnull;
} }
if (nsnull != mTagText) if (nsnull != mTagText) {
{
nsCRT::free(mTagText); nsCRT::free(mTagText);
mTagText = nsnull; mTagText = nsnull;
} }
@ -2063,90 +2030,12 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetAttributes(PRUint16& n,
const char*const*& names, const char*const*& names,
const char*const*& values) const char*const*& values)
{ {
nsresult rv; nsresult rv = EnsureCachedAttrParamArrays();
nsIContent* iContent; NS_ENSURE_SUCCESS(rv, rv);
if ((nsnull == mAttrNames) && (nsnull != mOwner)) { n = mNumCachedAttrs;
rv = mOwner->GetContent(&iContent); names = (const char **)mCachedAttrParamNames;
values = (const char **)mCachedAttrParamValues;
if (NS_SUCCEEDED(rv)) {
PRInt32 count;
if (NS_SUCCEEDED(iContent->GetAttrCount(count))) {
PRInt32 index;
mAttrNames = (char **)PR_Calloc(sizeof(char *) * count, 1);
mAttrVals = (char **)PR_Calloc(sizeof(char *) * count, 1);
mNumAttrs = 0;
if ((nsnull != mAttrNames) && (nsnull != mAttrVals)) {
for (index = 0; index < count; index++) {
PRInt32 nameSpaceID;
nsCOMPtr<nsIAtom> atom;
nsCOMPtr<nsIAtom> prefix;
iContent->GetAttrNameAt(index, nameSpaceID,
*getter_AddRefs(atom),
*getter_AddRefs(prefix));
nsAutoString value;
if (NS_CONTENT_ATTR_HAS_VALUE ==
iContent->GetAttr(nameSpaceID, atom, value)) {
nsAutoString name;
atom->ToString(name);
/* Changing to ToNewUTF8String addressing 17169, 39789
mAttrNames[mNumAttrs] = (char *)PR_Malloc(name.Length() + 1);
mAttrVals[mNumAttrs] = (char *)PR_Malloc(value.Length() + 1);
if ((nsnull != mAttrNames[mNumAttrs]) &&
(nsnull != mAttrVals[mNumAttrs]))
{
name.ToCString(mAttrNames[mNumAttrs], name.Length() + 1);
value.ToCString(mAttrVals[mNumAttrs], value.Length() + 1);
mNumAttrs++;
}
else
{
if (nsnull != mAttrNames[mNumAttrs])
{
PR_Free(mAttrNames[mNumAttrs]);
mAttrNames[mNumAttrs] = nsnull;
}
if (nsnull != mAttrVals[mNumAttrs])
{
PR_Free(mAttrVals[mNumAttrs]);
mAttrVals[mNumAttrs] = nsnull;
}
}
*/
mAttrNames[mNumAttrs] = ToNewUTF8String(name);
mAttrVals[mNumAttrs] = ToNewUTF8String(value);
mNumAttrs++;
}
}
}
else {
rv = NS_ERROR_OUT_OF_MEMORY;
if (nsnull != mAttrVals) {
PR_Free(mAttrVals);
mAttrVals = nsnull;
}
if (nsnull != mAttrNames) {
PR_Free(mAttrNames);
mAttrNames = nsnull;
}
}
}
NS_RELEASE(iContent);
}
}
else {
rv = NS_OK;
}
n = mNumAttrs;
names = (const char **)mAttrNames;
values = (const char **)mAttrVals;
return rv; return rv;
} }
@ -2155,18 +2044,15 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetAttribute(const char* name, const char*
{ {
NS_ENSURE_ARG_POINTER(name); NS_ENSURE_ARG_POINTER(name);
NS_ENSURE_ARG_POINTER(result); NS_ENSURE_ARG_POINTER(result);
if (nsnull == mAttrNames) {
PRUint16 numattrs; nsresult rv = EnsureCachedAttrParamArrays();
const char * const *names, * const *vals; NS_ENSURE_SUCCESS(rv, rv);
GetAttributes(numattrs, names, vals); *result = nsnull;
}
*result = NULL; for (int i = 0; i < mNumCachedAttrs; i++) {
if (0 == PL_strcasecmp(mCachedAttrParamNames[i], name)) {
for (int i = 0; i < mNumAttrs; i++) { *result = mCachedAttrParamValues[i];
if (0 == PL_strcasecmp(mAttrNames[i], name)) {
*result = mAttrVals[i];
return NS_OK; return NS_OK;
} }
} }
@ -2527,148 +2413,16 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetTagText(const char* *result)
NS_IMETHODIMP nsPluginInstanceOwner::GetParameters(PRUint16& n, const char*const*& names, const char*const*& values) NS_IMETHODIMP nsPluginInstanceOwner::GetParameters(PRUint16& n, const char*const*& names, const char*const*& values)
{ {
nsresult rv = NS_ERROR_FAILURE; nsresult rv = EnsureCachedAttrParamArrays();
NS_ENSURE_SUCCESS(rv, rv);
if ((nsnull == mParamNames) && (nsnull != mOwner)) // make sure we have at least one param tag because embed's don't have any
{ if (!mNumCachedParams)
nsIContent *cont; return NS_ERROR_FAILURE;
mOwner->GetContent(&cont); n = mNumCachedParams;
names = (const char **)(mCachedAttrParamNames + mNumCachedAttrs + 1);
if (nsnull != cont) values = (const char **)(mCachedAttrParamValues + mNumCachedAttrs + 1);
{
PRBool haskids = PR_FALSE;
cont->CanContainChildren(haskids);
if (PR_TRUE == haskids)
{
PRInt32 numkids, idx, numparams = 0;
cont->ChildCount(numkids);
//first pass, count number of param tags...
for (idx = 0; idx < numkids; idx++)
{
nsIContent *kid;
cont->ChildAt(idx, kid);
if (nsnull != kid)
{
nsIAtom *atom;
kid->GetTag(atom);
if (nsnull != atom)
{
if (atom == nsHTMLAtoms::param)
numparams++;
NS_RELEASE(atom);
}
NS_RELEASE(kid);
}
}
if (numparams > 0)
{
//now we need to create arrays
//representing the parameter name/value pairs...
mParamNames = (char **)PR_Calloc(sizeof(char *) * numparams, 1);
mParamVals = (char **)PR_Calloc(sizeof(char *) * numparams, 1);
if ((nsnull != mParamNames) && (nsnull != mParamVals))
{
for (idx = 0; idx < numkids; idx++)
{
nsIContent *kid;
cont->ChildAt(idx, kid);
if (nsnull != kid)
{
nsIAtom *atom;
kid->GetTag(atom);
if (nsnull != atom)
{
if (atom == nsHTMLAtoms::param)
{
nsAutoString val, name;
//add param to list...
if ((NS_CONTENT_ATTR_HAS_VALUE == kid->GetAttr(kNameSpaceID_HTML, nsHTMLAtoms::name, name)) &&
(NS_CONTENT_ATTR_HAS_VALUE == kid->GetAttr(kNameSpaceID_HTML, nsHTMLAtoms::value, val)))
{
/* Changing to ToNewUTF8String addressing 17169, 39789
mParamNames[mNumParams] = (char *)PR_Malloc(name.Length() + 1);
mParamVals[mNumParams] = (char *)PR_Malloc(val.Length() + 1);
if ((nsnull != mParamNames[mNumParams]) &&
(nsnull != mParamVals[mNumParams]))
{
name.ToCString(mParamNames[mNumParams], name.Length() + 1);
val.ToCString(mParamVals[mNumParams], val.Length() + 1);
mNumParams++;
}
else
{
if (nsnull != mParamNames[mNumParams])
{
PR_Free(mParamNames[mNumParams]);
mParamNames[mNumParams] = nsnull;
}
if (nsnull != mParamVals[mNumParams])
{
PR_Free(mParamVals[mNumParams]);
mParamVals[mNumParams] = nsnull;
}
}
*/
/* According to the HTML 4.01 spec, at
* http://www.w3.org/TR/html4/types.html#type-cdata
* ''User agents may ignore leading and trailing
* white space in CDATA attribute values (e.g., "
* myval " may be interpreted as "myval"). Authors
* should not declare attribute values with
* leading or trailing white space.''
*/
name.CompressWhitespace();
val.CompressWhitespace();
mParamNames[mNumParams] = ToNewUTF8String(name);
mParamVals[mNumParams] = ToNewUTF8String(val);
mNumParams++;
}
}
NS_RELEASE(atom);
}
}
NS_RELEASE(kid);
}
}
}
}
rv = NS_OK;
NS_RELEASE(cont);
}
}
n = mNumParams;
names = (const char **)mParamNames;
values = (const char **)mParamVals;
return rv; return rv;
} }
@ -2677,32 +2431,20 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetParameter(const char* name, const char*
{ {
NS_ENSURE_ARG_POINTER(name); NS_ENSURE_ARG_POINTER(name);
NS_ENSURE_ARG_POINTER(result); NS_ENSURE_ARG_POINTER(result);
nsresult rv;
PRInt32 count; nsresult rv = EnsureCachedAttrParamArrays();
NS_ENSURE_SUCCESS(rv, rv);
if (nsnull == mParamNames) *result = nsnull;
{
PRUint16 numattrs;
const char * const *names, * const *vals;
rv = GetParameters(numattrs, names, vals); for (int i = mNumCachedAttrs + 1; i < (mNumCachedParams + 1 + mNumCachedAttrs); i++) {
} if (0 == PL_strcasecmp(mCachedAttrParamNames[i], name)) {
*result = mCachedAttrParamValues[i];
for (count = 0; count < mNumParams; count++) return NS_OK;
{
if (0 == PL_strcasecmp(mParamNames[count], name))
{
*result = mParamVals[count];
break;
} }
} }
if (count >= mNumParams) { return NS_ERROR_FAILURE;
*result = "";
rv = NS_ERROR_FAILURE;
}
return rv;
} }
NS_IMETHODIMP nsPluginInstanceOwner::GetDocumentBase(const char* *result) NS_IMETHODIMP nsPluginInstanceOwner::GetDocumentBase(const char* *result)
@ -3000,6 +2742,155 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetMayScript(PRBool *result)
return NS_OK; return NS_OK;
} }
// Cache the attributes and/or parameters of our tag into a single set of arrays
// to be compatible with 4.x. The attributes go first, followed by a PARAM/null and
// then any PARAM tags. Also, hold the cached array around for the duration
// of the life of the instance because 4.x did. See bug 111008.
nsresult nsPluginInstanceOwner::EnsureCachedAttrParamArrays()
{
if (mCachedAttrParamValues)
return NS_OK;
NS_PRECONDITION((((mNumCachedAttrs + mNumCachedParams) == 0) && !mCachedAttrParamNames),
"re-cache of attrs/params not implemented! use the DOM node directy instead");
NS_ENSURE_TRUE(mOwner, NS_ERROR_NULL_POINTER);
// first, we need to find out how much we need to allocate for our arrays
// count up attributes
mNumCachedAttrs = 0;
nsCOMPtr<nsIContent> content;
nsresult rv = mOwner->GetContent(getter_AddRefs(content));
NS_ENSURE_TRUE(content, rv);
rv = content->GetAttrCount((PRInt32&)mNumCachedAttrs); // signed 32 bits to unsigned 16 bits conversion
NS_ENSURE_SUCCESS(rv, rv);
// now, we need to find all the PARAM tags that are children of us
// however, be carefull NOT to include any PARAMs that don't have us as a direct
// parent. For nested object (or applet) tags, be sure to only round up the
// param tags that coorespond with THIS instance. And also, weed out any bogus
// tags that may get in the way, see bug 39609. Then, with any param tag that meet our
// qualification, temporarly cache them in an nsISupportsArray until we can figure out
// what size to make our fixed char* array.
mNumCachedParams = 0;
nsCOMPtr<nsISupportsArray> ourParams;
rv = NS_NewISupportsArray(getter_AddRefs(ourParams));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMNode> mydomNode = do_QueryInterface(content);
NS_ENSURE_TRUE(mydomNode, NS_ERROR_NO_INTERFACE);
// use the DOM to get us ALL our dependant PARAM tags, even if not ours
nsCOMPtr<nsIDOMElement> mydomElement = do_QueryInterface(mydomNode);
NS_ENSURE_TRUE(mydomElement, NS_ERROR_NO_INTERFACE);
nsCOMPtr<nsIDOMNodeList> allParams;
mydomElement->GetElementsByTagName(NS_LITERAL_STRING("PARAM"), getter_AddRefs(allParams));
if (allParams) {
PRUint32 numAllParams;
allParams->GetLength(&numAllParams);
// loop through every so called dependant PARAM tag to check if it "belongs" to us
for (PRUint32 i = 0; i < numAllParams; i++) {
nsCOMPtr<nsIDOMNode> pnode;
allParams->Item(i, getter_AddRefs(pnode));
if (pnode) {
nsCOMPtr<nsIDOMElement> domelement = do_QueryInterface(pnode);
if (domelement) {
// let's NOT count up param tags that don't have a name attribute
nsAutoString name;
domelement->GetAttribute(NS_LITERAL_STRING("name"), name);
if (name.Length() > 0) {
nsCOMPtr<nsIDOMNode> parent;
nsCOMPtr<nsIDOMHTMLObjectElement> domobject;
nsCOMPtr<nsIDOMHTMLAppletElement> domapplet;
pnode->GetParentNode(getter_AddRefs(parent));
// walk up the parents of this PARAM until we find an object (or applet) tag
while (!(domobject || domapplet) && parent) {
domobject = do_QueryInterface(parent);
domapplet = do_QueryInterface(parent);
nsCOMPtr<nsIDOMNode> temp;
parent->GetParentNode(getter_AddRefs(temp));
parent = temp;
}
if (domapplet || domobject) {
parent = domapplet ? do_QueryInterface(domapplet) : do_QueryInterface(domobject);
// now check to see if this PARAM's parent is us. if so, cache it for later
if (parent.get() == mydomNode.get()) {
nsCOMPtr<nsISupports> sup = do_QueryInterface(pnode);
NS_ASSERTION(sup, "lame! DOM node does doesn't QI to nsISupports");
ourParams->AppendElement(sup);
}
}
}
}
}
}
}
ourParams->Count((PRUint32*)&mNumCachedParams); // unsigned 32 bits to unsigned 16 bits conversion
// now lets make the arrays
mCachedAttrParamNames = (char **)PR_Calloc(sizeof(char *) * (mNumCachedAttrs + 1 + mNumCachedParams), 1);
NS_ENSURE_TRUE(mCachedAttrParamNames, NS_ERROR_OUT_OF_MEMORY);
mCachedAttrParamValues = (char **)PR_Calloc(sizeof(char *) * (mNumCachedAttrs + 1 + mNumCachedParams), 1);
NS_ENSURE_TRUE(mCachedAttrParamValues, NS_ERROR_OUT_OF_MEMORY);
// let's fill in our attributes
PRInt16 c = 0;
for (PRInt16 index = 0; index < mNumCachedAttrs; index++) {
PRInt32 nameSpaceID;
nsCOMPtr<nsIAtom> atom;
nsCOMPtr<nsIAtom> prefix;
content->GetAttrNameAt(index, nameSpaceID,
*getter_AddRefs(atom),
*getter_AddRefs(prefix));
nsAutoString value;
if (NS_CONTENT_ATTR_NOT_THERE != content->GetAttr(nameSpaceID, atom, value)) {
nsAutoString name;
atom->ToString(name);
mCachedAttrParamNames [c] = ToNewUTF8String(name);
mCachedAttrParamValues[c] = ToNewUTF8String(value);
c++;
}
}
// add our PARAM and null seperator
mCachedAttrParamNames [mNumCachedAttrs + 1] = "PARAM";
mCachedAttrParamValues[mNumCachedAttrs + 1] = nsnull;
// now fill in the PARAM name/value pairs from the cached DOM nodes
c = 0;
for (PRInt16 idx = 0; idx < mNumCachedParams; idx++) {
nsCOMPtr<nsISupports> sup = ourParams->ElementAt(idx);
if (sup) {
nsCOMPtr<nsIDOMElement> param = do_QueryInterface(sup);
if (param) {
nsAutoString name;
nsAutoString value;
param->GetAttribute(NS_LITERAL_STRING("name"), name); // check for empty done above
param->GetAttribute(NS_LITERAL_STRING("value"), value);
/*
* According to the HTML 4.01 spec, at
* http://www.w3.org/TR/html4/types.html#type-cdata
* ''User agents may ignore leading and trailing
* white space in CDATA attribute values (e.g., "
* myval " may be interpreted as "myval"). Authors
* should not declare attribute values with
* leading or trailing white space.''
*/
name.CompressWhitespace(); // XXX right function?
value.CompressWhitespace();
mCachedAttrParamNames [mNumCachedAttrs + 1 + c] = ToNewUTF8String(name);
mCachedAttrParamValues[mNumCachedAttrs + 1 + c] = ToNewUTF8String(value);
c++; // rules!
}
}
}
return NS_OK;
}
// Here's where we forward events to plugins. // Here's where we forward events to plugins.
#ifdef XP_MAC #ifdef XP_MAC

Просмотреть файл

@ -796,36 +796,45 @@ NS_IMETHODIMP ns4xPluginInstance::Stop(void)
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
nsresult ns4xPluginInstance::InitializePlugin(nsIPluginInstancePeer* peer) nsresult ns4xPluginInstance::InitializePlugin(nsIPluginInstancePeer* peer)
{ {
NS_ENSURE_ARG_POINTER(peer);
mPeer = peer;
nsCOMPtr<nsIPluginTagInfo2> taginfo = do_QueryInterface(mPeer);
NS_ENSURE_TRUE(taginfo, NS_ERROR_NO_INTERFACE);
nsPluginTagType tagtype;
nsresult rv = taginfo->GetTagType(&tagtype);
NS_ENSURE_SUCCESS(rv, rv);
PRUint16 count = 0; PRUint16 count = 0;
const char* const* names = nsnull; const char* const* names = nsnull;
const char* const* values = nsnull; const char* const* values = nsnull;
nsresult rv; rv = taginfo->GetAttributes(count, names, values);
NPError error; NS_ENSURE_SUCCESS(rv, rv);
NS_ASSERTION(peer != NULL, "null peer"); // nsPluginTagType_Object or Applet may also have PARAM tags
// Note: The arrays handed back by GetParameters() are
mPeer = peer; // crafted specially to be directly behind the arrays from GetAtributes()
// with a null entry as a seperator. This is for 4.x backwards compatibility!
nsCOMPtr<nsIPluginTagInfo2> taginfo = do_QueryInterface(mPeer, &rv); // see bug 111008 for details
if (tagtype != nsPluginTagType_Embed) {
if (NS_SUCCEEDED(rv)) PRUint16 pcount = 0;
{ const char* const* pnames = nsnull;
nsPluginTagType tagtype; const char* const* pvalues = nsnull;
taginfo->GetTagType(&tagtype); if (NS_SUCCEEDED(taginfo->GetParameters(pcount, pnames, pvalues))) {
if (tagtype == nsPluginTagType_Embed) NS_ASSERTION(nsnull == values[count+1], "attribute/parameter array not setup correctly for 4.x plugins");
taginfo->GetAttributes(count, names, values); count += ++pcount; //if it's all setup correctly, then all we need is to change the count
else // nsPluginTagType_Object }
taginfo->GetParameters(count, names, values);
} }
if (fCallbacks->newp == nsnull)
return NS_ERROR_FAILURE; // XXX right error? NS_ENSURE_TRUE(fCallbacks->newp, NS_ERROR_FAILURE);
// XXX Note that the NPPluginType_* enums were crafted to be // XXX Note that the NPPluginType_* enums were crafted to be
// backward compatible... // backward compatible...
nsPluginMode mode; nsPluginMode mode;
nsMIMEType mimetype; nsMIMEType mimetype;
NPError error;
mPeer->GetMode(&mode); mPeer->GetMode(&mode);
mPeer->GetMIMEType(&mimetype); mPeer->GetMIMEType(&mimetype);