mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-28 21:28:55 +00:00
Fix for 44437 leaks. r=ben, a=waterson
This commit is contained in:
parent
320b10e024
commit
7e42d66752
@ -29,6 +29,7 @@
|
||||
|
||||
class nsIContent;
|
||||
class nsIDocument;
|
||||
class nsIDOMEventReceiver;
|
||||
class nsIXBLDocumentInfo;
|
||||
class nsIXBLPrototypeHandler;
|
||||
|
||||
@ -50,10 +51,15 @@ public:
|
||||
|
||||
NS_IMETHOD GetAllowScripts(PRBool* aResult)=0;
|
||||
|
||||
NS_IMETHOD BindingAttached(nsIDOMEventReceiver* aReceiver)=0;
|
||||
NS_IMETHOD BindingDetached(nsIDOMEventReceiver* aReceiver)=0;
|
||||
|
||||
NS_IMETHOD InheritsStyle(PRBool* aResult)=0;
|
||||
|
||||
NS_IMETHOD GetPrototypeHandler(nsIXBLPrototypeHandler** aHandler)=0;
|
||||
NS_IMETHOD SetPrototypeHandler(nsIXBLPrototypeHandler* aHandler)=0;
|
||||
NS_IMETHOD GetPrototypeHandlers(nsIXBLPrototypeHandler** aHandler,
|
||||
nsIXBLPrototypeHandler** aSpecialHandler)=0;
|
||||
NS_IMETHOD SetPrototypeHandlers(nsIXBLPrototypeHandler* aHandler,
|
||||
nsIXBLPrototypeHandler* aSpecialHandler)=0;
|
||||
|
||||
NS_IMETHOD AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag,
|
||||
nsIContent* aChangedElement, nsIContent* aAnonymousContent)=0;
|
||||
|
@ -53,6 +53,9 @@ public:
|
||||
|
||||
NS_IMETHOD GetHandlerElement(nsIContent** aResult) = 0;
|
||||
|
||||
NS_IMETHOD BindingAttached(nsIDOMEventReceiver* aRec)=0;
|
||||
NS_IMETHOD BindingDetached(nsIDOMEventReceiver* aRec)=0;
|
||||
|
||||
NS_IMETHOD GetNextHandler(nsIXBLPrototypeHandler** aResult) = 0;
|
||||
NS_IMETHOD SetNextHandler(nsIXBLPrototypeHandler* aHandler) = 0;
|
||||
|
||||
|
@ -160,8 +160,6 @@ nsIAtom* nsXBLBinding::kSetterAtom = nsnull;
|
||||
nsIAtom* nsXBLBinding::kNameAtom = nsnull;
|
||||
nsIAtom* nsXBLBinding::kReadOnlyAtom = nsnull;
|
||||
nsIAtom* nsXBLBinding::kAttachToAtom = nsnull;
|
||||
nsIAtom* nsXBLBinding::kBindingAttachedAtom = nsnull;
|
||||
nsIAtom* nsXBLBinding::kBindingDetachedAtom = nsnull;
|
||||
|
||||
nsXBLBinding::EventHandlerMapEntry
|
||||
nsXBLBinding::kEventHandlerMap[] = {
|
||||
@ -257,9 +255,7 @@ nsXBLBinding::nsXBLBinding(nsIXBLPrototypeBinding* aBinding)
|
||||
kNameAtom = NS_NewAtom("name");
|
||||
kReadOnlyAtom = NS_NewAtom("readonly");
|
||||
kAttachToAtom = NS_NewAtom("attachto");
|
||||
kBindingAttachedAtom = NS_NewAtom("bindingattached");
|
||||
kBindingDetachedAtom = NS_NewAtom("bindingdetached");
|
||||
|
||||
|
||||
EventHandlerMapEntry* entry = kEventHandlerMap;
|
||||
while (entry->mAttributeName) {
|
||||
entry->mAttributeAtom = NS_NewAtom(entry->mAttributeName);
|
||||
@ -299,7 +295,6 @@ nsXBLBinding::~nsXBLBinding(void)
|
||||
NS_RELEASE(kNameAtom);
|
||||
NS_RELEASE(kReadOnlyAtom);
|
||||
NS_RELEASE(kAttachToAtom);
|
||||
NS_RELEASE(kBindingAttachedAtom);
|
||||
|
||||
EventHandlerMapEntry* entry = kEventHandlerMap;
|
||||
while (entry->mAttributeName) {
|
||||
@ -542,8 +537,14 @@ nsXBLBinding::InstallEventHandlers(nsIContent* aBoundElement, nsIXBLBinding** aB
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> handlerChain;
|
||||
mPrototypeBinding->GetPrototypeHandler(getter_AddRefs(handlerChain));
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> specialChain;
|
||||
mPrototypeBinding->GetPrototypeHandlers(getter_AddRefs(handlerChain), getter_AddRefs(specialChain));
|
||||
|
||||
if (specialChain && !*aBinding) {
|
||||
*aBinding = this;
|
||||
NS_ADDREF(*aBinding);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> curr = handlerChain;
|
||||
nsXBLEventHandler* currHandler = nsnull;
|
||||
|
||||
@ -558,17 +559,9 @@ nsXBLBinding::InstallEventHandlers(nsIContent* aBoundElement, nsIXBLBinding** aB
|
||||
|
||||
nsIID iid;
|
||||
PRBool found = PR_FALSE;
|
||||
PRBool special = PR_FALSE;
|
||||
if (eventAtom.get() == kBindingAttachedAtom ||
|
||||
eventAtom.get() == kBindingDetachedAtom) {
|
||||
*aBinding = this;
|
||||
NS_ADDREF(*aBinding);
|
||||
special = PR_TRUE;
|
||||
}
|
||||
else
|
||||
GetEventHandlerIID(eventAtom, &iid, &found);
|
||||
GetEventHandlerIID(eventAtom, &iid, &found);
|
||||
|
||||
if (found || special) {
|
||||
if (found) {
|
||||
nsCOMPtr<nsIDOMEventReceiver> receiver = do_QueryInterface(mBoundElement);
|
||||
nsAutoString attachType;
|
||||
child->GetAttribute(kNameSpaceID_None, kAttachToAtom, attachType);
|
||||
@ -607,9 +600,7 @@ nsXBLBinding::InstallEventHandlers(nsIContent* aBoundElement, nsIXBLBinding** aB
|
||||
eventAtom->ToString(type);
|
||||
|
||||
// Add the event listener.
|
||||
if (special)
|
||||
NS_NewXBLEventHandler(receiver, curr, &handler);
|
||||
else if (iid.Equals(NS_GET_IID(nsIDOMMouseListener))) {
|
||||
if (iid.Equals(NS_GET_IID(nsIDOMMouseListener))) {
|
||||
nsXBLMouseHandler* mouseHandler;
|
||||
NS_NewXBLMouseHandler(receiver, curr, &mouseHandler);
|
||||
receiver->AddEventListener(type, (nsIDOMMouseListener*)mouseHandler, useCapture);
|
||||
@ -682,8 +673,8 @@ nsXBLBinding::InstallEventHandlers(nsIContent* aBoundElement, nsIXBLBinding** aB
|
||||
|
||||
currHandler = handler;
|
||||
|
||||
if (!special) // Let the listener manager hold on to the handler.
|
||||
NS_RELEASE(handler);
|
||||
// Let the listener manager hold on to the handler.
|
||||
NS_RELEASE(handler);
|
||||
}
|
||||
}
|
||||
|
||||
@ -997,8 +988,8 @@ nsXBLBinding::ExecuteAttachedHandler()
|
||||
if (mNextBinding)
|
||||
mNextBinding->ExecuteAttachedHandler();
|
||||
|
||||
if (mFirstHandler)
|
||||
mFirstHandler->BindingAttached();
|
||||
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(mBoundElement));
|
||||
mPrototypeBinding->BindingAttached(rec);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1006,8 +997,8 @@ nsXBLBinding::ExecuteAttachedHandler()
|
||||
NS_IMETHODIMP
|
||||
nsXBLBinding::ExecuteDetachedHandler()
|
||||
{
|
||||
if (mFirstHandler)
|
||||
mFirstHandler->BindingDetached();
|
||||
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(mBoundElement));
|
||||
mPrototypeBinding->BindingDetached(rec);
|
||||
|
||||
if (mNextBinding)
|
||||
mNextBinding->ExecuteDetachedHandler();
|
||||
|
@ -131,9 +131,7 @@ public:
|
||||
static nsIAtom* kNameAtom;
|
||||
static nsIAtom* kReadOnlyAtom;
|
||||
static nsIAtom* kAttachToAtom;
|
||||
static nsIAtom* kBindingAttachedAtom;
|
||||
static nsIAtom* kBindingDetachedAtom;
|
||||
|
||||
|
||||
// Used to easily obtain the correct IID for an event.
|
||||
struct EventHandlerMapEntry {
|
||||
const char* mAttributeName;
|
||||
|
@ -69,8 +69,6 @@ nsIAtom* nsXBLEventHandler::kActionAtom = nsnull;
|
||||
nsIAtom* nsXBLEventHandler::kCommandAtom = nsnull;
|
||||
nsIAtom* nsXBLEventHandler::kClickCountAtom = nsnull;
|
||||
nsIAtom* nsXBLEventHandler::kButtonAtom = nsnull;
|
||||
nsIAtom* nsXBLEventHandler::kBindingAttachedAtom = nsnull;
|
||||
nsIAtom* nsXBLEventHandler::kBindingDetachedAtom = nsnull;
|
||||
nsIAtom* nsXBLEventHandler::kModifiersAtom = nsnull;
|
||||
|
||||
nsXBLEventHandler::nsXBLEventHandler(nsIDOMEventReceiver* aEventReceiver, nsIXBLPrototypeHandler* aHandler)
|
||||
@ -89,8 +87,6 @@ nsXBLEventHandler::nsXBLEventHandler(nsIDOMEventReceiver* aEventReceiver, nsIXBL
|
||||
kCommandAtom = NS_NewAtom("command");
|
||||
kClickCountAtom = NS_NewAtom("clickcount");
|
||||
kButtonAtom = NS_NewAtom("button");
|
||||
kBindingAttachedAtom = NS_NewAtom("bindingattached");
|
||||
kBindingDetachedAtom = NS_NewAtom("bindingdetached");
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,114 +102,11 @@ nsXBLEventHandler::~nsXBLEventHandler()
|
||||
NS_RELEASE(kCommandAtom);
|
||||
NS_RELEASE(kButtonAtom);
|
||||
NS_RELEASE(kClickCountAtom);
|
||||
NS_RELEASE(kBindingAttachedAtom);
|
||||
NS_RELEASE(kBindingDetachedAtom);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsXBLEventHandler, nsISupports)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLEventHandler::BindingAttached()
|
||||
{
|
||||
if (!mProtoHandler)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIAtom> eventName;
|
||||
mProtoHandler->GetEventName(getter_AddRefs(eventName));
|
||||
|
||||
nsresult ret;
|
||||
if (eventName.get() == kBindingAttachedAtom) {
|
||||
nsMouseEvent event;
|
||||
event.eventStructType = NS_EVENT;
|
||||
event.message = NS_MENU_ACTION;
|
||||
event.isShift = PR_FALSE;
|
||||
event.isControl = PR_FALSE;
|
||||
event.isAlt = PR_FALSE;
|
||||
event.isMeta = PR_FALSE;
|
||||
event.clickCount = 0;
|
||||
event.widget = nsnull;
|
||||
|
||||
nsCOMPtr<nsIEventListenerManager> listenerManager;
|
||||
if (NS_FAILED(ret = mEventReceiver->GetListenerManager(getter_AddRefs(listenerManager)))) {
|
||||
NS_ERROR("Unable to instantiate a listener manager on this event.");
|
||||
return ret;
|
||||
}
|
||||
nsAutoString empty;
|
||||
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
if (NS_FAILED(ret = listenerManager->CreateEvent(nsnull, &event, empty, getter_AddRefs(domEvent)))) {
|
||||
NS_ERROR("The binding attach handler will fail without the ability to create the event early.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// We need to explicitly set the target here, because the
|
||||
// DOM implementation will try to compute the target from
|
||||
// the frame. If we don't have a frame then that breaks.
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(domEvent);
|
||||
if (privateEvent) {
|
||||
privateEvent->SetTarget(mEventReceiver);
|
||||
}
|
||||
|
||||
mProtoHandler->ExecuteHandler(mEventReceiver, domEvent);
|
||||
}
|
||||
|
||||
if (mNextHandler)
|
||||
return mNextHandler->BindingAttached();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLEventHandler::BindingDetached()
|
||||
{
|
||||
if (!mProtoHandler)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult ret;
|
||||
nsCOMPtr<nsIAtom> eventName;
|
||||
mProtoHandler->GetEventName(getter_AddRefs(eventName));
|
||||
if (eventName.get() == kBindingDetachedAtom) {
|
||||
nsMouseEvent event;
|
||||
event.eventStructType = NS_EVENT;
|
||||
event.message = NS_MENU_ACTION;
|
||||
event.isShift = PR_FALSE;
|
||||
event.isControl = PR_FALSE;
|
||||
event.isAlt = PR_FALSE;
|
||||
event.isMeta = PR_FALSE;
|
||||
event.clickCount = 0;
|
||||
event.widget = nsnull;
|
||||
|
||||
nsCOMPtr<nsIEventListenerManager> listenerManager;
|
||||
if (NS_FAILED(ret = mEventReceiver->GetListenerManager(getter_AddRefs(listenerManager)))) {
|
||||
NS_ERROR("Unable to instantiate a listener manager on this event.");
|
||||
return ret;
|
||||
}
|
||||
nsAutoString empty;
|
||||
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
if (NS_FAILED(ret = listenerManager->CreateEvent(nsnull, &event, empty, getter_AddRefs(domEvent)))) {
|
||||
NS_ERROR("The binding attach handler will fail without the ability to create the event early.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// We need to explicitly set the target here, because the
|
||||
// DOM implementation will try to compute the target from
|
||||
// the frame. If we don't have a frame then that breaks.
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(domEvent);
|
||||
if (privateEvent) {
|
||||
privateEvent->SetTarget(mEventReceiver);
|
||||
}
|
||||
|
||||
mProtoHandler->ExecuteHandler(mEventReceiver, domEvent);
|
||||
}
|
||||
|
||||
if (mNextHandler)
|
||||
return mNextHandler->BindingDetached();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsXBLEventHandler::RemoveEventHandlers()
|
||||
{
|
||||
@ -227,14 +120,6 @@ nsXBLEventHandler::RemoveEventHandlers()
|
||||
nsCOMPtr<nsIAtom> eventName;
|
||||
mProtoHandler->GetEventName(getter_AddRefs(eventName));
|
||||
|
||||
if (eventName.get() == kBindingAttachedAtom ||
|
||||
eventName.get() == kBindingDetachedAtom) {
|
||||
// Release and drop.
|
||||
mProtoHandler = nsnull;
|
||||
NS_RELEASE_THIS();
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> handlerElement;
|
||||
mProtoHandler->GetHandlerElement(getter_AddRefs(handlerElement));
|
||||
mProtoHandler = nsnull;
|
||||
|
@ -45,9 +45,6 @@ public:
|
||||
nsXBLEventHandler(nsIDOMEventReceiver* aReceiver, nsIXBLPrototypeHandler* aHandler);
|
||||
virtual ~nsXBLEventHandler();
|
||||
|
||||
NS_IMETHOD BindingAttached();
|
||||
NS_IMETHOD BindingDetached();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
public:
|
||||
@ -72,8 +69,6 @@ protected:
|
||||
static nsIAtom* kCommandAtom;
|
||||
static nsIAtom* kClickCountAtom;
|
||||
static nsIAtom* kButtonAtom;
|
||||
static nsIAtom* kBindingAttachedAtom;
|
||||
static nsIAtom* kBindingDetachedAtom;
|
||||
static nsIAtom* kModifiersAtom;
|
||||
|
||||
protected:
|
||||
|
@ -280,6 +280,22 @@ nsXBLPrototypeBinding::GetAllowScripts(PRBool* aResult)
|
||||
return info->GetScriptAccess(aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeBinding::BindingAttached(nsIDOMEventReceiver* aReceiver)
|
||||
{
|
||||
if (mSpecialHandler)
|
||||
return mSpecialHandler->BindingAttached(aReceiver);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeBinding::BindingDetached(nsIDOMEventReceiver* aReceiver)
|
||||
{
|
||||
if (mSpecialHandler)
|
||||
return mSpecialHandler->BindingDetached(aReceiver);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeBinding::InheritsStyle(PRBool* aResult)
|
||||
{
|
||||
@ -315,17 +331,22 @@ nsXBLPrototypeBinding::SetHasBasePrototype(PRBool aHasBase)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeBinding::GetPrototypeHandler(nsIXBLPrototypeHandler** aResult)
|
||||
nsXBLPrototypeBinding::GetPrototypeHandlers(nsIXBLPrototypeHandler** aResult,
|
||||
nsIXBLPrototypeHandler** aSpecialResult)
|
||||
{
|
||||
*aResult = mPrototypeHandler;
|
||||
*aSpecialResult = mSpecialHandler;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
NS_IF_ADDREF(*aSpecialResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeBinding::SetPrototypeHandler(nsIXBLPrototypeHandler* aHandler)
|
||||
nsXBLPrototypeBinding::SetPrototypeHandlers(nsIXBLPrototypeHandler* aHandler,
|
||||
nsIXBLPrototypeHandler* aSpecialHandler)
|
||||
{
|
||||
mPrototypeHandler = aHandler;
|
||||
mSpecialHandler = aSpecialHandler;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -510,11 +531,8 @@ nsXBLPrototypeBinding::ConstructHandlers()
|
||||
// See if this binding has a handler elt.
|
||||
nsCOMPtr<nsIContent> handlers;
|
||||
GetImmediateChild(kHandlersAtom, getter_AddRefs(handlers));
|
||||
if (handlers) {
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> firstHandler;
|
||||
nsXBLService::BuildHandlerChain(handlers, getter_AddRefs(firstHandler));
|
||||
SetPrototypeHandler(firstHandler);
|
||||
}
|
||||
if (handlers)
|
||||
nsXBLService::BuildHandlerChain(handlers, getter_AddRefs(mPrototypeHandler), getter_AddRefs(mSpecialHandler));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -52,10 +52,13 @@ class nsXBLPrototypeBinding: public nsIXBLPrototypeBinding
|
||||
|
||||
NS_IMETHOD GetAllowScripts(PRBool* aResult);
|
||||
|
||||
NS_IMETHOD BindingAttached(nsIDOMEventReceiver* aRec);
|
||||
NS_IMETHOD BindingDetached(nsIDOMEventReceiver* aRec);
|
||||
|
||||
NS_IMETHOD InheritsStyle(PRBool* aResult);
|
||||
|
||||
NS_IMETHOD GetPrototypeHandler(nsIXBLPrototypeHandler** aHandler);
|
||||
NS_IMETHOD SetPrototypeHandler(nsIXBLPrototypeHandler* aHandler);
|
||||
NS_IMETHOD GetPrototypeHandlers(nsIXBLPrototypeHandler** aHandler, nsIXBLPrototypeHandler** aSpecialHandler);
|
||||
NS_IMETHOD SetPrototypeHandlers(nsIXBLPrototypeHandler* aHandler, nsIXBLPrototypeHandler* aSpecialHandler);
|
||||
|
||||
NS_IMETHOD AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag,
|
||||
nsIContent* aChangedElement, nsIContent* aAnonymousContent);
|
||||
@ -117,6 +120,8 @@ protected:
|
||||
|
||||
nsCOMPtr<nsIContent> mBinding; // Strong. We own a ref to our content element in the binding doc.
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> mPrototypeHandler; // Strong. DocInfo owns us, and we own the handlers.
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> mSpecialHandler; // Strong. Our bindingattached/detached handlers.
|
||||
|
||||
nsCOMPtr<nsIXBLPrototypeBinding> mBaseBinding; // Strong. We own the base binding in our explicit inheritance chain.
|
||||
PRPackedBool mInheritStyle;
|
||||
PRPackedBool mHasBaseProto;
|
||||
|
@ -56,6 +56,9 @@
|
||||
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
|
||||
|
||||
PRUint32 nsXBLPrototypeHandler::gRefCnt = 0;
|
||||
|
||||
nsIAtom* nsXBLPrototypeHandler::kBindingAttachedAtom = nsnull;
|
||||
nsIAtom* nsXBLPrototypeHandler::kBindingDetachedAtom = nsnull;
|
||||
nsIAtom* nsXBLPrototypeHandler::kKeyCodeAtom = nsnull;
|
||||
nsIAtom* nsXBLPrototypeHandler::kCharCodeAtom = nsnull;
|
||||
nsIAtom* nsXBLPrototypeHandler::kKeyAtom = nsnull;
|
||||
@ -82,6 +85,8 @@ nsXBLPrototypeHandler::nsXBLPrototypeHandler(nsIContent* aHandlerElement)
|
||||
mHandlerElement = aHandlerElement;
|
||||
gRefCnt++;
|
||||
if (gRefCnt == 1) {
|
||||
kBindingAttachedAtom = NS_NewAtom("bindingattached");
|
||||
kBindingDetachedAtom = NS_NewAtom("bindingdetached");
|
||||
kKeyCodeAtom = NS_NewAtom("keycode");
|
||||
kKeyAtom = NS_NewAtom("key");
|
||||
kCharCodeAtom = NS_NewAtom("charcode");
|
||||
@ -106,6 +111,8 @@ nsXBLPrototypeHandler::~nsXBLPrototypeHandler()
|
||||
{
|
||||
gRefCnt--;
|
||||
if (gRefCnt == 0) {
|
||||
NS_RELEASE(kBindingAttachedAtom);
|
||||
NS_RELEASE(kBindingDetachedAtom);
|
||||
NS_RELEASE(kKeyAtom);
|
||||
NS_RELEASE(kKeyCodeAtom);
|
||||
NS_RELEASE(kCharCodeAtom);
|
||||
@ -315,6 +322,96 @@ nsXBLPrototypeHandler::GetEventName(nsIAtom** aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeHandler::BindingAttached(nsIDOMEventReceiver* aReceiver)
|
||||
{
|
||||
nsresult ret;
|
||||
if (mEventName.get() == kBindingAttachedAtom) {
|
||||
nsMouseEvent event;
|
||||
event.eventStructType = NS_EVENT;
|
||||
event.message = NS_MENU_ACTION;
|
||||
event.isShift = PR_FALSE;
|
||||
event.isControl = PR_FALSE;
|
||||
event.isAlt = PR_FALSE;
|
||||
event.isMeta = PR_FALSE;
|
||||
event.clickCount = 0;
|
||||
event.widget = nsnull;
|
||||
|
||||
nsCOMPtr<nsIEventListenerManager> listenerManager;
|
||||
if (NS_FAILED(ret = aReceiver->GetListenerManager(getter_AddRefs(listenerManager)))) {
|
||||
NS_ERROR("Unable to instantiate a listener manager on this event.");
|
||||
return ret;
|
||||
}
|
||||
nsAutoString empty;
|
||||
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
if (NS_FAILED(ret = listenerManager->CreateEvent(nsnull, &event, empty, getter_AddRefs(domEvent)))) {
|
||||
NS_ERROR("The binding attach handler will fail without the ability to create the event early.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// We need to explicitly set the target here, because the
|
||||
// DOM implementation will try to compute the target from
|
||||
// the frame. If we don't have a frame then that breaks.
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(domEvent);
|
||||
if (privateEvent) {
|
||||
privateEvent->SetTarget(aReceiver);
|
||||
}
|
||||
|
||||
ExecuteHandler(aReceiver, domEvent);
|
||||
}
|
||||
|
||||
if (mNextHandler)
|
||||
return mNextHandler->BindingAttached(aReceiver);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeHandler::BindingDetached(nsIDOMEventReceiver* aReceiver)
|
||||
{
|
||||
nsresult ret;
|
||||
if (mEventName.get() == kBindingDetachedAtom) {
|
||||
nsMouseEvent event;
|
||||
event.eventStructType = NS_EVENT;
|
||||
event.message = NS_MENU_ACTION;
|
||||
event.isShift = PR_FALSE;
|
||||
event.isControl = PR_FALSE;
|
||||
event.isAlt = PR_FALSE;
|
||||
event.isMeta = PR_FALSE;
|
||||
event.clickCount = 0;
|
||||
event.widget = nsnull;
|
||||
|
||||
nsCOMPtr<nsIEventListenerManager> listenerManager;
|
||||
if (NS_FAILED(ret = aReceiver->GetListenerManager(getter_AddRefs(listenerManager)))) {
|
||||
NS_ERROR("Unable to instantiate a listener manager on this event.");
|
||||
return ret;
|
||||
}
|
||||
nsAutoString empty;
|
||||
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
if (NS_FAILED(ret = listenerManager->CreateEvent(nsnull, &event, empty, getter_AddRefs(domEvent)))) {
|
||||
NS_ERROR("The binding attach handler will fail without the ability to create the event early.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// We need to explicitly set the target here, because the
|
||||
// DOM implementation will try to compute the target from
|
||||
// the frame. If we don't have a frame then that breaks.
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(domEvent);
|
||||
if (privateEvent) {
|
||||
privateEvent->SetTarget(aReceiver);
|
||||
}
|
||||
|
||||
ExecuteHandler(aReceiver, domEvent);
|
||||
}
|
||||
|
||||
if (mNextHandler)
|
||||
return mNextHandler->BindingDetached(aReceiver);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeHandler::GetController(nsIDOMEventReceiver* aReceiver, nsIController** aResult)
|
||||
{
|
||||
|
@ -56,10 +56,16 @@ public:
|
||||
|
||||
NS_IMETHOD GetEventName(nsIAtom** aResult);
|
||||
|
||||
NS_IMETHOD BindingAttached(nsIDOMEventReceiver* aReceiver);
|
||||
NS_IMETHOD BindingDetached(nsIDOMEventReceiver* aReceiver);
|
||||
|
||||
public:
|
||||
static nsresult GetTextData(nsIContent *aParent, nsString& aResult);
|
||||
|
||||
static PRUint32 gRefCnt;
|
||||
|
||||
static nsIAtom* kBindingAttachedAtom;
|
||||
static nsIAtom* kBindingDetachedAtom;
|
||||
static nsIAtom* kKeyAtom;
|
||||
static nsIAtom* kKeyCodeAtom;
|
||||
static nsIAtom* kCharCodeAtom;
|
||||
|
@ -484,6 +484,7 @@ PRUint32 nsXBLService::gClassLRUListLength = 0;
|
||||
PRUint32 nsXBLService::gClassLRUListQuota = 64;
|
||||
|
||||
nsIAtom* nsXBLService::kExtendsAtom = nsnull;
|
||||
nsIAtom* nsXBLService::kEventAtom = nsnull;
|
||||
nsIAtom* nsXBLService::kScrollbarAtom = nsnull;
|
||||
nsIAtom* nsXBLService::kInputAtom = nsnull;
|
||||
|
||||
@ -523,6 +524,7 @@ nsXBLService::nsXBLService(void)
|
||||
|
||||
// Create our atoms
|
||||
kExtendsAtom = NS_NewAtom("extends");
|
||||
kEventAtom = NS_NewAtom("event");
|
||||
kScrollbarAtom = NS_NewAtom("scrollbar");
|
||||
kInputAtom = NS_NewAtom("input");
|
||||
|
||||
@ -554,6 +556,7 @@ nsXBLService::~nsXBLService(void)
|
||||
|
||||
// Release our atoms
|
||||
NS_RELEASE(kExtendsAtom);
|
||||
NS_RELEASE(kEventAtom);
|
||||
NS_RELEASE(kScrollbarAtom);
|
||||
NS_RELEASE(kInputAtom);
|
||||
|
||||
@ -1291,28 +1294,51 @@ static void GetImmediateChild(nsIAtom* aTag, nsIContent* aParent, nsIContent** a
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXBLService::BuildHandlerChain(nsIContent* aContent, nsIXBLPrototypeHandler** aResult)
|
||||
nsXBLService::BuildHandlerChain(nsIContent* aContent, nsIXBLPrototypeHandler** aResult,
|
||||
nsIXBLPrototypeHandler** aSpecialResult)
|
||||
{
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> firstHandler;
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> currHandler;
|
||||
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> firstSpecialHandler;
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> currSpecialHandler;
|
||||
|
||||
PRInt32 handlerCount;
|
||||
aContent->ChildCount(handlerCount);
|
||||
for (PRInt32 j = 0; j < handlerCount; j++) {
|
||||
nsCOMPtr<nsIContent> handler;
|
||||
aContent->ChildAt(j, *getter_AddRefs(handler));
|
||||
|
||||
PRBool special = PR_FALSE;
|
||||
nsAutoString event;
|
||||
handler->GetAttribute(kNameSpaceID_None, kEventAtom, event);
|
||||
if (event.Equals(NS_LITERAL_STRING("bindingattached")) ||
|
||||
event.Equals(NS_LITERAL_STRING("bindingdetached")))
|
||||
special = PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> newHandler;
|
||||
NS_NewXBLPrototypeHandler(handler, getter_AddRefs(newHandler));
|
||||
|
||||
if (newHandler) {
|
||||
if (currHandler)
|
||||
currHandler->SetNextHandler(newHandler);
|
||||
else firstHandler = newHandler;
|
||||
currHandler = newHandler;
|
||||
if (special) {
|
||||
if (currSpecialHandler)
|
||||
currSpecialHandler->SetNextHandler(newHandler);
|
||||
else firstSpecialHandler = newHandler;
|
||||
currSpecialHandler = newHandler;
|
||||
}
|
||||
else {
|
||||
if (currHandler)
|
||||
currHandler->SetNextHandler(newHandler);
|
||||
else firstHandler = newHandler;
|
||||
currHandler = newHandler;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*aResult = firstHandler;
|
||||
*aSpecialResult = firstSpecialHandler;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
NS_IF_ADDREF(*aSpecialResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -103,7 +103,8 @@ public:
|
||||
// This method walks a binding document and removes any text nodes
|
||||
// that contain only whitespace.
|
||||
static nsresult StripWhitespaceNodes(nsIContent* aContent);
|
||||
static nsresult BuildHandlerChain(nsIContent* aContent, nsIXBLPrototypeHandler** aResult);
|
||||
static nsresult BuildHandlerChain(nsIContent* aContent, nsIXBLPrototypeHandler** aResult,
|
||||
nsIXBLPrototypeHandler** aSpecialResult);
|
||||
|
||||
// MEMBER VARIABLES
|
||||
public:
|
||||
@ -125,6 +126,7 @@ public:
|
||||
|
||||
// XBL Atoms
|
||||
static nsIAtom* kExtendsAtom;
|
||||
static nsIAtom* kEventAtom;
|
||||
static nsIAtom* kScrollbarAtom;
|
||||
static nsIAtom* kInputAtom;
|
||||
|
||||
|
@ -143,7 +143,8 @@ static void GetHandlers(nsIXBLDocumentInfo* aInfo, const nsCString& aDocURI,
|
||||
}
|
||||
}
|
||||
|
||||
binding->GetPrototypeHandler(aResult); // Addref happens here.
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> dummy;
|
||||
binding->GetPrototypeHandlers(aResult, getter_AddRefs(dummy)); // Addref happens here.
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -154,7 +155,8 @@ nsXBLWindowKeyHandler::EnsureHandlers()
|
||||
return NS_OK;
|
||||
// Call into the XBL service.
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mElement));
|
||||
nsXBLService::BuildHandlerChain(content, getter_AddRefs(mHandler));
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> dummy;
|
||||
nsXBLService::BuildHandlerChain(content, getter_AddRefs(mHandler), getter_AddRefs(dummy));
|
||||
}
|
||||
else {
|
||||
if (!mXBLSpecialDocInfo)
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
class nsIContent;
|
||||
class nsIDocument;
|
||||
class nsIDOMEventReceiver;
|
||||
class nsIXBLDocumentInfo;
|
||||
class nsIXBLPrototypeHandler;
|
||||
|
||||
@ -50,10 +51,15 @@ public:
|
||||
|
||||
NS_IMETHOD GetAllowScripts(PRBool* aResult)=0;
|
||||
|
||||
NS_IMETHOD BindingAttached(nsIDOMEventReceiver* aReceiver)=0;
|
||||
NS_IMETHOD BindingDetached(nsIDOMEventReceiver* aReceiver)=0;
|
||||
|
||||
NS_IMETHOD InheritsStyle(PRBool* aResult)=0;
|
||||
|
||||
NS_IMETHOD GetPrototypeHandler(nsIXBLPrototypeHandler** aHandler)=0;
|
||||
NS_IMETHOD SetPrototypeHandler(nsIXBLPrototypeHandler* aHandler)=0;
|
||||
NS_IMETHOD GetPrototypeHandlers(nsIXBLPrototypeHandler** aHandler,
|
||||
nsIXBLPrototypeHandler** aSpecialHandler)=0;
|
||||
NS_IMETHOD SetPrototypeHandlers(nsIXBLPrototypeHandler* aHandler,
|
||||
nsIXBLPrototypeHandler* aSpecialHandler)=0;
|
||||
|
||||
NS_IMETHOD AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag,
|
||||
nsIContent* aChangedElement, nsIContent* aAnonymousContent)=0;
|
||||
|
@ -53,6 +53,9 @@ public:
|
||||
|
||||
NS_IMETHOD GetHandlerElement(nsIContent** aResult) = 0;
|
||||
|
||||
NS_IMETHOD BindingAttached(nsIDOMEventReceiver* aRec)=0;
|
||||
NS_IMETHOD BindingDetached(nsIDOMEventReceiver* aRec)=0;
|
||||
|
||||
NS_IMETHOD GetNextHandler(nsIXBLPrototypeHandler** aResult) = 0;
|
||||
NS_IMETHOD SetNextHandler(nsIXBLPrototypeHandler* aHandler) = 0;
|
||||
|
||||
|
@ -160,8 +160,6 @@ nsIAtom* nsXBLBinding::kSetterAtom = nsnull;
|
||||
nsIAtom* nsXBLBinding::kNameAtom = nsnull;
|
||||
nsIAtom* nsXBLBinding::kReadOnlyAtom = nsnull;
|
||||
nsIAtom* nsXBLBinding::kAttachToAtom = nsnull;
|
||||
nsIAtom* nsXBLBinding::kBindingAttachedAtom = nsnull;
|
||||
nsIAtom* nsXBLBinding::kBindingDetachedAtom = nsnull;
|
||||
|
||||
nsXBLBinding::EventHandlerMapEntry
|
||||
nsXBLBinding::kEventHandlerMap[] = {
|
||||
@ -257,9 +255,7 @@ nsXBLBinding::nsXBLBinding(nsIXBLPrototypeBinding* aBinding)
|
||||
kNameAtom = NS_NewAtom("name");
|
||||
kReadOnlyAtom = NS_NewAtom("readonly");
|
||||
kAttachToAtom = NS_NewAtom("attachto");
|
||||
kBindingAttachedAtom = NS_NewAtom("bindingattached");
|
||||
kBindingDetachedAtom = NS_NewAtom("bindingdetached");
|
||||
|
||||
|
||||
EventHandlerMapEntry* entry = kEventHandlerMap;
|
||||
while (entry->mAttributeName) {
|
||||
entry->mAttributeAtom = NS_NewAtom(entry->mAttributeName);
|
||||
@ -299,7 +295,6 @@ nsXBLBinding::~nsXBLBinding(void)
|
||||
NS_RELEASE(kNameAtom);
|
||||
NS_RELEASE(kReadOnlyAtom);
|
||||
NS_RELEASE(kAttachToAtom);
|
||||
NS_RELEASE(kBindingAttachedAtom);
|
||||
|
||||
EventHandlerMapEntry* entry = kEventHandlerMap;
|
||||
while (entry->mAttributeName) {
|
||||
@ -542,8 +537,14 @@ nsXBLBinding::InstallEventHandlers(nsIContent* aBoundElement, nsIXBLBinding** aB
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> handlerChain;
|
||||
mPrototypeBinding->GetPrototypeHandler(getter_AddRefs(handlerChain));
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> specialChain;
|
||||
mPrototypeBinding->GetPrototypeHandlers(getter_AddRefs(handlerChain), getter_AddRefs(specialChain));
|
||||
|
||||
if (specialChain && !*aBinding) {
|
||||
*aBinding = this;
|
||||
NS_ADDREF(*aBinding);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> curr = handlerChain;
|
||||
nsXBLEventHandler* currHandler = nsnull;
|
||||
|
||||
@ -558,17 +559,9 @@ nsXBLBinding::InstallEventHandlers(nsIContent* aBoundElement, nsIXBLBinding** aB
|
||||
|
||||
nsIID iid;
|
||||
PRBool found = PR_FALSE;
|
||||
PRBool special = PR_FALSE;
|
||||
if (eventAtom.get() == kBindingAttachedAtom ||
|
||||
eventAtom.get() == kBindingDetachedAtom) {
|
||||
*aBinding = this;
|
||||
NS_ADDREF(*aBinding);
|
||||
special = PR_TRUE;
|
||||
}
|
||||
else
|
||||
GetEventHandlerIID(eventAtom, &iid, &found);
|
||||
GetEventHandlerIID(eventAtom, &iid, &found);
|
||||
|
||||
if (found || special) {
|
||||
if (found) {
|
||||
nsCOMPtr<nsIDOMEventReceiver> receiver = do_QueryInterface(mBoundElement);
|
||||
nsAutoString attachType;
|
||||
child->GetAttribute(kNameSpaceID_None, kAttachToAtom, attachType);
|
||||
@ -607,9 +600,7 @@ nsXBLBinding::InstallEventHandlers(nsIContent* aBoundElement, nsIXBLBinding** aB
|
||||
eventAtom->ToString(type);
|
||||
|
||||
// Add the event listener.
|
||||
if (special)
|
||||
NS_NewXBLEventHandler(receiver, curr, &handler);
|
||||
else if (iid.Equals(NS_GET_IID(nsIDOMMouseListener))) {
|
||||
if (iid.Equals(NS_GET_IID(nsIDOMMouseListener))) {
|
||||
nsXBLMouseHandler* mouseHandler;
|
||||
NS_NewXBLMouseHandler(receiver, curr, &mouseHandler);
|
||||
receiver->AddEventListener(type, (nsIDOMMouseListener*)mouseHandler, useCapture);
|
||||
@ -682,8 +673,8 @@ nsXBLBinding::InstallEventHandlers(nsIContent* aBoundElement, nsIXBLBinding** aB
|
||||
|
||||
currHandler = handler;
|
||||
|
||||
if (!special) // Let the listener manager hold on to the handler.
|
||||
NS_RELEASE(handler);
|
||||
// Let the listener manager hold on to the handler.
|
||||
NS_RELEASE(handler);
|
||||
}
|
||||
}
|
||||
|
||||
@ -997,8 +988,8 @@ nsXBLBinding::ExecuteAttachedHandler()
|
||||
if (mNextBinding)
|
||||
mNextBinding->ExecuteAttachedHandler();
|
||||
|
||||
if (mFirstHandler)
|
||||
mFirstHandler->BindingAttached();
|
||||
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(mBoundElement));
|
||||
mPrototypeBinding->BindingAttached(rec);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1006,8 +997,8 @@ nsXBLBinding::ExecuteAttachedHandler()
|
||||
NS_IMETHODIMP
|
||||
nsXBLBinding::ExecuteDetachedHandler()
|
||||
{
|
||||
if (mFirstHandler)
|
||||
mFirstHandler->BindingDetached();
|
||||
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(mBoundElement));
|
||||
mPrototypeBinding->BindingDetached(rec);
|
||||
|
||||
if (mNextBinding)
|
||||
mNextBinding->ExecuteDetachedHandler();
|
||||
|
@ -131,9 +131,7 @@ public:
|
||||
static nsIAtom* kNameAtom;
|
||||
static nsIAtom* kReadOnlyAtom;
|
||||
static nsIAtom* kAttachToAtom;
|
||||
static nsIAtom* kBindingAttachedAtom;
|
||||
static nsIAtom* kBindingDetachedAtom;
|
||||
|
||||
|
||||
// Used to easily obtain the correct IID for an event.
|
||||
struct EventHandlerMapEntry {
|
||||
const char* mAttributeName;
|
||||
|
@ -69,8 +69,6 @@ nsIAtom* nsXBLEventHandler::kActionAtom = nsnull;
|
||||
nsIAtom* nsXBLEventHandler::kCommandAtom = nsnull;
|
||||
nsIAtom* nsXBLEventHandler::kClickCountAtom = nsnull;
|
||||
nsIAtom* nsXBLEventHandler::kButtonAtom = nsnull;
|
||||
nsIAtom* nsXBLEventHandler::kBindingAttachedAtom = nsnull;
|
||||
nsIAtom* nsXBLEventHandler::kBindingDetachedAtom = nsnull;
|
||||
nsIAtom* nsXBLEventHandler::kModifiersAtom = nsnull;
|
||||
|
||||
nsXBLEventHandler::nsXBLEventHandler(nsIDOMEventReceiver* aEventReceiver, nsIXBLPrototypeHandler* aHandler)
|
||||
@ -89,8 +87,6 @@ nsXBLEventHandler::nsXBLEventHandler(nsIDOMEventReceiver* aEventReceiver, nsIXBL
|
||||
kCommandAtom = NS_NewAtom("command");
|
||||
kClickCountAtom = NS_NewAtom("clickcount");
|
||||
kButtonAtom = NS_NewAtom("button");
|
||||
kBindingAttachedAtom = NS_NewAtom("bindingattached");
|
||||
kBindingDetachedAtom = NS_NewAtom("bindingdetached");
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,114 +102,11 @@ nsXBLEventHandler::~nsXBLEventHandler()
|
||||
NS_RELEASE(kCommandAtom);
|
||||
NS_RELEASE(kButtonAtom);
|
||||
NS_RELEASE(kClickCountAtom);
|
||||
NS_RELEASE(kBindingAttachedAtom);
|
||||
NS_RELEASE(kBindingDetachedAtom);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsXBLEventHandler, nsISupports)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLEventHandler::BindingAttached()
|
||||
{
|
||||
if (!mProtoHandler)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIAtom> eventName;
|
||||
mProtoHandler->GetEventName(getter_AddRefs(eventName));
|
||||
|
||||
nsresult ret;
|
||||
if (eventName.get() == kBindingAttachedAtom) {
|
||||
nsMouseEvent event;
|
||||
event.eventStructType = NS_EVENT;
|
||||
event.message = NS_MENU_ACTION;
|
||||
event.isShift = PR_FALSE;
|
||||
event.isControl = PR_FALSE;
|
||||
event.isAlt = PR_FALSE;
|
||||
event.isMeta = PR_FALSE;
|
||||
event.clickCount = 0;
|
||||
event.widget = nsnull;
|
||||
|
||||
nsCOMPtr<nsIEventListenerManager> listenerManager;
|
||||
if (NS_FAILED(ret = mEventReceiver->GetListenerManager(getter_AddRefs(listenerManager)))) {
|
||||
NS_ERROR("Unable to instantiate a listener manager on this event.");
|
||||
return ret;
|
||||
}
|
||||
nsAutoString empty;
|
||||
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
if (NS_FAILED(ret = listenerManager->CreateEvent(nsnull, &event, empty, getter_AddRefs(domEvent)))) {
|
||||
NS_ERROR("The binding attach handler will fail without the ability to create the event early.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// We need to explicitly set the target here, because the
|
||||
// DOM implementation will try to compute the target from
|
||||
// the frame. If we don't have a frame then that breaks.
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(domEvent);
|
||||
if (privateEvent) {
|
||||
privateEvent->SetTarget(mEventReceiver);
|
||||
}
|
||||
|
||||
mProtoHandler->ExecuteHandler(mEventReceiver, domEvent);
|
||||
}
|
||||
|
||||
if (mNextHandler)
|
||||
return mNextHandler->BindingAttached();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLEventHandler::BindingDetached()
|
||||
{
|
||||
if (!mProtoHandler)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult ret;
|
||||
nsCOMPtr<nsIAtom> eventName;
|
||||
mProtoHandler->GetEventName(getter_AddRefs(eventName));
|
||||
if (eventName.get() == kBindingDetachedAtom) {
|
||||
nsMouseEvent event;
|
||||
event.eventStructType = NS_EVENT;
|
||||
event.message = NS_MENU_ACTION;
|
||||
event.isShift = PR_FALSE;
|
||||
event.isControl = PR_FALSE;
|
||||
event.isAlt = PR_FALSE;
|
||||
event.isMeta = PR_FALSE;
|
||||
event.clickCount = 0;
|
||||
event.widget = nsnull;
|
||||
|
||||
nsCOMPtr<nsIEventListenerManager> listenerManager;
|
||||
if (NS_FAILED(ret = mEventReceiver->GetListenerManager(getter_AddRefs(listenerManager)))) {
|
||||
NS_ERROR("Unable to instantiate a listener manager on this event.");
|
||||
return ret;
|
||||
}
|
||||
nsAutoString empty;
|
||||
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
if (NS_FAILED(ret = listenerManager->CreateEvent(nsnull, &event, empty, getter_AddRefs(domEvent)))) {
|
||||
NS_ERROR("The binding attach handler will fail without the ability to create the event early.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// We need to explicitly set the target here, because the
|
||||
// DOM implementation will try to compute the target from
|
||||
// the frame. If we don't have a frame then that breaks.
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(domEvent);
|
||||
if (privateEvent) {
|
||||
privateEvent->SetTarget(mEventReceiver);
|
||||
}
|
||||
|
||||
mProtoHandler->ExecuteHandler(mEventReceiver, domEvent);
|
||||
}
|
||||
|
||||
if (mNextHandler)
|
||||
return mNextHandler->BindingDetached();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsXBLEventHandler::RemoveEventHandlers()
|
||||
{
|
||||
@ -227,14 +120,6 @@ nsXBLEventHandler::RemoveEventHandlers()
|
||||
nsCOMPtr<nsIAtom> eventName;
|
||||
mProtoHandler->GetEventName(getter_AddRefs(eventName));
|
||||
|
||||
if (eventName.get() == kBindingAttachedAtom ||
|
||||
eventName.get() == kBindingDetachedAtom) {
|
||||
// Release and drop.
|
||||
mProtoHandler = nsnull;
|
||||
NS_RELEASE_THIS();
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> handlerElement;
|
||||
mProtoHandler->GetHandlerElement(getter_AddRefs(handlerElement));
|
||||
mProtoHandler = nsnull;
|
||||
|
@ -45,9 +45,6 @@ public:
|
||||
nsXBLEventHandler(nsIDOMEventReceiver* aReceiver, nsIXBLPrototypeHandler* aHandler);
|
||||
virtual ~nsXBLEventHandler();
|
||||
|
||||
NS_IMETHOD BindingAttached();
|
||||
NS_IMETHOD BindingDetached();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
public:
|
||||
@ -72,8 +69,6 @@ protected:
|
||||
static nsIAtom* kCommandAtom;
|
||||
static nsIAtom* kClickCountAtom;
|
||||
static nsIAtom* kButtonAtom;
|
||||
static nsIAtom* kBindingAttachedAtom;
|
||||
static nsIAtom* kBindingDetachedAtom;
|
||||
static nsIAtom* kModifiersAtom;
|
||||
|
||||
protected:
|
||||
|
@ -280,6 +280,22 @@ nsXBLPrototypeBinding::GetAllowScripts(PRBool* aResult)
|
||||
return info->GetScriptAccess(aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeBinding::BindingAttached(nsIDOMEventReceiver* aReceiver)
|
||||
{
|
||||
if (mSpecialHandler)
|
||||
return mSpecialHandler->BindingAttached(aReceiver);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeBinding::BindingDetached(nsIDOMEventReceiver* aReceiver)
|
||||
{
|
||||
if (mSpecialHandler)
|
||||
return mSpecialHandler->BindingDetached(aReceiver);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeBinding::InheritsStyle(PRBool* aResult)
|
||||
{
|
||||
@ -315,17 +331,22 @@ nsXBLPrototypeBinding::SetHasBasePrototype(PRBool aHasBase)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeBinding::GetPrototypeHandler(nsIXBLPrototypeHandler** aResult)
|
||||
nsXBLPrototypeBinding::GetPrototypeHandlers(nsIXBLPrototypeHandler** aResult,
|
||||
nsIXBLPrototypeHandler** aSpecialResult)
|
||||
{
|
||||
*aResult = mPrototypeHandler;
|
||||
*aSpecialResult = mSpecialHandler;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
NS_IF_ADDREF(*aSpecialResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeBinding::SetPrototypeHandler(nsIXBLPrototypeHandler* aHandler)
|
||||
nsXBLPrototypeBinding::SetPrototypeHandlers(nsIXBLPrototypeHandler* aHandler,
|
||||
nsIXBLPrototypeHandler* aSpecialHandler)
|
||||
{
|
||||
mPrototypeHandler = aHandler;
|
||||
mSpecialHandler = aSpecialHandler;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -510,11 +531,8 @@ nsXBLPrototypeBinding::ConstructHandlers()
|
||||
// See if this binding has a handler elt.
|
||||
nsCOMPtr<nsIContent> handlers;
|
||||
GetImmediateChild(kHandlersAtom, getter_AddRefs(handlers));
|
||||
if (handlers) {
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> firstHandler;
|
||||
nsXBLService::BuildHandlerChain(handlers, getter_AddRefs(firstHandler));
|
||||
SetPrototypeHandler(firstHandler);
|
||||
}
|
||||
if (handlers)
|
||||
nsXBLService::BuildHandlerChain(handlers, getter_AddRefs(mPrototypeHandler), getter_AddRefs(mSpecialHandler));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -52,10 +52,13 @@ class nsXBLPrototypeBinding: public nsIXBLPrototypeBinding
|
||||
|
||||
NS_IMETHOD GetAllowScripts(PRBool* aResult);
|
||||
|
||||
NS_IMETHOD BindingAttached(nsIDOMEventReceiver* aRec);
|
||||
NS_IMETHOD BindingDetached(nsIDOMEventReceiver* aRec);
|
||||
|
||||
NS_IMETHOD InheritsStyle(PRBool* aResult);
|
||||
|
||||
NS_IMETHOD GetPrototypeHandler(nsIXBLPrototypeHandler** aHandler);
|
||||
NS_IMETHOD SetPrototypeHandler(nsIXBLPrototypeHandler* aHandler);
|
||||
NS_IMETHOD GetPrototypeHandlers(nsIXBLPrototypeHandler** aHandler, nsIXBLPrototypeHandler** aSpecialHandler);
|
||||
NS_IMETHOD SetPrototypeHandlers(nsIXBLPrototypeHandler* aHandler, nsIXBLPrototypeHandler* aSpecialHandler);
|
||||
|
||||
NS_IMETHOD AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag,
|
||||
nsIContent* aChangedElement, nsIContent* aAnonymousContent);
|
||||
@ -117,6 +120,8 @@ protected:
|
||||
|
||||
nsCOMPtr<nsIContent> mBinding; // Strong. We own a ref to our content element in the binding doc.
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> mPrototypeHandler; // Strong. DocInfo owns us, and we own the handlers.
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> mSpecialHandler; // Strong. Our bindingattached/detached handlers.
|
||||
|
||||
nsCOMPtr<nsIXBLPrototypeBinding> mBaseBinding; // Strong. We own the base binding in our explicit inheritance chain.
|
||||
PRPackedBool mInheritStyle;
|
||||
PRPackedBool mHasBaseProto;
|
||||
|
@ -56,6 +56,9 @@
|
||||
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
|
||||
|
||||
PRUint32 nsXBLPrototypeHandler::gRefCnt = 0;
|
||||
|
||||
nsIAtom* nsXBLPrototypeHandler::kBindingAttachedAtom = nsnull;
|
||||
nsIAtom* nsXBLPrototypeHandler::kBindingDetachedAtom = nsnull;
|
||||
nsIAtom* nsXBLPrototypeHandler::kKeyCodeAtom = nsnull;
|
||||
nsIAtom* nsXBLPrototypeHandler::kCharCodeAtom = nsnull;
|
||||
nsIAtom* nsXBLPrototypeHandler::kKeyAtom = nsnull;
|
||||
@ -82,6 +85,8 @@ nsXBLPrototypeHandler::nsXBLPrototypeHandler(nsIContent* aHandlerElement)
|
||||
mHandlerElement = aHandlerElement;
|
||||
gRefCnt++;
|
||||
if (gRefCnt == 1) {
|
||||
kBindingAttachedAtom = NS_NewAtom("bindingattached");
|
||||
kBindingDetachedAtom = NS_NewAtom("bindingdetached");
|
||||
kKeyCodeAtom = NS_NewAtom("keycode");
|
||||
kKeyAtom = NS_NewAtom("key");
|
||||
kCharCodeAtom = NS_NewAtom("charcode");
|
||||
@ -106,6 +111,8 @@ nsXBLPrototypeHandler::~nsXBLPrototypeHandler()
|
||||
{
|
||||
gRefCnt--;
|
||||
if (gRefCnt == 0) {
|
||||
NS_RELEASE(kBindingAttachedAtom);
|
||||
NS_RELEASE(kBindingDetachedAtom);
|
||||
NS_RELEASE(kKeyAtom);
|
||||
NS_RELEASE(kKeyCodeAtom);
|
||||
NS_RELEASE(kCharCodeAtom);
|
||||
@ -315,6 +322,96 @@ nsXBLPrototypeHandler::GetEventName(nsIAtom** aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeHandler::BindingAttached(nsIDOMEventReceiver* aReceiver)
|
||||
{
|
||||
nsresult ret;
|
||||
if (mEventName.get() == kBindingAttachedAtom) {
|
||||
nsMouseEvent event;
|
||||
event.eventStructType = NS_EVENT;
|
||||
event.message = NS_MENU_ACTION;
|
||||
event.isShift = PR_FALSE;
|
||||
event.isControl = PR_FALSE;
|
||||
event.isAlt = PR_FALSE;
|
||||
event.isMeta = PR_FALSE;
|
||||
event.clickCount = 0;
|
||||
event.widget = nsnull;
|
||||
|
||||
nsCOMPtr<nsIEventListenerManager> listenerManager;
|
||||
if (NS_FAILED(ret = aReceiver->GetListenerManager(getter_AddRefs(listenerManager)))) {
|
||||
NS_ERROR("Unable to instantiate a listener manager on this event.");
|
||||
return ret;
|
||||
}
|
||||
nsAutoString empty;
|
||||
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
if (NS_FAILED(ret = listenerManager->CreateEvent(nsnull, &event, empty, getter_AddRefs(domEvent)))) {
|
||||
NS_ERROR("The binding attach handler will fail without the ability to create the event early.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// We need to explicitly set the target here, because the
|
||||
// DOM implementation will try to compute the target from
|
||||
// the frame. If we don't have a frame then that breaks.
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(domEvent);
|
||||
if (privateEvent) {
|
||||
privateEvent->SetTarget(aReceiver);
|
||||
}
|
||||
|
||||
ExecuteHandler(aReceiver, domEvent);
|
||||
}
|
||||
|
||||
if (mNextHandler)
|
||||
return mNextHandler->BindingAttached(aReceiver);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeHandler::BindingDetached(nsIDOMEventReceiver* aReceiver)
|
||||
{
|
||||
nsresult ret;
|
||||
if (mEventName.get() == kBindingDetachedAtom) {
|
||||
nsMouseEvent event;
|
||||
event.eventStructType = NS_EVENT;
|
||||
event.message = NS_MENU_ACTION;
|
||||
event.isShift = PR_FALSE;
|
||||
event.isControl = PR_FALSE;
|
||||
event.isAlt = PR_FALSE;
|
||||
event.isMeta = PR_FALSE;
|
||||
event.clickCount = 0;
|
||||
event.widget = nsnull;
|
||||
|
||||
nsCOMPtr<nsIEventListenerManager> listenerManager;
|
||||
if (NS_FAILED(ret = aReceiver->GetListenerManager(getter_AddRefs(listenerManager)))) {
|
||||
NS_ERROR("Unable to instantiate a listener manager on this event.");
|
||||
return ret;
|
||||
}
|
||||
nsAutoString empty;
|
||||
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
if (NS_FAILED(ret = listenerManager->CreateEvent(nsnull, &event, empty, getter_AddRefs(domEvent)))) {
|
||||
NS_ERROR("The binding attach handler will fail without the ability to create the event early.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// We need to explicitly set the target here, because the
|
||||
// DOM implementation will try to compute the target from
|
||||
// the frame. If we don't have a frame then that breaks.
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(domEvent);
|
||||
if (privateEvent) {
|
||||
privateEvent->SetTarget(aReceiver);
|
||||
}
|
||||
|
||||
ExecuteHandler(aReceiver, domEvent);
|
||||
}
|
||||
|
||||
if (mNextHandler)
|
||||
return mNextHandler->BindingDetached(aReceiver);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeHandler::GetController(nsIDOMEventReceiver* aReceiver, nsIController** aResult)
|
||||
{
|
||||
|
@ -56,10 +56,16 @@ public:
|
||||
|
||||
NS_IMETHOD GetEventName(nsIAtom** aResult);
|
||||
|
||||
NS_IMETHOD BindingAttached(nsIDOMEventReceiver* aReceiver);
|
||||
NS_IMETHOD BindingDetached(nsIDOMEventReceiver* aReceiver);
|
||||
|
||||
public:
|
||||
static nsresult GetTextData(nsIContent *aParent, nsString& aResult);
|
||||
|
||||
static PRUint32 gRefCnt;
|
||||
|
||||
static nsIAtom* kBindingAttachedAtom;
|
||||
static nsIAtom* kBindingDetachedAtom;
|
||||
static nsIAtom* kKeyAtom;
|
||||
static nsIAtom* kKeyCodeAtom;
|
||||
static nsIAtom* kCharCodeAtom;
|
||||
|
@ -484,6 +484,7 @@ PRUint32 nsXBLService::gClassLRUListLength = 0;
|
||||
PRUint32 nsXBLService::gClassLRUListQuota = 64;
|
||||
|
||||
nsIAtom* nsXBLService::kExtendsAtom = nsnull;
|
||||
nsIAtom* nsXBLService::kEventAtom = nsnull;
|
||||
nsIAtom* nsXBLService::kScrollbarAtom = nsnull;
|
||||
nsIAtom* nsXBLService::kInputAtom = nsnull;
|
||||
|
||||
@ -523,6 +524,7 @@ nsXBLService::nsXBLService(void)
|
||||
|
||||
// Create our atoms
|
||||
kExtendsAtom = NS_NewAtom("extends");
|
||||
kEventAtom = NS_NewAtom("event");
|
||||
kScrollbarAtom = NS_NewAtom("scrollbar");
|
||||
kInputAtom = NS_NewAtom("input");
|
||||
|
||||
@ -554,6 +556,7 @@ nsXBLService::~nsXBLService(void)
|
||||
|
||||
// Release our atoms
|
||||
NS_RELEASE(kExtendsAtom);
|
||||
NS_RELEASE(kEventAtom);
|
||||
NS_RELEASE(kScrollbarAtom);
|
||||
NS_RELEASE(kInputAtom);
|
||||
|
||||
@ -1291,28 +1294,51 @@ static void GetImmediateChild(nsIAtom* aTag, nsIContent* aParent, nsIContent** a
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXBLService::BuildHandlerChain(nsIContent* aContent, nsIXBLPrototypeHandler** aResult)
|
||||
nsXBLService::BuildHandlerChain(nsIContent* aContent, nsIXBLPrototypeHandler** aResult,
|
||||
nsIXBLPrototypeHandler** aSpecialResult)
|
||||
{
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> firstHandler;
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> currHandler;
|
||||
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> firstSpecialHandler;
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> currSpecialHandler;
|
||||
|
||||
PRInt32 handlerCount;
|
||||
aContent->ChildCount(handlerCount);
|
||||
for (PRInt32 j = 0; j < handlerCount; j++) {
|
||||
nsCOMPtr<nsIContent> handler;
|
||||
aContent->ChildAt(j, *getter_AddRefs(handler));
|
||||
|
||||
PRBool special = PR_FALSE;
|
||||
nsAutoString event;
|
||||
handler->GetAttribute(kNameSpaceID_None, kEventAtom, event);
|
||||
if (event.Equals(NS_LITERAL_STRING("bindingattached")) ||
|
||||
event.Equals(NS_LITERAL_STRING("bindingdetached")))
|
||||
special = PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> newHandler;
|
||||
NS_NewXBLPrototypeHandler(handler, getter_AddRefs(newHandler));
|
||||
|
||||
if (newHandler) {
|
||||
if (currHandler)
|
||||
currHandler->SetNextHandler(newHandler);
|
||||
else firstHandler = newHandler;
|
||||
currHandler = newHandler;
|
||||
if (special) {
|
||||
if (currSpecialHandler)
|
||||
currSpecialHandler->SetNextHandler(newHandler);
|
||||
else firstSpecialHandler = newHandler;
|
||||
currSpecialHandler = newHandler;
|
||||
}
|
||||
else {
|
||||
if (currHandler)
|
||||
currHandler->SetNextHandler(newHandler);
|
||||
else firstHandler = newHandler;
|
||||
currHandler = newHandler;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*aResult = firstHandler;
|
||||
*aSpecialResult = firstSpecialHandler;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
NS_IF_ADDREF(*aSpecialResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -103,7 +103,8 @@ public:
|
||||
// This method walks a binding document and removes any text nodes
|
||||
// that contain only whitespace.
|
||||
static nsresult StripWhitespaceNodes(nsIContent* aContent);
|
||||
static nsresult BuildHandlerChain(nsIContent* aContent, nsIXBLPrototypeHandler** aResult);
|
||||
static nsresult BuildHandlerChain(nsIContent* aContent, nsIXBLPrototypeHandler** aResult,
|
||||
nsIXBLPrototypeHandler** aSpecialResult);
|
||||
|
||||
// MEMBER VARIABLES
|
||||
public:
|
||||
@ -125,6 +126,7 @@ public:
|
||||
|
||||
// XBL Atoms
|
||||
static nsIAtom* kExtendsAtom;
|
||||
static nsIAtom* kEventAtom;
|
||||
static nsIAtom* kScrollbarAtom;
|
||||
static nsIAtom* kInputAtom;
|
||||
|
||||
|
@ -143,7 +143,8 @@ static void GetHandlers(nsIXBLDocumentInfo* aInfo, const nsCString& aDocURI,
|
||||
}
|
||||
}
|
||||
|
||||
binding->GetPrototypeHandler(aResult); // Addref happens here.
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> dummy;
|
||||
binding->GetPrototypeHandlers(aResult, getter_AddRefs(dummy)); // Addref happens here.
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -154,7 +155,8 @@ nsXBLWindowKeyHandler::EnsureHandlers()
|
||||
return NS_OK;
|
||||
// Call into the XBL service.
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mElement));
|
||||
nsXBLService::BuildHandlerChain(content, getter_AddRefs(mHandler));
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> dummy;
|
||||
nsXBLService::BuildHandlerChain(content, getter_AddRefs(mHandler), getter_AddRefs(dummy));
|
||||
}
|
||||
else {
|
||||
if (!mXBLSpecialDocInfo)
|
||||
|
Loading…
x
Reference in New Issue
Block a user