зеркало из https://github.com/mozilla/gecko-dev.git
Bug 877277 - Move the document.all getter into WebIDL; r=smaug
This commit is contained in:
Родитель
09bb5c9224
Коммит
88ca948d77
|
@ -201,18 +201,44 @@ nsHTMLDocument::nsHTMLDocument()
|
|||
SetIsDOMBinding();
|
||||
}
|
||||
|
||||
nsHTMLDocument::~nsHTMLDocument()
|
||||
{
|
||||
mAll = nullptr;
|
||||
NS_DROP_JS_OBJECTS(this, nsHTMLDocument);
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED_10(nsHTMLDocument, nsDocument,
|
||||
mImages,
|
||||
mApplets,
|
||||
mEmbeds,
|
||||
mLinks,
|
||||
mAnchors,
|
||||
mScripts,
|
||||
mForms,
|
||||
mFormControls,
|
||||
mWyciwygChannel,
|
||||
mMidasCommandManager)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLDocument, nsDocument)
|
||||
NS_ASSERTION(!nsCCUncollectableMarker::InGeneration(cb, tmp->GetMarkedCCGeneration()),
|
||||
"Shouldn't traverse nsHTMLDocument!");
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImages)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mApplets)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEmbeds)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLinks)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAnchors)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mScripts)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mForms)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFormControls)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWyciwygChannel)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMidasCommandManager)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHTMLDocument, nsDocument)
|
||||
tmp->mAll = nullptr;
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mImages)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mApplets)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mEmbeds)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mLinks)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAnchors)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mScripts)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mForms)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFormControls)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWyciwygChannel)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMidasCommandManager)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(nsHTMLDocument, nsDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mAll)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsHTMLDocument, nsDocument)
|
||||
NS_IMPL_RELEASE_INHERITED(nsHTMLDocument, nsDocument)
|
||||
|
@ -2310,10 +2336,6 @@ nsHTMLDocument::NamedGetter(JSContext* cx, const nsAString& aName, bool& aFound,
|
|||
nsISupports* supp = ResolveName(aName, &cache);
|
||||
if (!supp) {
|
||||
aFound = false;
|
||||
if (aName.EqualsLiteral("all")) {
|
||||
JS::Rooted<JSObject*> obj(cx, GetWrapper());
|
||||
rv = nsHTMLDocumentSH::TryResolveAll(cx, this, obj);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -2698,6 +2720,27 @@ nsHTMLDocument::GetDocumentAllResult(const nsAString& aID,
|
|||
return cont;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
nsHTMLDocument::GetAll(JSContext* aCx, ErrorResult& aRv)
|
||||
{
|
||||
if (!mAll) {
|
||||
mAll = JS_NewObject(aCx, &sHTMLDocumentAllClass, nullptr,
|
||||
JS_GetGlobalForObject(aCx, GetWrapper()));
|
||||
if (!mAll) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Make the JSObject hold a reference to this.
|
||||
JS_SetPrivate(mAll, static_cast<nsINode*>(this));
|
||||
NS_ADDREF_THIS();
|
||||
|
||||
NS_HOLD_JS_OBJECTS(this, nsHTMLDocument);
|
||||
}
|
||||
|
||||
return mAll;
|
||||
}
|
||||
|
||||
static void
|
||||
NotifyEditableStateChange(nsINode *aNode, nsIDocument *aDocument)
|
||||
{
|
||||
|
|
|
@ -44,13 +44,14 @@ public:
|
|||
using nsDocument::GetPlugins;
|
||||
|
||||
nsHTMLDocument();
|
||||
~nsHTMLDocument();
|
||||
virtual nsresult Init() MOZ_OVERRIDE;
|
||||
|
||||
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) MOZ_OVERRIDE;
|
||||
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void) MOZ_OVERRIDE;
|
||||
NS_IMETHOD_(nsrefcnt) Release(void) MOZ_OVERRIDE;
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(nsHTMLDocument,
|
||||
nsDocument)
|
||||
|
||||
// nsIDocument
|
||||
virtual void Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) MOZ_OVERRIDE;
|
||||
virtual void ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup,
|
||||
nsIPrincipal* aPrincipal) MOZ_OVERRIDE;
|
||||
|
@ -69,9 +70,15 @@ public:
|
|||
virtual void StopDocumentLoad() MOZ_OVERRIDE;
|
||||
|
||||
virtual void BeginLoad() MOZ_OVERRIDE;
|
||||
|
||||
virtual void EndLoad() MOZ_OVERRIDE;
|
||||
|
||||
virtual NS_HIDDEN_(void) Destroy() MOZ_OVERRIDE
|
||||
{
|
||||
mAll = nullptr;
|
||||
nsDocument::Destroy();
|
||||
}
|
||||
|
||||
// nsIHTMLDocument
|
||||
virtual void SetCompatibilityMode(nsCompatibility aMode) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool IsWriting() MOZ_OVERRIDE
|
||||
|
@ -108,6 +115,7 @@ public:
|
|||
nsISupports *GetDocumentAllResult(const nsAString& aID,
|
||||
nsWrapperCache **aCache,
|
||||
nsresult *aResult);
|
||||
JSObject* GetAll(JSContext* aCx, mozilla::ErrorResult& aRv);
|
||||
|
||||
nsISupports* ResolveName(const nsAString& aName, nsWrapperCache **aCache);
|
||||
virtual already_AddRefed<nsISupports> ResolveName(const nsAString& aName,
|
||||
|
@ -155,8 +163,6 @@ public:
|
|||
|
||||
void EndUpdate(nsUpdateType aUpdateType) MOZ_OVERRIDE;
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHTMLDocument, nsDocument)
|
||||
|
||||
virtual nsresult SetEditingState(EditingState aState) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
|
||||
|
@ -294,6 +300,8 @@ protected:
|
|||
nsRefPtr<nsContentList> mForms;
|
||||
nsRefPtr<nsContentList> mFormControls;
|
||||
|
||||
JSObject* mAll;
|
||||
|
||||
/** # of forms in the document, synchronously set */
|
||||
int32_t mNumForms;
|
||||
|
||||
|
|
|
@ -892,7 +892,6 @@ jsid nsDOMClassInfo::sTop_id = JSID_VOID;
|
|||
jsid nsDOMClassInfo::sDocument_id = JSID_VOID;
|
||||
jsid nsDOMClassInfo::sFrames_id = JSID_VOID;
|
||||
jsid nsDOMClassInfo::sSelf_id = JSID_VOID;
|
||||
jsid nsDOMClassInfo::sAll_id = JSID_VOID;
|
||||
jsid nsDOMClassInfo::sWrappedJSObject_id = JSID_VOID;
|
||||
jsid nsDOMClassInfo::sURL_id = JSID_VOID;
|
||||
jsid nsDOMClassInfo::sOnload_id = JSID_VOID;
|
||||
|
@ -1088,7 +1087,6 @@ nsDOMClassInfo::DefineStaticJSVals(JSContext *cx)
|
|||
SET_JSID_TO_STRING(sDocument_id, cx, "document");
|
||||
SET_JSID_TO_STRING(sFrames_id, cx, "frames");
|
||||
SET_JSID_TO_STRING(sSelf_id, cx, "self");
|
||||
SET_JSID_TO_STRING(sAll_id, cx, "all");
|
||||
SET_JSID_TO_STRING(sWrappedJSObject_id, cx, "wrappedJSObject");
|
||||
SET_JSID_TO_STRING(sURL_id, cx, "URL");
|
||||
SET_JSID_TO_STRING(sOnload_id, cx, "onload");
|
||||
|
@ -2611,7 +2609,6 @@ nsDOMClassInfo::ShutDown()
|
|||
sDocument_id = JSID_VOID;
|
||||
sFrames_id = JSID_VOID;
|
||||
sSelf_id = JSID_VOID;
|
||||
sAll_id = JSID_VOID;
|
||||
sWrappedJSObject_id = JSID_VOID;
|
||||
sOnload_id = JSID_VOID;
|
||||
sOnerror_id = JSID_VOID;
|
||||
|
@ -2725,8 +2722,9 @@ ChildWindowGetter(JSContext *cx, JSHandleObject obj, JSHandleId id,
|
|||
static nsHTMLDocument*
|
||||
GetDocument(JSObject *obj)
|
||||
{
|
||||
MOZ_ASSERT(js::GetObjectJSClass(obj) == &sHTMLDocumentAllClass);
|
||||
return static_cast<nsHTMLDocument*>(
|
||||
static_cast<nsIHTMLDocument*>(::JS_GetPrivate(obj)));
|
||||
static_cast<nsINode*>(JS_GetPrivate(obj)));
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -5625,9 +5623,9 @@ nsNamedArraySH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
|||
}
|
||||
|
||||
|
||||
// HTMLDocument helper
|
||||
// HTMLAllCollection
|
||||
|
||||
static JSClass sHTMLDocumentAllClass = {
|
||||
JSClass sHTMLDocumentAllClass = {
|
||||
"HTML document.all class",
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_NEW_RESOLVE |
|
||||
JSCLASS_EMULATES_UNDEFINED | JSCLASS_HAS_RESERVED_SLOTS(1),
|
||||
|
@ -5644,19 +5642,6 @@ static JSClass sHTMLDocumentAllClass = {
|
|||
};
|
||||
|
||||
|
||||
static JSClass sHTMLDocumentAllHelperClass = {
|
||||
"HTML document.all helper class",
|
||||
JSCLASS_NEW_RESOLVE,
|
||||
JS_PropertyStub, /* addProperty */
|
||||
JS_DeletePropertyStub, /* delProperty */
|
||||
nsHTMLDocumentSH::DocumentAllHelperGetProperty, /* getProperty */
|
||||
JS_StrictPropertyStub, /* setProperty */
|
||||
JS_EnumerateStub,
|
||||
(JSResolveOp)nsHTMLDocumentSH::DocumentAllHelperNewResolve,
|
||||
JS_ConvertStub
|
||||
};
|
||||
|
||||
|
||||
// static
|
||||
JSBool
|
||||
nsHTMLDocumentSH::GetDocumentAllNodeList(JSContext *cx,
|
||||
|
@ -5860,13 +5845,10 @@ nsHTMLDocumentSH::DocumentAllNewResolve(JSContext *cx, JSHandleObject obj, JSHan
|
|||
return ok;
|
||||
}
|
||||
|
||||
// Finalize hook used by document related JS objects, but also by
|
||||
// sGlobalScopePolluterClass!
|
||||
|
||||
void
|
||||
nsHTMLDocumentSH::ReleaseDocument(JSFreeOp *fop, JSObject *obj)
|
||||
{
|
||||
nsIHTMLDocument *doc = static_cast<nsIHTMLDocument *>(JS_GetPrivate(obj));
|
||||
nsIHTMLDocument* doc = GetDocument(obj);
|
||||
if (doc) {
|
||||
xpc::DeferredRelease(doc);
|
||||
}
|
||||
|
@ -5916,155 +5898,6 @@ nsHTMLDocumentSH::CallToGetPropMapper(JSContext *cx, unsigned argc, jsval *vp)
|
|||
}
|
||||
|
||||
|
||||
static inline bool
|
||||
GetDocumentAllHelper(JSContext *cx, JS::Handle<JSObject*> aObj, JSObject **result)
|
||||
{
|
||||
JS::Rooted<JSObject*> obj(cx, aObj);
|
||||
while (obj && JS_GetClass(obj) != &sHTMLDocumentAllHelperClass) {
|
||||
if (!::JS_GetPrototype(cx, obj, obj.address())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*result = obj;
|
||||
return true;
|
||||
}
|
||||
|
||||
JSBool
|
||||
nsHTMLDocumentSH::DocumentAllHelperGetProperty(JSContext *cx, JSHandleObject obj,
|
||||
JSHandleId id, JSMutableHandleValue vp)
|
||||
{
|
||||
if (nsDOMClassInfo::sAll_id != id) {
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
if (!vp.isObjectOrNull()) {
|
||||
// First time through, create the collection, and set the
|
||||
// document as its private nsISupports data.
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIHTMLDocument> doc = do_QueryWrapper(cx, obj, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
xpc::Throw(cx, rv);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> all(cx);
|
||||
all = ::JS_NewObject(cx, &sHTMLDocumentAllClass, nullptr,
|
||||
::JS_GetGlobalForObject(cx, obj));
|
||||
if (!all) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
// Let the JSObject take over ownership of doc.
|
||||
::JS_SetPrivate(all, doc.forget().get());
|
||||
|
||||
vp.setObject(*all);
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool
|
||||
nsHTMLDocumentSH::DocumentAllHelperNewResolve(JSContext *cx, JSHandleObject obj,
|
||||
JSHandleId id, unsigned flags,
|
||||
JS::MutableHandle<JSObject*> objp)
|
||||
{
|
||||
if (nsDOMClassInfo::sAll_id == id) {
|
||||
// document.all is resolved for the first time. Define it.
|
||||
JS::Rooted<JSObject*> helper(cx);
|
||||
if (!GetDocumentAllHelper(cx, obj, helper.address())) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if (helper) {
|
||||
if (!::JS_DefineProperty(cx, helper, "all", JSVAL_VOID, nullptr, nullptr,
|
||||
JSPROP_ENUMERATE)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
objp.set(helper);
|
||||
}
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static nsresult
|
||||
ResolveAll(JSContext* cx, nsIDocument* doc, JS::Handle<JSObject*> obj)
|
||||
{
|
||||
JS::Rooted<JSObject*> proto(cx);
|
||||
if (!::JS_GetPrototype(cx, obj, proto.address())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> helper(cx);
|
||||
if (!GetDocumentAllHelper(cx, proto, helper.address())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (!::JS_GetPrototype(cx, helper ? helper : obj, proto.address())) {
|
||||
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.
|
||||
JS::Rooted<JSObject*> tmp(cx, obj), tmpProto(cx, tmp);
|
||||
|
||||
do {
|
||||
tmp = tmpProto;
|
||||
if (!::JS_GetPrototype(cx, tmp, tmpProto.address())) {
|
||||
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) {
|
||||
if (!::JS_GetPrototype(cx, obj, proto.address())) {
|
||||
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;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLDocumentSH::TryResolveAll(JSContext* cx, nsHTMLDocument* doc,
|
||||
JS::Handle<JSObject*> obj)
|
||||
{
|
||||
JSAutoCompartment ac(cx, obj);
|
||||
return ResolveAll(cx, doc, obj);
|
||||
}
|
||||
|
||||
// HTMLFormElement helper
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -217,7 +217,6 @@ public:
|
|||
static jsid sDocument_id;
|
||||
static jsid sFrames_id;
|
||||
static jsid sSelf_id;
|
||||
static jsid sAll_id;
|
||||
static jsid sJava_id;
|
||||
static jsid sPackages_id;
|
||||
static jsid sWrappedJSObject_id;
|
||||
|
@ -591,7 +590,9 @@ private:
|
|||
};
|
||||
|
||||
|
||||
// HTMLDocument helper
|
||||
// HTMLAllCollection
|
||||
|
||||
extern JSClass sHTMLDocumentAllClass;
|
||||
|
||||
class nsHTMLDocumentSH
|
||||
{
|
||||
|
@ -606,14 +607,6 @@ public:
|
|||
unsigned flags, JS::MutableHandle<JSObject*> objp);
|
||||
static void ReleaseDocument(JSFreeOp *fop, JSObject *obj);
|
||||
static JSBool CallToGetPropMapper(JSContext *cx, unsigned argc, jsval *vp);
|
||||
static JSBool DocumentAllHelperGetProperty(JSContext *cx, JSHandleObject obj,
|
||||
JSHandleId id, JSMutableHandleValue vp);
|
||||
static JSBool DocumentAllHelperNewResolve(JSContext *cx, JSHandleObject obj,
|
||||
JSHandleId id, unsigned flags,
|
||||
JS::MutableHandle<JSObject*> objp);
|
||||
|
||||
static nsresult TryResolveAll(JSContext* cx, nsHTMLDocument* doc,
|
||||
JS::Handle<JSObject*> obj);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -65,6 +65,9 @@ interface HTMLDocument : Document {
|
|||
|
||||
void clear();
|
||||
|
||||
[Throws]
|
||||
readonly attribute object all;
|
||||
|
||||
// https://dvcs.w3.org/hg/editing/raw-file/tip/editing.html#selections
|
||||
[Throws]
|
||||
Selection getSelection();
|
||||
|
|
Загрузка…
Ссылка в новой задаче