зеркало из https://github.com/mozilla/gecko-dev.git
Fix for bug 820657 (Implement the NamedGetter functionality on HTMLDocument) - refactor code to support document.all. r=bz.
--HG-- extra : rebase_source : b69d963e8931a4f62dce64d7f90b78a05c488347
This commit is contained in:
Родитель
14965e0e30
Коммит
c274fed7b6
|
@ -7120,6 +7120,76 @@ nsHTMLDocumentSH::DocumentAllTagsNewResolve(JSContext *cx, JSHandleObject obj,
|
|||
}
|
||||
|
||||
|
||||
static nsresult
|
||||
ResolveAll(JSContext* cx, nsIDocument* doc, JSObject* obj)
|
||||
{
|
||||
JSObject *proto;
|
||||
if (!::JS_GetPrototype(cx, obj, &proto)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JSObject *helper;
|
||||
if (!GetDocumentAllHelper(cx, proto, &helper)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (!::JS_GetPrototype(cx, helper ? helper : obj, &proto)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Check if the property all is defined on obj's (or helper's
|
||||
// if obj doesn't exist) prototype, if it is, don't expose our
|
||||
// document.all helper.
|
||||
|
||||
JSBool hasAll = JS_FALSE;
|
||||
if (proto && !JS_HasProperty(cx, proto, "all", &hasAll)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
if (hasAll && helper) {
|
||||
// Our helper's prototype now has an "all" property, remove
|
||||
// the helper out of the prototype chain to prevent
|
||||
// shadowing of the now defined "all" property.
|
||||
JSObject *tmp = obj, *tmpProto = tmp;
|
||||
|
||||
do {
|
||||
tmp = tmpProto;
|
||||
if (!::JS_GetPrototype(cx, tmp, &tmpProto)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
} while (tmpProto != helper);
|
||||
|
||||
::JS_SetPrototype(cx, tmp, proto);
|
||||
}
|
||||
|
||||
// If we don't already have a helper and "all" isn't already defined on
|
||||
// our prototype, create a helper.
|
||||
if (!helper && !hasAll) {
|
||||
// Print a warning so developers can stop using document.all
|
||||
PrintWarningOnConsole(cx, "DocumentAllUsed");
|
||||
|
||||
if (!::JS_GetPrototype(cx, obj, &proto)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
helper = ::JS_NewObject(cx, &sHTMLDocumentAllHelperClass,
|
||||
proto,
|
||||
::JS_GetGlobalForObject(cx, obj));
|
||||
|
||||
if (!helper) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// Insert the helper into our prototype chain. helper's prototype
|
||||
// is already obj's current prototype.
|
||||
if (!::JS_SetPrototype(cx, obj, helper)) {
|
||||
xpc::Throw(cx, NS_ERROR_UNEXPECTED);
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLDocumentSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsid id, uint32_t flags,
|
||||
|
@ -7158,69 +7228,7 @@ nsHTMLDocumentSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
|||
nsIDocument *doc = static_cast<nsIDocument*>(wrapper->Native());
|
||||
|
||||
if (doc->GetCompatibilityMode() == eCompatibility_NavQuirks) {
|
||||
JSObject *proto;
|
||||
if (!::JS_GetPrototype(cx, obj, &proto)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JSObject *helper;
|
||||
if (!GetDocumentAllHelper(cx, proto, &helper)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (!::JS_GetPrototype(cx, helper ? helper : obj, &proto)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Check if the property all is defined on obj's (or helper's
|
||||
// if obj doesn't exist) prototype, if it is, don't expose our
|
||||
// document.all helper.
|
||||
|
||||
JSBool hasAll = JS_FALSE;
|
||||
if (proto && !JS_HasProperty(cx, proto, "all", &hasAll)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
if (hasAll && helper) {
|
||||
// Our helper's prototype now has an "all" property, remove
|
||||
// the helper out of the prototype chain to prevent
|
||||
// shadowing of the now defined "all" property.
|
||||
JSObject *tmp = obj, *tmpProto = tmp;
|
||||
|
||||
do {
|
||||
tmp = tmpProto;
|
||||
if (!::JS_GetPrototype(cx, tmp, &tmpProto)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
} while (tmpProto != helper);
|
||||
|
||||
::JS_SetPrototype(cx, tmp, proto);
|
||||
}
|
||||
|
||||
// If we don't already have a helper and "all" isn't already defined on
|
||||
// our prototype, create a helper.
|
||||
if (!helper && !hasAll) {
|
||||
// Print a warning so developers can stop using document.all
|
||||
PrintWarningOnConsole(cx, "DocumentAllUsed");
|
||||
|
||||
if (!::JS_GetPrototype(cx, obj, &proto)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
helper = ::JS_NewObject(cx, &sHTMLDocumentAllHelperClass,
|
||||
proto,
|
||||
::JS_GetGlobalForObject(cx, obj));
|
||||
|
||||
if (!helper) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// Insert the helper into our prototype chain. helper's prototype
|
||||
// is already obj's current prototype.
|
||||
if (!::JS_SetPrototype(cx, obj, helper)) {
|
||||
xpc::Throw(cx, NS_ERROR_UNEXPECTED);
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
return ResolveAll(cx, doc, obj);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
Загрузка…
Ссылка в новой задаче