mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 890193. Make the XML prettyprinter actually drop its binding when it unhooks, and remove the now-dead concept of "style binding" in the process. r=mrbkap
This commit is contained in:
parent
94bdd2756a
commit
e787289888
@ -442,11 +442,6 @@ nsBindingManager::ClearBinding(nsIContent* aContent)
|
||||
// For now we can only handle removing a binding if it's the only one
|
||||
NS_ENSURE_FALSE(binding->GetBaseBinding(), NS_ERROR_FAILURE);
|
||||
|
||||
// Make sure it isn't a style binding
|
||||
if (binding->IsStyleBinding()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Hold strong ref in case removing the binding tries to close the
|
||||
// window or something.
|
||||
// XXXbz should that be ownerdoc? Wouldn't we need a ref to the
|
||||
|
@ -142,8 +142,7 @@ nsXBLJSClass::Destroy()
|
||||
|
||||
// Constructors/Destructors
|
||||
nsXBLBinding::nsXBLBinding(nsXBLPrototypeBinding* aBinding)
|
||||
: mIsStyleBinding(true),
|
||||
mMarkedForDeath(false),
|
||||
: mMarkedForDeath(false),
|
||||
mPrototypeBinding(aBinding)
|
||||
{
|
||||
NS_ASSERTION(mPrototypeBinding, "Must have a prototype binding!");
|
||||
@ -714,95 +713,92 @@ nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocumen
|
||||
if (aOldDocument == aNewDocument)
|
||||
return;
|
||||
|
||||
// Only style bindings get their prototypes unhooked. First do ourselves.
|
||||
if (mIsStyleBinding) {
|
||||
// Now the binding dies. Unhook our prototypes.
|
||||
if (mPrototypeBinding->HasImplementation()) {
|
||||
nsCOMPtr<nsIScriptGlobalObject> global = do_QueryInterface(
|
||||
aOldDocument->GetScopeObject());
|
||||
if (global) {
|
||||
nsCOMPtr<nsIScriptContext> context = global->GetContext();
|
||||
if (context) {
|
||||
JSContext *cx = context->GetNativeContext();
|
||||
// Now the binding dies. Unhook our prototypes.
|
||||
if (mPrototypeBinding->HasImplementation()) {
|
||||
nsCOMPtr<nsIScriptGlobalObject> global = do_QueryInterface(
|
||||
aOldDocument->GetScopeObject());
|
||||
if (global) {
|
||||
nsCOMPtr<nsIScriptContext> context = global->GetContext();
|
||||
if (context) {
|
||||
JSContext *cx = context->GetNativeContext();
|
||||
|
||||
nsCxPusher pusher;
|
||||
pusher.Push(cx);
|
||||
nsCxPusher pusher;
|
||||
pusher.Push(cx);
|
||||
|
||||
// scope might be null if we've cycle-collected the global
|
||||
// object, since the Unlink phase of cycle collection happens
|
||||
// after JS GC finalization. But in that case, we don't care
|
||||
// about fixing the prototype chain, since everything's going
|
||||
// away immediately.
|
||||
JS::Rooted<JSObject*> scope(cx, global->GetGlobalJSObject());
|
||||
JS::Rooted<JSObject*> scriptObject(cx, mBoundElement->GetWrapper());
|
||||
if (scope && scriptObject) {
|
||||
// XXX Stay in sync! What if a layered binding has an
|
||||
// <interface>?!
|
||||
// XXXbz what does that comment mean, really? It seems to date
|
||||
// back to when there was such a thing as an <interface>, whever
|
||||
// that was...
|
||||
// scope might be null if we've cycle-collected the global
|
||||
// object, since the Unlink phase of cycle collection happens
|
||||
// after JS GC finalization. But in that case, we don't care
|
||||
// about fixing the prototype chain, since everything's going
|
||||
// away immediately.
|
||||
JS::Rooted<JSObject*> scope(cx, global->GetGlobalJSObject());
|
||||
JS::Rooted<JSObject*> scriptObject(cx, mBoundElement->GetWrapper());
|
||||
if (scope && scriptObject) {
|
||||
// XXX Stay in sync! What if a layered binding has an
|
||||
// <interface>?!
|
||||
// XXXbz what does that comment mean, really? It seems to date
|
||||
// back to when there was such a thing as an <interface>, whever
|
||||
// that was...
|
||||
|
||||
// Find the right prototype.
|
||||
JSAutoCompartment ac(cx, scriptObject);
|
||||
// Find the right prototype.
|
||||
JSAutoCompartment ac(cx, scriptObject);
|
||||
|
||||
JS::Rooted<JSObject*> base(cx, scriptObject);
|
||||
JS::Rooted<JSObject*> proto(cx);
|
||||
for ( ; true; base = proto) { // Will break out on null proto
|
||||
if (!JS_GetPrototype(cx, base, proto.address())) {
|
||||
return;
|
||||
}
|
||||
if (!proto) {
|
||||
break;
|
||||
}
|
||||
|
||||
JSClass* clazz = ::JS_GetClass(proto);
|
||||
if (!clazz ||
|
||||
(~clazz->flags &
|
||||
(JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS)) ||
|
||||
JSCLASS_RESERVED_SLOTS(clazz) != 1 ||
|
||||
clazz->finalize != XBLFinalize) {
|
||||
// Clearly not the right class
|
||||
continue;
|
||||
}
|
||||
|
||||
nsRefPtr<nsXBLDocumentInfo> docInfo =
|
||||
static_cast<nsXBLDocumentInfo*>(::JS_GetPrivate(proto));
|
||||
if (!docInfo) {
|
||||
// Not the proto we seek
|
||||
continue;
|
||||
}
|
||||
|
||||
JS::Value protoBinding = ::JS_GetReservedSlot(proto, 0);
|
||||
|
||||
if (JSVAL_TO_PRIVATE(protoBinding) != mPrototypeBinding) {
|
||||
// Not the right binding
|
||||
continue;
|
||||
}
|
||||
|
||||
// Alright! This is the right prototype. Pull it out of the
|
||||
// proto chain.
|
||||
JS::Rooted<JSObject*> grandProto(cx);
|
||||
if (!JS_GetPrototype(cx, proto, grandProto.address())) {
|
||||
return;
|
||||
}
|
||||
::JS_SetPrototype(cx, base, grandProto);
|
||||
JS::Rooted<JSObject*> base(cx, scriptObject);
|
||||
JS::Rooted<JSObject*> proto(cx);
|
||||
for ( ; true; base = proto) { // Will break out on null proto
|
||||
if (!JS_GetPrototype(cx, base, proto.address())) {
|
||||
return;
|
||||
}
|
||||
if (!proto) {
|
||||
break;
|
||||
}
|
||||
|
||||
mPrototypeBinding->UndefineFields(cx, scriptObject);
|
||||
JSClass* clazz = ::JS_GetClass(proto);
|
||||
if (!clazz ||
|
||||
(~clazz->flags &
|
||||
(JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS)) ||
|
||||
JSCLASS_RESERVED_SLOTS(clazz) != 1 ||
|
||||
clazz->finalize != XBLFinalize) {
|
||||
// Clearly not the right class
|
||||
continue;
|
||||
}
|
||||
|
||||
// Don't remove the reference from the document to the
|
||||
// wrapper here since it'll be removed by the element
|
||||
// itself when that's taken out of the document.
|
||||
nsRefPtr<nsXBLDocumentInfo> docInfo =
|
||||
static_cast<nsXBLDocumentInfo*>(::JS_GetPrivate(proto));
|
||||
if (!docInfo) {
|
||||
// Not the proto we seek
|
||||
continue;
|
||||
}
|
||||
|
||||
JS::Value protoBinding = ::JS_GetReservedSlot(proto, 0);
|
||||
|
||||
if (JSVAL_TO_PRIVATE(protoBinding) != mPrototypeBinding) {
|
||||
// Not the right binding
|
||||
continue;
|
||||
}
|
||||
|
||||
// Alright! This is the right prototype. Pull it out of the
|
||||
// proto chain.
|
||||
JS::Rooted<JSObject*> grandProto(cx);
|
||||
if (!JS_GetPrototype(cx, proto, grandProto.address())) {
|
||||
return;
|
||||
}
|
||||
::JS_SetPrototype(cx, base, grandProto);
|
||||
break;
|
||||
}
|
||||
|
||||
mPrototypeBinding->UndefineFields(cx, scriptObject);
|
||||
|
||||
// Don't remove the reference from the document to the
|
||||
// wrapper here since it'll be removed by the element
|
||||
// itself when that's taken out of the document.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove our event handlers
|
||||
UnhookEventHandlers();
|
||||
}
|
||||
|
||||
// Remove our event handlers
|
||||
UnhookEventHandlers();
|
||||
|
||||
{
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
|
||||
@ -1076,15 +1072,6 @@ nsXBLBinding::RootBinding()
|
||||
return this;
|
||||
}
|
||||
|
||||
nsXBLBinding*
|
||||
nsXBLBinding::GetFirstStyleBinding()
|
||||
{
|
||||
if (mIsStyleBinding)
|
||||
return this;
|
||||
|
||||
return mNextBinding ? mNextBinding->GetFirstStyleBinding() : nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
nsXBLBinding::ResolveAllFields(JSContext *cx, JS::Handle<JSObject*> obj) const
|
||||
{
|
||||
|
@ -73,9 +73,6 @@ public:
|
||||
mJSClass = aClass;
|
||||
}
|
||||
|
||||
bool IsStyleBinding() const { return mIsStyleBinding; }
|
||||
void SetIsStyleBinding(bool aIsStyle) { mIsStyleBinding = aIsStyle; }
|
||||
|
||||
/*
|
||||
* Does a lookup for a method or attribute provided by one of the bindings'
|
||||
* prototype implementation. If found, |desc| will be set up appropriately,
|
||||
@ -122,7 +119,6 @@ public:
|
||||
|
||||
nsIAtom* GetBaseTag(int32_t* aNameSpaceID);
|
||||
nsXBLBinding* RootBinding();
|
||||
nsXBLBinding* GetFirstStyleBinding();
|
||||
|
||||
// Resolve all the fields for this binding and all ancestor bindings on the
|
||||
// object |obj|. False return means a JS exception was set.
|
||||
@ -166,7 +162,6 @@ public:
|
||||
// MEMBER VARIABLES
|
||||
protected:
|
||||
|
||||
bool mIsStyleBinding;
|
||||
bool mMarkedForDeath;
|
||||
|
||||
nsXBLPrototypeBinding* mPrototypeBinding; // Weak, but we're holding a ref to the docinfo
|
||||
|
@ -455,19 +455,16 @@ nsXBLService::LoadBindings(nsIContent* aContent, nsIURI* aURL,
|
||||
|
||||
nsXBLBinding *binding = bindingManager->GetBinding(aContent);
|
||||
if (binding) {
|
||||
nsXBLBinding *styleBinding = binding->GetFirstStyleBinding();
|
||||
if (styleBinding) {
|
||||
if (binding->MarkedForDeath()) {
|
||||
FlushStyleBindings(aContent);
|
||||
binding = nullptr;
|
||||
}
|
||||
else {
|
||||
// See if the URIs match.
|
||||
if (styleBinding->PrototypeBinding()->CompareBindingURI(aURL))
|
||||
return NS_OK;
|
||||
FlushStyleBindings(aContent);
|
||||
binding = nullptr;
|
||||
}
|
||||
if (binding->MarkedForDeath()) {
|
||||
FlushStyleBindings(aContent);
|
||||
binding = nullptr;
|
||||
}
|
||||
else {
|
||||
// See if the URIs match.
|
||||
if (binding->PrototypeBinding()->CompareBindingURI(aURL))
|
||||
return NS_OK;
|
||||
FlushStyleBindings(aContent);
|
||||
binding = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -537,15 +534,10 @@ nsXBLService::FlushStyleBindings(nsIContent* aContent)
|
||||
nsXBLBinding *binding = bindingManager->GetBinding(aContent);
|
||||
|
||||
if (binding) {
|
||||
nsXBLBinding *styleBinding = binding->GetFirstStyleBinding();
|
||||
// Clear out the script references.
|
||||
binding->ChangeDocument(document, nullptr);
|
||||
|
||||
if (styleBinding) {
|
||||
// Clear out the script references.
|
||||
styleBinding->ChangeDocument(document, nullptr);
|
||||
}
|
||||
|
||||
if (styleBinding == binding)
|
||||
bindingManager->SetBinding(aContent, nullptr); // Flush old style bindings
|
||||
bindingManager->SetBinding(aContent, nullptr); // Flush old style bindings
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
Loading…
Reference in New Issue
Block a user