зеркало из https://github.com/mozilla/pjs.git
Fixing xpcdom regression bug 79737 that caused problems on bugzilla. HTMLFormElement's resolve hook wasn't implemented so form controls in a form weren't shadowing DOM properties on form elements. Also fixing problem with select[n] = new Object(). r=pollmann@netscape.com, sr=jband@netscape.com
This commit is contained in:
Родитель
57401d6d98
Коммит
478c78fc7a
|
@ -66,15 +66,18 @@
|
|||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsIDOMNamedNodeMap.h"
|
||||
#include "nsIFormControl.h"
|
||||
|
||||
// HTMLFormElement helper includes
|
||||
#include "nsIForm.h"
|
||||
#include "nsIFormControl.h"
|
||||
#include "nsIDOMHTMLFormElement.h"
|
||||
#include "nsIDOMNSHTMLFormControlList.h"
|
||||
#include "nsIDOMHTMLCollection.h"
|
||||
#include "nsIHTMLDocument.h"
|
||||
|
||||
// HTMLSelectElement helper includes
|
||||
#include "nsIDOMHTMLSelectElement.h"
|
||||
|
||||
// HTMLEmbed/ObjectElement helper includes
|
||||
#include "nsIPluginInstance.h"
|
||||
#include "nsIObjectFrame.h"
|
||||
|
@ -207,7 +210,7 @@ nsDOMClassInfoData sClassInfoData[] = {
|
|||
NS_DEFINE_CLASSINFO_DATA(Navigator, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(Plugin, nsPluginSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
ARRAY_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(PluginArray, nsPluginArraySH,
|
||||
ARRAY_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(MimeType, nsDOMGenericSH,
|
||||
|
@ -369,8 +372,9 @@ nsDOMClassInfoData sClassInfoData[] = {
|
|||
ELEMENT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(HTMLScriptElement, nsElementSH,
|
||||
ELEMENT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(HTMLSelectElement, nsElementSH,
|
||||
ELEMENT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(HTMLSelectElement, nsHTMLSelectElementSH,
|
||||
ELEMENT_SCRIPTABLE_FLAGS |
|
||||
nsIXPCScriptable::WANT_GETPROPERTY)
|
||||
NS_DEFINE_CLASSINFO_DATA(HTMLSpacerElement, nsElementSH,
|
||||
ELEMENT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(HTMLSpanElement, nsElementSH,
|
||||
|
@ -2336,6 +2340,70 @@ nsHTMLDocumentSH::GetProperty(nsIXPConnectWrappedNative *wrapper,
|
|||
|
||||
// HTMLFormElement helper
|
||||
|
||||
// static
|
||||
nsresult
|
||||
nsHTMLFormElementSH::FindNamedItem(nsIForm *aForm, JSString *str,
|
||||
nsISupports **aResult)
|
||||
{
|
||||
*aResult = nsnull;
|
||||
|
||||
nsLiteralString name(NS_REINTERPRET_CAST(const PRUnichar *,
|
||||
::JS_GetStringChars(str)),
|
||||
::JS_GetStringLength(str));
|
||||
|
||||
aForm->ResolveName(name, aResult);
|
||||
|
||||
if (!*aResult) {
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aForm));
|
||||
nsCOMPtr<nsIDOMHTMLFormElement> form_element(do_QueryInterface(aForm));
|
||||
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
content->GetDocument(*getter_AddRefs(doc));
|
||||
|
||||
nsCOMPtr<nsIHTMLDocument> html_doc(do_QueryInterface(doc));
|
||||
|
||||
if (html_doc && form_element) {
|
||||
html_doc->ResolveName(name, form_element, aResult);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLFormElementSH::NewResolve(nsIXPConnectWrappedNative *wrapper,
|
||||
JSContext *cx, JSObject *obj, jsval id,
|
||||
PRUint32 flags, JSObject **objp,
|
||||
PRBool *_retval)
|
||||
{
|
||||
if ((!(JSRESOLVE_ASSIGNING & flags)) && JSVAL_IS_STRING(id)) {
|
||||
nsCOMPtr<nsISupports> native;
|
||||
|
||||
wrapper->GetNative(getter_AddRefs(native));
|
||||
NS_ABORT_IF_FALSE(native, "No native!");
|
||||
|
||||
nsCOMPtr<nsIForm> form(do_QueryInterface(native));
|
||||
nsCOMPtr<nsISupports> result;
|
||||
|
||||
JSString *str = JSVAL_TO_STRING(id);
|
||||
|
||||
FindNamedItem(form, str, getter_AddRefs(result));
|
||||
|
||||
if (result) {
|
||||
*_retval = ::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str),
|
||||
::JS_GetStringLength(str),
|
||||
JSVAL_VOID, nsnull, nsnull, 0);
|
||||
|
||||
*objp = obj;
|
||||
|
||||
return *_retval ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return nsElementSH::NewResolve(wrapper, cx, obj, id, flags, objp, _retval);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLFormElementSH::GetProperty(nsIXPConnectWrappedNative *wrapper,
|
||||
JSContext *cx, JSObject *obj, jsval id,
|
||||
|
@ -2349,29 +2417,11 @@ nsHTMLFormElementSH::GetProperty(nsIXPConnectWrappedNative *wrapper,
|
|||
nsCOMPtr<nsIForm> form(do_QueryInterface(native));
|
||||
|
||||
if (JSVAL_IS_STRING(id)) {
|
||||
JSString *str = JSVAL_TO_STRING(id);
|
||||
|
||||
nsLiteralString name(NS_REINTERPRET_CAST(const PRUnichar *,
|
||||
::JS_GetStringChars(str)),
|
||||
::JS_GetStringLength(str));
|
||||
|
||||
nsCOMPtr<nsISupports> result;
|
||||
|
||||
form->ResolveName(name, getter_AddRefs(result));
|
||||
JSString *str = JSVAL_TO_STRING(id);
|
||||
|
||||
if (!result) {
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(native));
|
||||
nsCOMPtr<nsIDOMHTMLFormElement> form_element(do_QueryInterface(native));
|
||||
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
content->GetDocument(*getter_AddRefs(doc));
|
||||
|
||||
nsCOMPtr<nsIHTMLDocument> html_doc(do_QueryInterface(doc));
|
||||
|
||||
if (html_doc && form_element) {
|
||||
html_doc->ResolveName(name, form_element, getter_AddRefs(result));
|
||||
}
|
||||
}
|
||||
FindNamedItem(form, str, getter_AddRefs(result));
|
||||
|
||||
if (result) {
|
||||
// Wrap result, result can be either an element or a list of
|
||||
|
@ -2398,6 +2448,105 @@ nsHTMLFormElementSH::GetProperty(nsIXPConnectWrappedNative *wrapper,
|
|||
}
|
||||
|
||||
|
||||
// HTMLSelectElement helper
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLSelectElementSH::GetProperty(nsIXPConnectWrappedNative *wrapper,
|
||||
JSContext *cx, JSObject *obj, jsval id,
|
||||
jsval *vp, PRBool *_retval)
|
||||
{
|
||||
int32 n = -1;
|
||||
|
||||
if ((JSVAL_IS_NUMBER(id) || JSVAL_IS_STRING(id)) &&
|
||||
::JS_ValueToInt32(cx, id, &n) && n >= 0) {
|
||||
nsCOMPtr<nsISupports> native;
|
||||
|
||||
wrapper->GetNative(getter_AddRefs(native));
|
||||
NS_ABORT_IF_FALSE(native, "No native!");
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLSelectElement> s(do_QueryInterface(native));
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLCollection> options;
|
||||
|
||||
s->GetOptions(getter_AddRefs(options));
|
||||
|
||||
if (options) {
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
|
||||
options->Item(n, getter_AddRefs(node));
|
||||
|
||||
return WrapNative(cx, ::JS_GetGlobalObject(cx), node,
|
||||
NS_GET_IID(nsIDOMNode), vp);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
nsHTMLSelectElementSH::SetOption(JSContext *cx, jsval *vp, PRUint32 aIndex,
|
||||
nsIDOMNSHTMLOptionCollection *aOptCollection)
|
||||
{
|
||||
// vp must refer to an object
|
||||
if (!JSVAL_IS_OBJECT(*vp) && !::JS_ConvertValue(cx, *vp, JSTYPE_OBJECT,
|
||||
vp)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLOptionElement> new_option;
|
||||
|
||||
if (!JSVAL_IS_NULL(*vp)) {
|
||||
nsCOMPtr<nsIXPConnectWrappedNative> new_wrapper;
|
||||
nsresult rv;
|
||||
|
||||
rv = sXPConnect->GetWrappedNativeOfJSObject(cx, JSVAL_TO_OBJECT(*vp),
|
||||
getter_AddRefs(new_wrapper));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsISupports> native;
|
||||
new_wrapper->GetNative(getter_AddRefs(native));
|
||||
|
||||
new_option = do_QueryInterface(native);
|
||||
|
||||
if (!new_option) {
|
||||
// Someone is trying to set an option to a non-option object.
|
||||
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
return aOptCollection->SetOption(aIndex, new_option);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLSelectElementSH::SetProperty(nsIXPConnectWrappedNative *wrapper,
|
||||
JSContext *cx, JSObject *obj, jsval id,
|
||||
jsval *vp, PRBool *_retval)
|
||||
{
|
||||
int32 n = -1;
|
||||
|
||||
if ((!JSVAL_IS_NUMBER(id) && !JSVAL_IS_STRING(id)) ||
|
||||
!::JS_ValueToInt32(cx, id, &n) || n < 0) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports> native;
|
||||
wrapper->GetNative(getter_AddRefs(native));
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLSelectElement> select(do_QueryInterface(native));
|
||||
NS_ENSURE_TRUE(select, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLCollection> options;
|
||||
select->GetOptions(getter_AddRefs(options));
|
||||
|
||||
nsCOMPtr<nsIDOMNSHTMLOptionCollection> oc(do_QueryInterface(options));
|
||||
NS_ENSURE_TRUE(oc, NS_ERROR_UNEXPECTED);
|
||||
|
||||
return SetOption(cx, vp, n, oc);
|
||||
}
|
||||
|
||||
|
||||
// HTMLObject/EmbedElement helper
|
||||
|
||||
// This resolve hook makes embed.nsIFoo work as if
|
||||
|
@ -2803,45 +2952,20 @@ nsHTMLOptionCollectionSH::SetProperty(nsIXPConnectWrappedNative *wrapper,
|
|||
JSContext *cx, JSObject *obj, jsval id,
|
||||
jsval *vp, PRBool *_retval)
|
||||
{
|
||||
if (!JSVAL_IS_INT(id)) {
|
||||
int32 n = -1;
|
||||
|
||||
if ((!JSVAL_IS_NUMBER(id) && !JSVAL_IS_STRING(id)) ||
|
||||
!::JS_ValueToInt32(cx, id, &n) || n < 0) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// vp must refer to an object
|
||||
if (!JSVAL_IS_OBJECT(*vp) && !::JS_ConvertValue(cx, *vp, JSTYPE_OBJECT,
|
||||
vp)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLOptionElement> new_option;
|
||||
|
||||
if (!JSVAL_IS_NULL(*vp)) {
|
||||
nsCOMPtr<nsIXPConnectWrappedNative> new_wrapper;
|
||||
nsresult rv;
|
||||
|
||||
rv = sXPConnect->GetWrappedNativeOfJSObject(cx, JSVAL_TO_OBJECT(*vp),
|
||||
getter_AddRefs(new_wrapper));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsISupports> native;
|
||||
new_wrapper->GetNative(getter_AddRefs(native));
|
||||
|
||||
new_option = do_QueryInterface(native);
|
||||
|
||||
if (!new_option) {
|
||||
// Someone is trying to set an option to a non-option object.
|
||||
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports> native;
|
||||
wrapper->GetNative(getter_AddRefs(native));
|
||||
|
||||
nsCOMPtr<nsIDOMNSHTMLOptionCollection> oc(do_QueryInterface(native));
|
||||
NS_ENSURE_TRUE(oc, NS_ERROR_UNEXPECTED);
|
||||
|
||||
return oc->SetOption(JSVAL_TO_INT(id), new_option);
|
||||
return nsHTMLSelectElementSH::SetOption(cx, vp, n, oc);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -29,7 +29,9 @@
|
|||
#include "jsapi.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
|
||||
class nsIDOMNSHTMLOptionCollection;
|
||||
class nsIPluginInstance;
|
||||
class nsIForm;
|
||||
|
||||
struct nsDOMClassInfoData;
|
||||
typedef void (*GetDOMClassIIDsFnc)(nsVoidArray& aArray);
|
||||
|
@ -464,7 +466,13 @@ protected:
|
|||
{
|
||||
}
|
||||
|
||||
static nsresult FindNamedItem(nsIForm *aForm, JSString *str,
|
||||
nsISupports **aResult);
|
||||
|
||||
public:
|
||||
NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsval id, PRUint32 flags,
|
||||
JSObject **objp, PRBool *_retval);
|
||||
NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsval id, jsval *vp,
|
||||
PRBool *_retval);
|
||||
|
@ -476,6 +484,36 @@ public:
|
|||
};
|
||||
|
||||
|
||||
// HTMLSelectElement helper
|
||||
|
||||
class nsHTMLSelectElementSH : public nsElementSH
|
||||
{
|
||||
protected:
|
||||
nsHTMLSelectElementSH(nsDOMClassInfoID aID) : nsElementSH(aID)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~nsHTMLSelectElementSH()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsval id, jsval *vp,
|
||||
PRBool *_retval);
|
||||
NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsval id, jsval *vp, PRBool *_retval);
|
||||
|
||||
static nsresult SetOption(JSContext *cx, jsval *vp, PRUint32 aIndex,
|
||||
nsIDOMNSHTMLOptionCollection *aOptCollection);
|
||||
|
||||
static nsIClassInfo *doCreate(nsDOMClassInfoID aID)
|
||||
{
|
||||
return new nsHTMLSelectElementSH(aID);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Base helper for external HTML object (such as a plugin or an
|
||||
// applet)
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче