зеркало из https://github.com/mozilla/pjs.git
Fix for 44437 leaks. r=ben, a=waterson
This commit is contained in:
Родитель
3fcba76e2b
Коммит
2b3bf3aed3
|
@ -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;
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Private interface to the XBL PrototypeHandler
|
||||
|
||||
*/
|
||||
|
||||
#ifndef nsIXBLPrototypeHandler_h__
|
||||
#define nsIXBLPrototypeHandler_h__
|
||||
|
||||
class nsIContent;
|
||||
class nsIDOMEvent;
|
||||
class nsIDOMMouseEvent;
|
||||
class nsIDOMKeyEvent;
|
||||
class nsIController;
|
||||
class nsIAtom;
|
||||
class nsIDOMEventReceiver;
|
||||
|
||||
// {921812E7-A044-4bd8-B49E-69BB0A607202}
|
||||
#define NS_IXBLPROTOTYPEHANDLER_IID \
|
||||
{ 0x921812e7, 0xa044, 0x4bd8, { 0xb4, 0x9e, 0x69, 0xbb, 0xa, 0x60, 0x72, 0x2 } }
|
||||
|
||||
class nsIXBLPrototypeHandler : public nsISupports
|
||||
{
|
||||
public:
|
||||
static const nsIID& GetIID() { static nsIID iid = NS_IXBLPROTOTYPEHANDLER_IID; return iid; }
|
||||
|
||||
NS_IMETHOD MouseEventMatched(nsIAtom* aEventType, nsIDOMMouseEvent* aEvent, PRBool* aResult) = 0;
|
||||
NS_IMETHOD KeyEventMatched(nsIAtom* aEventType, nsIDOMKeyEvent* aEvent, PRBool* aResult) = 0;
|
||||
|
||||
NS_IMETHOD GetHandlerElement(nsIContent** aResult) = 0;
|
||||
|
||||
NS_IMETHOD GetNextHandler(nsIXBLPrototypeHandler** aResult) = 0;
|
||||
NS_IMETHOD SetNextHandler(nsIXBLPrototypeHandler* aHandler) = 0;
|
||||
|
||||
NS_IMETHOD ExecuteHandler(nsIDOMEventReceiver* aReceiver, nsIDOMEvent* aEvent) = 0;
|
||||
|
||||
NS_IMETHOD GetEventName(nsIAtom** aResult) = 0;
|
||||
};
|
||||
|
||||
extern nsresult
|
||||
NS_NewXBLPrototypeHandler(nsIContent* aHandlerElement, nsIXBLPrototypeHandler** aResult);
|
||||
|
||||
#endif // nsIXBLPrototypeHandler_h__
|
|
@ -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;
|
||||
|
|
|
@ -1,298 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
||||
*
|
||||
* Contributor(s): Brendan Eich (brendan@mozilla.org)
|
||||
*/
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIXBLPrototypeHandler.h"
|
||||
#include "nsXBLEventHandler.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIDOMKeyEvent.h"
|
||||
#include "nsIDOMMouseEvent.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsIScriptObjectOwner.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIJSEventListener.h"
|
||||
#include "nsIController.h"
|
||||
#include "nsIControllers.h"
|
||||
#include "nsIDOMXULElement.h"
|
||||
#include "nsIDOMNSHTMLTextAreaElement.h"
|
||||
#include "nsIDOMNSHTMLInputElement.h"
|
||||
#include "nsIDOMText.h"
|
||||
#include "nsIEventListenerManager.h"
|
||||
#include "nsIDOMEventReceiver.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsXBLBinding.h"
|
||||
#include "nsIPrivateDOMEvent.h"
|
||||
#include "nsIDOMWindowInternal.h"
|
||||
#include "nsIPref.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsXPIDLString.h"
|
||||
|
||||
#include "nsIDOMFocusListener.h"
|
||||
#include "nsIDOMKeyListener.h"
|
||||
#include "nsIDOMMenuListener.h"
|
||||
#include "nsIDOMMouseListener.h"
|
||||
#include "nsIDOMDragListener.h"
|
||||
#include "nsIDOMScrollListener.h"
|
||||
#include "nsIDOMFormListener.h"
|
||||
|
||||
PRUint32 nsXBLEventHandler::gRefCnt = 0;
|
||||
nsIAtom* nsXBLEventHandler::kKeyCodeAtom = nsnull;
|
||||
nsIAtom* nsXBLEventHandler::kCharCodeAtom = nsnull;
|
||||
nsIAtom* nsXBLEventHandler::kKeyAtom = nsnull;
|
||||
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)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mEventReceiver = aEventReceiver;
|
||||
mProtoHandler = aHandler;
|
||||
mNextHandler = nsnull;
|
||||
gRefCnt++;
|
||||
if (gRefCnt == 1) {
|
||||
kKeyCodeAtom = NS_NewAtom("keycode");
|
||||
kKeyAtom = NS_NewAtom("key");
|
||||
kCharCodeAtom = NS_NewAtom("charcode");
|
||||
kModifiersAtom = NS_NewAtom("modifiers");
|
||||
kActionAtom = NS_NewAtom("action");
|
||||
kCommandAtom = NS_NewAtom("command");
|
||||
kClickCountAtom = NS_NewAtom("clickcount");
|
||||
kButtonAtom = NS_NewAtom("button");
|
||||
kBindingAttachedAtom = NS_NewAtom("bindingattached");
|
||||
kBindingDetachedAtom = NS_NewAtom("bindingdetached");
|
||||
}
|
||||
}
|
||||
|
||||
nsXBLEventHandler::~nsXBLEventHandler()
|
||||
{
|
||||
gRefCnt--;
|
||||
if (gRefCnt == 0) {
|
||||
NS_RELEASE(kKeyAtom);
|
||||
NS_RELEASE(kKeyCodeAtom);
|
||||
NS_RELEASE(kCharCodeAtom);
|
||||
NS_RELEASE(kModifiersAtom);
|
||||
NS_RELEASE(kActionAtom);
|
||||
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()
|
||||
{
|
||||
if (mNextHandler)
|
||||
mNextHandler->RemoveEventHandlers();
|
||||
|
||||
// Figure out if we're using capturing or not.
|
||||
if (!mProtoHandler)
|
||||
return;
|
||||
|
||||
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;
|
||||
if (!handlerElement)
|
||||
return;
|
||||
|
||||
PRBool useCapture = PR_FALSE;
|
||||
nsAutoString capturer;
|
||||
handlerElement->GetAttribute(kNameSpaceID_None, nsXBLBinding::kPhaseAtom, capturer);
|
||||
if (capturer == NS_LITERAL_STRING("capturing"))
|
||||
useCapture = PR_TRUE;
|
||||
|
||||
nsAutoString type;
|
||||
handlerElement->GetAttribute(kNameSpaceID_None, nsXBLBinding::kEventAtom, type);
|
||||
|
||||
PRBool found = PR_FALSE;
|
||||
nsIID iid;
|
||||
nsXBLBinding::GetEventHandlerIID(eventName, &iid, &found);
|
||||
|
||||
nsCOMPtr<nsIDOMEventListener> listener(do_QueryInterface(this));
|
||||
|
||||
if (found && listener)
|
||||
mEventReceiver->RemoveEventListener(type, listener, useCapture);
|
||||
}
|
||||
|
||||
/// Helpers that are relegated to the end of the file /////////////////////////////
|
||||
|
||||
nsresult
|
||||
nsXBLEventHandler::GetTextData(nsIContent *aParent, nsString& aResult)
|
||||
{
|
||||
aResult.Truncate(0);
|
||||
|
||||
nsCOMPtr<nsIContent> textChild;
|
||||
PRInt32 textCount;
|
||||
aParent->ChildCount(textCount);
|
||||
nsAutoString answer;
|
||||
for (PRInt32 j = 0; j < textCount; j++) {
|
||||
// Get the child.
|
||||
aParent->ChildAt(j, *getter_AddRefs(textChild));
|
||||
nsCOMPtr<nsIDOMText> text(do_QueryInterface(textChild));
|
||||
if (text) {
|
||||
nsAutoString data;
|
||||
text->GetData(data);
|
||||
aResult += data;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
NS_NewXBLEventHandler(nsIDOMEventReceiver* aRec, nsIXBLPrototypeHandler* aHandler,
|
||||
nsXBLEventHandler** aResult)
|
||||
{
|
||||
*aResult = new nsXBLEventHandler(aRec, aHandler);
|
||||
if (!*aResult)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#ifndef nsXBLEventHandler_h__
|
||||
#define nsXBLEventHandler_h__
|
||||
|
||||
#include "nsIDOMEventReceiver.h"
|
||||
|
||||
class nsIXBLBinding;
|
||||
class nsIDOMEvent;
|
||||
class nsIContent;
|
||||
class nsIDOMUIEvent;
|
||||
class nsIDOMKeyEvent;
|
||||
class nsIDOMMouseEvent;
|
||||
class nsIAtom;
|
||||
class nsIController;
|
||||
class nsIXBLPrototypeHandler;
|
||||
|
||||
// XXX This should be broken up into subclasses for each listener IID type, so we
|
||||
// can cut down on the bloat of the handlers.
|
||||
class nsXBLEventHandler : public nsISupports
|
||||
{
|
||||
public:
|
||||
nsXBLEventHandler(nsIDOMEventReceiver* aReceiver, nsIXBLPrototypeHandler* aHandler);
|
||||
virtual ~nsXBLEventHandler();
|
||||
|
||||
NS_IMETHOD BindingAttached();
|
||||
NS_IMETHOD BindingDetached();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
public:
|
||||
void SetNextHandler(nsXBLEventHandler* aHandler) {
|
||||
mNextHandler = aHandler;
|
||||
}
|
||||
|
||||
void RemoveEventHandlers();
|
||||
|
||||
void MarkForDeath() {
|
||||
if (mNextHandler) mNextHandler->MarkForDeath(); mProtoHandler = nsnull; mEventReceiver = nsnull;
|
||||
}
|
||||
|
||||
static nsresult GetTextData(nsIContent *aParent, nsString& aResult);
|
||||
|
||||
protected:
|
||||
static PRUint32 gRefCnt;
|
||||
static nsIAtom* kKeyAtom;
|
||||
static nsIAtom* kKeyCodeAtom;
|
||||
static nsIAtom* kCharCodeAtom;
|
||||
static nsIAtom* kActionAtom;
|
||||
static nsIAtom* kCommandAtom;
|
||||
static nsIAtom* kClickCountAtom;
|
||||
static nsIAtom* kButtonAtom;
|
||||
static nsIAtom* kBindingAttachedAtom;
|
||||
static nsIAtom* kBindingDetachedAtom;
|
||||
static nsIAtom* kModifiersAtom;
|
||||
|
||||
protected:
|
||||
nsIDOMEventReceiver* mEventReceiver; // Both of these refs are weak.
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> mProtoHandler;
|
||||
|
||||
nsXBLEventHandler* mNextHandler; // Handlers are chained for easy unloading later.
|
||||
};
|
||||
|
||||
extern nsresult
|
||||
NS_NewXBLEventHandler(nsIDOMEventReceiver* aEventReceiver, nsIXBLPrototypeHandler* aHandlerElement,
|
||||
nsXBLEventHandler** aResult);
|
||||
#endif
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -1,116 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#ifndef nsXBLPrototypeHandler_h__
|
||||
#define nsXBLPrototypeHandler_h__
|
||||
|
||||
#include "nsIXBLPrototypeHandler.h"
|
||||
#include "nsIAtom.h"
|
||||
|
||||
class nsIXBLBinding;
|
||||
class nsIDOMEvent;
|
||||
class nsIContent;
|
||||
class nsIDOMUIEvent;
|
||||
class nsIDOMKeyEvent;
|
||||
class nsIDOMMouseEvent;
|
||||
class nsString;
|
||||
|
||||
class nsXBLPrototypeHandler : public nsIXBLPrototypeHandler
|
||||
{
|
||||
public:
|
||||
nsXBLPrototypeHandler(nsIContent* aHandlerElement);
|
||||
virtual ~nsXBLPrototypeHandler();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD MouseEventMatched(nsIAtom* aEventType, nsIDOMMouseEvent* aEvent, PRBool* aResult);
|
||||
NS_IMETHOD KeyEventMatched(nsIAtom* aEventType, nsIDOMKeyEvent* aEvent, PRBool* aResult);
|
||||
|
||||
NS_IMETHOD GetHandlerElement(nsIContent** aResult);
|
||||
|
||||
NS_IMETHOD GetNextHandler(nsIXBLPrototypeHandler** aResult);
|
||||
NS_IMETHOD SetNextHandler(nsIXBLPrototypeHandler* aHandler);
|
||||
|
||||
NS_IMETHOD ExecuteHandler(nsIDOMEventReceiver* aReceiver, nsIDOMEvent* aEvent);
|
||||
|
||||
NS_IMETHOD GetEventName(nsIAtom** aResult);
|
||||
|
||||
public:
|
||||
static nsresult GetTextData(nsIContent *aParent, nsString& aResult);
|
||||
|
||||
static PRUint32 gRefCnt;
|
||||
static nsIAtom* kKeyAtom;
|
||||
static nsIAtom* kKeyCodeAtom;
|
||||
static nsIAtom* kCharCodeAtom;
|
||||
static nsIAtom* kActionAtom;
|
||||
static nsIAtom* kCommandAtom;
|
||||
static nsIAtom* kOnCommandAtom;
|
||||
static nsIAtom* kFocusCommandAtom;
|
||||
static nsIAtom* kClickCountAtom;
|
||||
static nsIAtom* kButtonAtom;
|
||||
static nsIAtom* kModifiersAtom;
|
||||
static nsIAtom* kTypeAtom;
|
||||
|
||||
protected:
|
||||
NS_IMETHOD GetController(nsIDOMEventReceiver* aReceiver, nsIController** aResult);
|
||||
|
||||
inline PRInt32 GetMatchingKeyCode(const nsString& aKeyName);
|
||||
void ConstructMask();
|
||||
PRBool ModifiersMatchMask(nsIDOMUIEvent* aEvent);
|
||||
|
||||
inline PRBool KeyEventMatched(nsIDOMKeyEvent* aKeyEvent);
|
||||
inline PRBool MouseEventMatched(nsIDOMMouseEvent* aMouseEvent);
|
||||
|
||||
PRInt32 KeyToMask(PRInt32 key);
|
||||
|
||||
static PRInt32 kAccelKey;
|
||||
static PRInt32 kMenuAccessKey;
|
||||
static void InitAccessKeys();
|
||||
|
||||
static const PRInt32 cShift;
|
||||
static const PRInt32 cAlt;
|
||||
static const PRInt32 cControl;
|
||||
static const PRInt32 cMeta;
|
||||
|
||||
protected:
|
||||
nsIContent* mHandlerElement; // This ref is weak.
|
||||
|
||||
PRInt32 mKeyMask; // Which modifier keys this event handler expects to have down
|
||||
// in order to be matched.
|
||||
|
||||
PRInt32 mDetail; // For key events, contains a charcode or keycode. For
|
||||
// mouse events, stores the button info.
|
||||
|
||||
PRInt32 mDetail2; // Miscellaneous extra information. For key events,
|
||||
// stores whether or not we're a key code or char code.
|
||||
// For mouse events, stores the clickCount.
|
||||
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> mNextHandler; // Prototype handlers are chained. We own the next handler in the chain.
|
||||
nsCOMPtr<nsIAtom> mEventName; // The type of the event, e.g., "keypress"
|
||||
};
|
||||
|
||||
extern nsresult
|
||||
NS_NewXBLPrototypeHandler(nsIContent* aHandlerElement, nsIXBLPrototypeHandler** aResult);
|
||||
|
||||
#endif
|
|
@ -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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче