breaking apart root key handler into base class

This commit is contained in:
pinkerton%netscape.com 2000-11-29 02:51:26 +00:00
parent 8ae0f7fd90
commit 83e2a61ae6
8 changed files with 1244 additions and 0 deletions

View File

@ -0,0 +1,183 @@
/* -*- 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.
*
* Contributor(s):
* - Mike Pinkerton (pinkerton@netscape.com)
*/
#include "nsCOMPtr.h"
#include "nsIXBLPrototypeHandler.h"
#include "nsXBLWindowDragHandler.h"
#include "nsIContent.h"
#include "nsIAtom.h"
#include "nsIDOMNSUIEvent.h"
#include "nsIDOMMouseEvent.h"
#include "nsIDOMEventReceiver.h"
#include "nsXBLService.h"
#include "nsIServiceManager.h"
#include "nsHTMLAtoms.h"
#include "nsINameSpaceManager.h"
#include "nsIXBLDocumentInfo.h"
#include "nsIScriptGlobalObject.h"
#include "nsIDOMElement.h"
PRUint32 nsXBLWindowDragHandler::gRefCnt = 0;
nsIAtom* nsXBLWindowDragHandler::kDragGestureAtom = nsnull;
nsIAtom* nsXBLWindowDragHandler::kDragOverAtom = nsnull;
nsIAtom* nsXBLWindowDragHandler::kDragEnterAtom = nsnull;
nsIAtom* nsXBLWindowDragHandler::kDragExitAtom = nsnull;
nsIAtom* nsXBLWindowDragHandler::kDragDropAtom = nsnull;
struct nsXBLSpecialDocInfo {
nsCOMPtr<nsIXBLDocumentInfo> mHTMLBindings;
nsCOMPtr<nsIXBLDocumentInfo> mPlatformHTMLBindings;
PRBool mFilesPresent;
nsXBLSpecialDocInfo() :mFilesPresent(PR_TRUE) {};
};
nsXBLWindowDragHandler::nsXBLWindowDragHandler(nsIDOMEventReceiver* aReceiver)
: nsXBLWindowHandler(nsnull, aReceiver)
{
NS_INIT_ISUPPORTS();
gRefCnt++;
if (gRefCnt == 1) {
kDragEnterAtom = NS_NewAtom("dragenter");
kDragOverAtom = NS_NewAtom("dragover");
kDragExitAtom = NS_NewAtom("dragexit");
kDragDropAtom = NS_NewAtom("dragdrop");
kDragGestureAtom = NS_NewAtom("draggesture");
}
}
nsXBLWindowDragHandler::~nsXBLWindowDragHandler()
{
gRefCnt--;
if (gRefCnt == 0) {
NS_RELEASE(kDragEnterAtom);
NS_RELEASE(kDragOverAtom);
NS_RELEASE(kDragExitAtom);
NS_RELEASE(kDragDropAtom);
NS_RELEASE(kDragGestureAtom);
}
}
NS_IMPL_ISUPPORTS1(nsXBLWindowDragHandler, nsIDOMDragListener)
NS_IMETHODIMP
nsXBLWindowDragHandler::WalkHandlers(nsIDOMEvent* aDragEvent, nsIAtom* aEventType)
{
nsCOMPtr<nsIDOMNSUIEvent> evt = do_QueryInterface(aDragEvent);
PRBool prevent;
evt->GetPreventDefault(&prevent);
if (prevent)
return NS_OK;
// Make sure our event is really a mouse event
nsCOMPtr<nsIDOMMouseEvent> dragEvent(do_QueryInterface(aDragEvent));
if (!dragEvent)
return NS_OK;
EnsureHandlers();
if (!mElement) {
WalkHandlersInternal(aDragEvent, aEventType, mPlatformHandler);
evt->GetPreventDefault(&prevent);
if (prevent)
return NS_OK; // Handled by the platform. Our work here is done.
}
WalkHandlersInternal(aDragEvent, aEventType, mHandler);
return NS_OK;
}
//
// DragGesture
// DragEnter
// DragExit
// DragOver
// DragDrop
//
// On the particular event, walk the handlers we loaded in to
// do something with the event.
//
nsresult
nsXBLWindowDragHandler::DragGesture(nsIDOMEvent* aDragEvent)
{
return WalkHandlers(aDragEvent, kDragGestureAtom);
}
nsresult
nsXBLWindowDragHandler::DragEnter(nsIDOMEvent* aDragEvent)
{
return WalkHandlers(aDragEvent, kDragEnterAtom);
}
nsresult
nsXBLWindowDragHandler::DragExit(nsIDOMEvent* aDragEvent)
{
return WalkHandlers(aDragEvent, kDragExitAtom);
}
nsresult
nsXBLWindowDragHandler::DragOver(nsIDOMEvent* aDragEvent)
{
return WalkHandlers(aDragEvent, kDragOverAtom);
}
nsresult
nsXBLWindowDragHandler::DragDrop(nsIDOMEvent* aDragEvent)
{
return WalkHandlers(aDragEvent, kDragDropAtom);
}
//
// EventMatched
//
// See if the given handler cares about this particular key event
//
PRBool
nsXBLWindowDragHandler :: EventMatched ( nsIXBLPrototypeHandler* inHandler, nsIAtom* inEventType, nsIDOMEvent* inEvent )
{
PRBool matched = PR_FALSE;
nsCOMPtr<nsIDOMMouseEvent> dragEvent ( do_QueryInterface(inEvent) );
if ( dragEvent )
inHandler->MouseEventMatched(inEventType, dragEvent, &matched);
return matched;
}
///////////////////////////////////////////////////////////////////////////////////
nsresult
NS_NewXBLWindowDragHandler(nsIDOMEventReceiver* aReceiver, nsXBLWindowDragHandler** aResult)
{
*aResult = new nsXBLWindowDragHandler(aReceiver);
if (!*aResult)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult);
return NS_OK;
}

View File

@ -0,0 +1,74 @@
/* -*- 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.
*
* Contributor(s):
* - Mike Pinkerton (pinkerton@netscape.com)
*/
#ifndef nsXBLWindowDragHandler_h__
#define nsXBLWindowDragHandler_h__
#include "nsIDOMDragListener.h"
#include "nsIDOMElement.h"
#include "nsXBLWindowHandler.h"
class nsIAtom;
class nsIDOMEventReceiver;
struct nsXBLSpecialDocInfo;
class nsXBLWindowDragHandler : public nsIDOMDragListener, public nsXBLWindowHandler
{
public:
nsXBLWindowDragHandler(nsIDOMEventReceiver* aReceiver);
virtual ~nsXBLWindowDragHandler();
// nsIDOMetc.
virtual nsresult HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; };
virtual nsresult DragGesture(nsIDOMEvent* aMouseEvent) ;
virtual nsresult DragOver(nsIDOMEvent* aMouseEvent) ;
virtual nsresult DragEnter(nsIDOMEvent* aMouseEvent) ;
virtual nsresult DragExit(nsIDOMEvent* aMouseEvent) ;
virtual nsresult DragDrop(nsIDOMEvent* aMouseEvent) ;
NS_DECL_ISUPPORTS
protected:
NS_IMETHOD WalkHandlers(nsIDOMEvent* aKeyEvent, nsIAtom* aEventType);
// check if the given handler cares about the given key event
PRBool EventMatched ( nsIXBLPrototypeHandler* inHandler, nsIAtom* inEventType,
nsIDOMEvent* inEvent ) ;
// We need our own refcount (even though our base class has one) because
// we have our own statics that need to be initialized and the creation of
// other subclasses would cause us to miss things if we shared the counter.
static PRUint32 gRefCnt;
static nsIAtom* kDragGestureAtom;
static nsIAtom* kDragOverAtom;
static nsIAtom* kDragEnterAtom;
static nsIAtom* kDragExitAtom;
static nsIAtom* kDragDropAtom;
};
extern nsresult
NS_NewXBLWindowDragHandler(nsIDOMEventReceiver* aReceiver,
nsXBLWindowDragHandler** aResult);
#endif

View File

@ -0,0 +1,274 @@
/* -*- 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.
*
* Contributor(s):
* - David W. Hyatt (hyatt@netscape.com)
* - Mike Pinkerton (pinkerton@netscape.com)
*/
#include "nsXBLWindowHandler.h"
#include "nsCOMPtr.h"
#include "nsPIWindowRoot.h"
#include "nsIDOMWindowInternal.h"
#include "nsIFocusController.h"
#include "nsIScriptGlobalObject.h"
#include "nsIDocShell.h"
#include "nsIPresShell.h"
#include "nsIDOMElement.h"
#include "nsIDOMEventReceiver.h"
#include "nsIXBLPrototypeHandler.h"
#include "nsIXBLPrototypeBinding.h"
#include "nsIPrivateDOMEvent.h"
#include "nsIDOMEvent.h"
#include "nsIContent.h"
#include "nsHTMLAtoms.h"
#include "nsINameSpaceManager.h"
#include "nsIXBLDocumentInfo.h"
#include "nsIDocument.h"
#include "nsIXBLService.h"
#include "nsIServiceManager.h"
struct nsXBLSpecialDocInfo {
nsCOMPtr<nsIXBLDocumentInfo> mHTMLBindings;
nsCOMPtr<nsIXBLDocumentInfo> mPlatformHTMLBindings;
PRBool mFilesPresent;
nsXBLSpecialDocInfo() :mFilesPresent(PR_TRUE) {};
};
// Init statics
nsXBLSpecialDocInfo* nsXBLWindowHandler::sXBLSpecialDocInfo = nsnull;
PRUint32 nsXBLWindowHandler::sRefCnt = 0;
//
// nsXBLWindowHandler ctor
//
// Increment the refcount
//
nsXBLWindowHandler :: nsXBLWindowHandler (nsIDOMElement* aElement, nsIDOMEventReceiver* aReceiver)
: mElement(aElement), mReceiver(aReceiver)
{
++sRefCnt;
}
//
// nsXBLWindowHandler dtor
//
// Decrement the refcount. If we get to zero, get rid of the static XBL doc
// info.
//
nsXBLWindowHandler :: ~nsXBLWindowHandler ( )
{
--sRefCnt;
if ( !sRefCnt )
delete sXBLSpecialDocInfo;
}
//
// IsEditor
//
// Determine if the document we're working with is Editor or Browser
//
PRBool
nsXBLWindowHandler :: IsEditor()
{
nsCOMPtr<nsPIWindowRoot> windowRoot(do_QueryInterface(mReceiver));
nsCOMPtr<nsIFocusController> focusController;
windowRoot->GetFocusController(getter_AddRefs(focusController));
if (!focusController) {
NS_WARNING("********* Something went wrong! No focus controller on the root!!!\n");
return PR_FALSE;
}
nsCOMPtr<nsIDOMWindowInternal> focusedWindow;
focusController->GetFocusedWindow(getter_AddRefs(focusedWindow));
if (!focusedWindow)
return PR_FALSE;
nsCOMPtr<nsIScriptGlobalObject> obj(do_QueryInterface(focusedWindow));
nsCOMPtr<nsIDocShell> docShell;
obj->GetDocShell(getter_AddRefs(docShell));
nsCOMPtr<nsIPresShell> presShell;
if (docShell)
docShell->GetPresShell(getter_AddRefs(presShell));
if (presShell) {
PRBool isEditor;
presShell->GetDisplayNonTextSelection(&isEditor);
return isEditor;
}
return PR_FALSE;
} // IsEditor
//
// WalkHandlersInternal
//
// Given a particular DOM event and a pointer to the first handler in the list,
// scan through the list to find something to handle the event and then make it
// so.
//
NS_IMETHODIMP
nsXBLWindowHandler::WalkHandlersInternal(nsIDOMEvent* aEvent, nsIAtom* aEventType,
nsIXBLPrototypeHandler* aHandler)
{
nsresult rv;
nsCOMPtr<nsIXBLPrototypeHandler> currHandler = aHandler;
while (currHandler) {
PRBool stopped;
nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(aEvent));
privateEvent->IsDispatchStopped(&stopped);
if (stopped)
return NS_OK;
// if the handler says it wants the event, execute it
if ( EventMatched(currHandler, aEventType, aEvent) ) {
// ...but don't exectute if it is disabled.
nsAutoString disabled;
nsCOMPtr<nsIContent> elt;
currHandler->GetHandlerElement(getter_AddRefs(elt));
elt->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::disabled, disabled);
if (!disabled.Equals(NS_LITERAL_STRING("true"))) {
nsCOMPtr<nsIDOMEventReceiver> rec = mReceiver;
if (mElement)
rec = do_QueryInterface(elt);
rv = currHandler->ExecuteHandler(rec, aEvent);
if (NS_SUCCEEDED(rv))
return NS_OK;
}
}
// the current handler didn't want it, try the next one.
nsCOMPtr<nsIXBLPrototypeHandler> nextHandler;
currHandler->GetNextHandler(getter_AddRefs(nextHandler));
currHandler = nextHandler;
}
return NS_OK;
} // WalkHandlersInternal
//
// GetHandlers
//
//
void
nsXBLWindowHandler::GetHandlers(nsIXBLDocumentInfo* aInfo, const nsAReadableCString& aDocURI,
const nsAReadableCString& aRef, nsIXBLPrototypeHandler** aResult)
{
nsCOMPtr<nsIXBLPrototypeBinding> binding;
aInfo->GetPrototypeBinding(aRef, getter_AddRefs(binding));
if (!binding) {
nsCOMPtr<nsIDocument> doc;
aInfo->GetDocument(getter_AddRefs(doc));
nsCOMPtr<nsIContent> root = getter_AddRefs(doc->GetRootContent());
PRInt32 childCount;
root->ChildCount(childCount);
for (PRInt32 i = 0; i < childCount; i++) {
nsCOMPtr<nsIContent> child;
root->ChildAt(i, *getter_AddRefs(child));
nsAutoString id;
child->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, id);
if (id.EqualsWithConversion(nsPromiseFlatCString(aRef))) {
NS_NewXBLPrototypeBinding(aRef, child, aInfo, getter_AddRefs(binding));
aInfo->SetPrototypeBinding(aRef, binding);
break;
}
}
}
nsCOMPtr<nsIXBLPrototypeHandler> dummy;
binding->GetPrototypeHandlers(aResult, getter_AddRefs(dummy)); // Addref happens here.
} // GetHandlers
//
// EnsureHandlers
//
// Lazily load the XP and platform-specific bindings
//
NS_IMETHODIMP
nsXBLWindowHandler::EnsureHandlers()
{
if (!sXBLSpecialDocInfo)
sXBLSpecialDocInfo = new nsXBLSpecialDocInfo();
if (!sXBLSpecialDocInfo)
return NS_ERROR_OUT_OF_MEMORY;
if (!sXBLSpecialDocInfo->mFilesPresent)
return NS_OK;
if (!sXBLSpecialDocInfo->mHTMLBindings || !sXBLSpecialDocInfo->mPlatformHTMLBindings) {
nsresult rv;
NS_WITH_SERVICE(nsIXBLService, xblService, "@mozilla.org/xbl;1", &rv);
if (xblService) {
// Obtain the two doc infos we need.
xblService->LoadBindingDocumentInfo(nsnull, nsnull,
nsCAutoString("resource:///res/builtin/htmlBindings.xml"),
nsCAutoString(""), PR_TRUE,
getter_AddRefs(sXBLSpecialDocInfo->mHTMLBindings));
xblService->LoadBindingDocumentInfo(nsnull, nsnull,
nsCAutoString("resource:///res/builtin/platformHTMLBindings.xml"),
nsCAutoString(""), PR_TRUE,
getter_AddRefs(sXBLSpecialDocInfo->mPlatformHTMLBindings));
if (!sXBLSpecialDocInfo->mHTMLBindings || !sXBLSpecialDocInfo->mPlatformHTMLBindings) {
sXBLSpecialDocInfo->mFilesPresent = PR_FALSE;
return NS_OK;
}
}
}
// Now determine which handlers we should be using.
if (IsEditor()) {
GetHandlers(sXBLSpecialDocInfo->mPlatformHTMLBindings,
nsCAutoString("resource:///res/builtin/platformHTMLBindings.xml"),
nsCAutoString("editor"),
getter_AddRefs(mPlatformHandler));
GetHandlers(sXBLSpecialDocInfo->mHTMLBindings,
nsCAutoString("resource:///res/builtin/htmlBindings.xml"),
nsCAutoString("editorBase"),
getter_AddRefs(mHandler));
}
else {
GetHandlers(sXBLSpecialDocInfo->mPlatformHTMLBindings,
nsCAutoString("resource:///res/builtin/platformHTMLBindings.xml"),
nsCAutoString("browser"),
getter_AddRefs(mPlatformHandler));
GetHandlers(sXBLSpecialDocInfo->mHTMLBindings,
nsCAutoString("resource:///res/builtin/htmlBindings.xml"),
nsCAutoString("browserBase"),
getter_AddRefs(mHandler));
}
return NS_OK;
} // EnsureHandlers

View File

@ -0,0 +1,91 @@
/* -*- 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.
*
* Contributor(s):
* - David W. Hyatt (hyatt@netscape.com)
* - Mike Pinkerton (pinkerton@netscape.com)
*/
#ifndef nsXBLWindowHandler_h__
#define nsXBLWindowHandler_h__
#include "prtypes.h"
#include "nsError.h"
#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsIXBLPrototypeHandler.h"
class nsIDOMEventReceiver;
class nsIDOMElement;
class nsIDOMEvent;
class nsIAtom;
class nsIXBLDocumentInfo;
struct nsXBLSpecialDocInfo;
//
// class nsXBLWindowHandler
//
// A virtual base class that all window-level event handlers inherit
// from. Provides the code to parse and walk the XBL bindings.
//
class nsXBLWindowHandler
{
public:
nsXBLWindowHandler(nsIDOMElement* aElement, nsIDOMEventReceiver* aReceiver);
virtual ~nsXBLWindowHandler();
protected:
// are we working with editor or browser?
PRBool IsEditor() ;
// lazily load the handlers
virtual nsresult EnsureHandlers();
// walk the handlers, looking for one to handle the event
virtual nsresult WalkHandlersInternal(nsIDOMEvent* aKeyEvent, nsIAtom* aEventType,
nsIXBLPrototypeHandler* aHandler);
// create the event handler list from the given document/URI
void GetHandlers(nsIXBLDocumentInfo* aInfo, const nsAReadableCString& aDocURI,
const nsAReadableCString& aRef, nsIXBLPrototypeHandler** aResult) ;
// does the handler care about the particular event?
virtual PRBool EventMatched ( nsIXBLPrototypeHandler* inHandler, nsIAtom* inEventType,
nsIDOMEvent* inEvent ) = 0;
nsIDOMElement* mElement; // weak ref
nsIDOMEventReceiver* mReceiver; // weak ref
nsCOMPtr<nsIXBLPrototypeHandler> mHandler; // XP bindings
nsCOMPtr<nsIXBLPrototypeHandler> mPlatformHandler; // platform-specific bindings
static nsXBLSpecialDocInfo* sXBLSpecialDocInfo; // holds document info about bindings
private:
static PRUint32 sRefCnt;
}; // class nsXBLWindowHandler
#endif

View File

@ -0,0 +1,183 @@
/* -*- 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.
*
* Contributor(s):
* - Mike Pinkerton (pinkerton@netscape.com)
*/
#include "nsCOMPtr.h"
#include "nsIXBLPrototypeHandler.h"
#include "nsXBLWindowDragHandler.h"
#include "nsIContent.h"
#include "nsIAtom.h"
#include "nsIDOMNSUIEvent.h"
#include "nsIDOMMouseEvent.h"
#include "nsIDOMEventReceiver.h"
#include "nsXBLService.h"
#include "nsIServiceManager.h"
#include "nsHTMLAtoms.h"
#include "nsINameSpaceManager.h"
#include "nsIXBLDocumentInfo.h"
#include "nsIScriptGlobalObject.h"
#include "nsIDOMElement.h"
PRUint32 nsXBLWindowDragHandler::gRefCnt = 0;
nsIAtom* nsXBLWindowDragHandler::kDragGestureAtom = nsnull;
nsIAtom* nsXBLWindowDragHandler::kDragOverAtom = nsnull;
nsIAtom* nsXBLWindowDragHandler::kDragEnterAtom = nsnull;
nsIAtom* nsXBLWindowDragHandler::kDragExitAtom = nsnull;
nsIAtom* nsXBLWindowDragHandler::kDragDropAtom = nsnull;
struct nsXBLSpecialDocInfo {
nsCOMPtr<nsIXBLDocumentInfo> mHTMLBindings;
nsCOMPtr<nsIXBLDocumentInfo> mPlatformHTMLBindings;
PRBool mFilesPresent;
nsXBLSpecialDocInfo() :mFilesPresent(PR_TRUE) {};
};
nsXBLWindowDragHandler::nsXBLWindowDragHandler(nsIDOMEventReceiver* aReceiver)
: nsXBLWindowHandler(nsnull, aReceiver)
{
NS_INIT_ISUPPORTS();
gRefCnt++;
if (gRefCnt == 1) {
kDragEnterAtom = NS_NewAtom("dragenter");
kDragOverAtom = NS_NewAtom("dragover");
kDragExitAtom = NS_NewAtom("dragexit");
kDragDropAtom = NS_NewAtom("dragdrop");
kDragGestureAtom = NS_NewAtom("draggesture");
}
}
nsXBLWindowDragHandler::~nsXBLWindowDragHandler()
{
gRefCnt--;
if (gRefCnt == 0) {
NS_RELEASE(kDragEnterAtom);
NS_RELEASE(kDragOverAtom);
NS_RELEASE(kDragExitAtom);
NS_RELEASE(kDragDropAtom);
NS_RELEASE(kDragGestureAtom);
}
}
NS_IMPL_ISUPPORTS1(nsXBLWindowDragHandler, nsIDOMDragListener)
NS_IMETHODIMP
nsXBLWindowDragHandler::WalkHandlers(nsIDOMEvent* aDragEvent, nsIAtom* aEventType)
{
nsCOMPtr<nsIDOMNSUIEvent> evt = do_QueryInterface(aDragEvent);
PRBool prevent;
evt->GetPreventDefault(&prevent);
if (prevent)
return NS_OK;
// Make sure our event is really a mouse event
nsCOMPtr<nsIDOMMouseEvent> dragEvent(do_QueryInterface(aDragEvent));
if (!dragEvent)
return NS_OK;
EnsureHandlers();
if (!mElement) {
WalkHandlersInternal(aDragEvent, aEventType, mPlatformHandler);
evt->GetPreventDefault(&prevent);
if (prevent)
return NS_OK; // Handled by the platform. Our work here is done.
}
WalkHandlersInternal(aDragEvent, aEventType, mHandler);
return NS_OK;
}
//
// DragGesture
// DragEnter
// DragExit
// DragOver
// DragDrop
//
// On the particular event, walk the handlers we loaded in to
// do something with the event.
//
nsresult
nsXBLWindowDragHandler::DragGesture(nsIDOMEvent* aDragEvent)
{
return WalkHandlers(aDragEvent, kDragGestureAtom);
}
nsresult
nsXBLWindowDragHandler::DragEnter(nsIDOMEvent* aDragEvent)
{
return WalkHandlers(aDragEvent, kDragEnterAtom);
}
nsresult
nsXBLWindowDragHandler::DragExit(nsIDOMEvent* aDragEvent)
{
return WalkHandlers(aDragEvent, kDragExitAtom);
}
nsresult
nsXBLWindowDragHandler::DragOver(nsIDOMEvent* aDragEvent)
{
return WalkHandlers(aDragEvent, kDragOverAtom);
}
nsresult
nsXBLWindowDragHandler::DragDrop(nsIDOMEvent* aDragEvent)
{
return WalkHandlers(aDragEvent, kDragDropAtom);
}
//
// EventMatched
//
// See if the given handler cares about this particular key event
//
PRBool
nsXBLWindowDragHandler :: EventMatched ( nsIXBLPrototypeHandler* inHandler, nsIAtom* inEventType, nsIDOMEvent* inEvent )
{
PRBool matched = PR_FALSE;
nsCOMPtr<nsIDOMMouseEvent> dragEvent ( do_QueryInterface(inEvent) );
if ( dragEvent )
inHandler->MouseEventMatched(inEventType, dragEvent, &matched);
return matched;
}
///////////////////////////////////////////////////////////////////////////////////
nsresult
NS_NewXBLWindowDragHandler(nsIDOMEventReceiver* aReceiver, nsXBLWindowDragHandler** aResult)
{
*aResult = new nsXBLWindowDragHandler(aReceiver);
if (!*aResult)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult);
return NS_OK;
}

View File

@ -0,0 +1,74 @@
/* -*- 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.
*
* Contributor(s):
* - Mike Pinkerton (pinkerton@netscape.com)
*/
#ifndef nsXBLWindowDragHandler_h__
#define nsXBLWindowDragHandler_h__
#include "nsIDOMDragListener.h"
#include "nsIDOMElement.h"
#include "nsXBLWindowHandler.h"
class nsIAtom;
class nsIDOMEventReceiver;
struct nsXBLSpecialDocInfo;
class nsXBLWindowDragHandler : public nsIDOMDragListener, public nsXBLWindowHandler
{
public:
nsXBLWindowDragHandler(nsIDOMEventReceiver* aReceiver);
virtual ~nsXBLWindowDragHandler();
// nsIDOMetc.
virtual nsresult HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; };
virtual nsresult DragGesture(nsIDOMEvent* aMouseEvent) ;
virtual nsresult DragOver(nsIDOMEvent* aMouseEvent) ;
virtual nsresult DragEnter(nsIDOMEvent* aMouseEvent) ;
virtual nsresult DragExit(nsIDOMEvent* aMouseEvent) ;
virtual nsresult DragDrop(nsIDOMEvent* aMouseEvent) ;
NS_DECL_ISUPPORTS
protected:
NS_IMETHOD WalkHandlers(nsIDOMEvent* aKeyEvent, nsIAtom* aEventType);
// check if the given handler cares about the given key event
PRBool EventMatched ( nsIXBLPrototypeHandler* inHandler, nsIAtom* inEventType,
nsIDOMEvent* inEvent ) ;
// We need our own refcount (even though our base class has one) because
// we have our own statics that need to be initialized and the creation of
// other subclasses would cause us to miss things if we shared the counter.
static PRUint32 gRefCnt;
static nsIAtom* kDragGestureAtom;
static nsIAtom* kDragOverAtom;
static nsIAtom* kDragEnterAtom;
static nsIAtom* kDragExitAtom;
static nsIAtom* kDragDropAtom;
};
extern nsresult
NS_NewXBLWindowDragHandler(nsIDOMEventReceiver* aReceiver,
nsXBLWindowDragHandler** aResult);
#endif

View File

@ -0,0 +1,274 @@
/* -*- 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.
*
* Contributor(s):
* - David W. Hyatt (hyatt@netscape.com)
* - Mike Pinkerton (pinkerton@netscape.com)
*/
#include "nsXBLWindowHandler.h"
#include "nsCOMPtr.h"
#include "nsPIWindowRoot.h"
#include "nsIDOMWindowInternal.h"
#include "nsIFocusController.h"
#include "nsIScriptGlobalObject.h"
#include "nsIDocShell.h"
#include "nsIPresShell.h"
#include "nsIDOMElement.h"
#include "nsIDOMEventReceiver.h"
#include "nsIXBLPrototypeHandler.h"
#include "nsIXBLPrototypeBinding.h"
#include "nsIPrivateDOMEvent.h"
#include "nsIDOMEvent.h"
#include "nsIContent.h"
#include "nsHTMLAtoms.h"
#include "nsINameSpaceManager.h"
#include "nsIXBLDocumentInfo.h"
#include "nsIDocument.h"
#include "nsIXBLService.h"
#include "nsIServiceManager.h"
struct nsXBLSpecialDocInfo {
nsCOMPtr<nsIXBLDocumentInfo> mHTMLBindings;
nsCOMPtr<nsIXBLDocumentInfo> mPlatformHTMLBindings;
PRBool mFilesPresent;
nsXBLSpecialDocInfo() :mFilesPresent(PR_TRUE) {};
};
// Init statics
nsXBLSpecialDocInfo* nsXBLWindowHandler::sXBLSpecialDocInfo = nsnull;
PRUint32 nsXBLWindowHandler::sRefCnt = 0;
//
// nsXBLWindowHandler ctor
//
// Increment the refcount
//
nsXBLWindowHandler :: nsXBLWindowHandler (nsIDOMElement* aElement, nsIDOMEventReceiver* aReceiver)
: mElement(aElement), mReceiver(aReceiver)
{
++sRefCnt;
}
//
// nsXBLWindowHandler dtor
//
// Decrement the refcount. If we get to zero, get rid of the static XBL doc
// info.
//
nsXBLWindowHandler :: ~nsXBLWindowHandler ( )
{
--sRefCnt;
if ( !sRefCnt )
delete sXBLSpecialDocInfo;
}
//
// IsEditor
//
// Determine if the document we're working with is Editor or Browser
//
PRBool
nsXBLWindowHandler :: IsEditor()
{
nsCOMPtr<nsPIWindowRoot> windowRoot(do_QueryInterface(mReceiver));
nsCOMPtr<nsIFocusController> focusController;
windowRoot->GetFocusController(getter_AddRefs(focusController));
if (!focusController) {
NS_WARNING("********* Something went wrong! No focus controller on the root!!!\n");
return PR_FALSE;
}
nsCOMPtr<nsIDOMWindowInternal> focusedWindow;
focusController->GetFocusedWindow(getter_AddRefs(focusedWindow));
if (!focusedWindow)
return PR_FALSE;
nsCOMPtr<nsIScriptGlobalObject> obj(do_QueryInterface(focusedWindow));
nsCOMPtr<nsIDocShell> docShell;
obj->GetDocShell(getter_AddRefs(docShell));
nsCOMPtr<nsIPresShell> presShell;
if (docShell)
docShell->GetPresShell(getter_AddRefs(presShell));
if (presShell) {
PRBool isEditor;
presShell->GetDisplayNonTextSelection(&isEditor);
return isEditor;
}
return PR_FALSE;
} // IsEditor
//
// WalkHandlersInternal
//
// Given a particular DOM event and a pointer to the first handler in the list,
// scan through the list to find something to handle the event and then make it
// so.
//
NS_IMETHODIMP
nsXBLWindowHandler::WalkHandlersInternal(nsIDOMEvent* aEvent, nsIAtom* aEventType,
nsIXBLPrototypeHandler* aHandler)
{
nsresult rv;
nsCOMPtr<nsIXBLPrototypeHandler> currHandler = aHandler;
while (currHandler) {
PRBool stopped;
nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(aEvent));
privateEvent->IsDispatchStopped(&stopped);
if (stopped)
return NS_OK;
// if the handler says it wants the event, execute it
if ( EventMatched(currHandler, aEventType, aEvent) ) {
// ...but don't exectute if it is disabled.
nsAutoString disabled;
nsCOMPtr<nsIContent> elt;
currHandler->GetHandlerElement(getter_AddRefs(elt));
elt->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::disabled, disabled);
if (!disabled.Equals(NS_LITERAL_STRING("true"))) {
nsCOMPtr<nsIDOMEventReceiver> rec = mReceiver;
if (mElement)
rec = do_QueryInterface(elt);
rv = currHandler->ExecuteHandler(rec, aEvent);
if (NS_SUCCEEDED(rv))
return NS_OK;
}
}
// the current handler didn't want it, try the next one.
nsCOMPtr<nsIXBLPrototypeHandler> nextHandler;
currHandler->GetNextHandler(getter_AddRefs(nextHandler));
currHandler = nextHandler;
}
return NS_OK;
} // WalkHandlersInternal
//
// GetHandlers
//
//
void
nsXBLWindowHandler::GetHandlers(nsIXBLDocumentInfo* aInfo, const nsAReadableCString& aDocURI,
const nsAReadableCString& aRef, nsIXBLPrototypeHandler** aResult)
{
nsCOMPtr<nsIXBLPrototypeBinding> binding;
aInfo->GetPrototypeBinding(aRef, getter_AddRefs(binding));
if (!binding) {
nsCOMPtr<nsIDocument> doc;
aInfo->GetDocument(getter_AddRefs(doc));
nsCOMPtr<nsIContent> root = getter_AddRefs(doc->GetRootContent());
PRInt32 childCount;
root->ChildCount(childCount);
for (PRInt32 i = 0; i < childCount; i++) {
nsCOMPtr<nsIContent> child;
root->ChildAt(i, *getter_AddRefs(child));
nsAutoString id;
child->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, id);
if (id.EqualsWithConversion(nsPromiseFlatCString(aRef))) {
NS_NewXBLPrototypeBinding(aRef, child, aInfo, getter_AddRefs(binding));
aInfo->SetPrototypeBinding(aRef, binding);
break;
}
}
}
nsCOMPtr<nsIXBLPrototypeHandler> dummy;
binding->GetPrototypeHandlers(aResult, getter_AddRefs(dummy)); // Addref happens here.
} // GetHandlers
//
// EnsureHandlers
//
// Lazily load the XP and platform-specific bindings
//
NS_IMETHODIMP
nsXBLWindowHandler::EnsureHandlers()
{
if (!sXBLSpecialDocInfo)
sXBLSpecialDocInfo = new nsXBLSpecialDocInfo();
if (!sXBLSpecialDocInfo)
return NS_ERROR_OUT_OF_MEMORY;
if (!sXBLSpecialDocInfo->mFilesPresent)
return NS_OK;
if (!sXBLSpecialDocInfo->mHTMLBindings || !sXBLSpecialDocInfo->mPlatformHTMLBindings) {
nsresult rv;
NS_WITH_SERVICE(nsIXBLService, xblService, "@mozilla.org/xbl;1", &rv);
if (xblService) {
// Obtain the two doc infos we need.
xblService->LoadBindingDocumentInfo(nsnull, nsnull,
nsCAutoString("resource:///res/builtin/htmlBindings.xml"),
nsCAutoString(""), PR_TRUE,
getter_AddRefs(sXBLSpecialDocInfo->mHTMLBindings));
xblService->LoadBindingDocumentInfo(nsnull, nsnull,
nsCAutoString("resource:///res/builtin/platformHTMLBindings.xml"),
nsCAutoString(""), PR_TRUE,
getter_AddRefs(sXBLSpecialDocInfo->mPlatformHTMLBindings));
if (!sXBLSpecialDocInfo->mHTMLBindings || !sXBLSpecialDocInfo->mPlatformHTMLBindings) {
sXBLSpecialDocInfo->mFilesPresent = PR_FALSE;
return NS_OK;
}
}
}
// Now determine which handlers we should be using.
if (IsEditor()) {
GetHandlers(sXBLSpecialDocInfo->mPlatformHTMLBindings,
nsCAutoString("resource:///res/builtin/platformHTMLBindings.xml"),
nsCAutoString("editor"),
getter_AddRefs(mPlatformHandler));
GetHandlers(sXBLSpecialDocInfo->mHTMLBindings,
nsCAutoString("resource:///res/builtin/htmlBindings.xml"),
nsCAutoString("editorBase"),
getter_AddRefs(mHandler));
}
else {
GetHandlers(sXBLSpecialDocInfo->mPlatformHTMLBindings,
nsCAutoString("resource:///res/builtin/platformHTMLBindings.xml"),
nsCAutoString("browser"),
getter_AddRefs(mPlatformHandler));
GetHandlers(sXBLSpecialDocInfo->mHTMLBindings,
nsCAutoString("resource:///res/builtin/htmlBindings.xml"),
nsCAutoString("browserBase"),
getter_AddRefs(mHandler));
}
return NS_OK;
} // EnsureHandlers

View File

@ -0,0 +1,91 @@
/* -*- 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.
*
* Contributor(s):
* - David W. Hyatt (hyatt@netscape.com)
* - Mike Pinkerton (pinkerton@netscape.com)
*/
#ifndef nsXBLWindowHandler_h__
#define nsXBLWindowHandler_h__
#include "prtypes.h"
#include "nsError.h"
#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsIXBLPrototypeHandler.h"
class nsIDOMEventReceiver;
class nsIDOMElement;
class nsIDOMEvent;
class nsIAtom;
class nsIXBLDocumentInfo;
struct nsXBLSpecialDocInfo;
//
// class nsXBLWindowHandler
//
// A virtual base class that all window-level event handlers inherit
// from. Provides the code to parse and walk the XBL bindings.
//
class nsXBLWindowHandler
{
public:
nsXBLWindowHandler(nsIDOMElement* aElement, nsIDOMEventReceiver* aReceiver);
virtual ~nsXBLWindowHandler();
protected:
// are we working with editor or browser?
PRBool IsEditor() ;
// lazily load the handlers
virtual nsresult EnsureHandlers();
// walk the handlers, looking for one to handle the event
virtual nsresult WalkHandlersInternal(nsIDOMEvent* aKeyEvent, nsIAtom* aEventType,
nsIXBLPrototypeHandler* aHandler);
// create the event handler list from the given document/URI
void GetHandlers(nsIXBLDocumentInfo* aInfo, const nsAReadableCString& aDocURI,
const nsAReadableCString& aRef, nsIXBLPrototypeHandler** aResult) ;
// does the handler care about the particular event?
virtual PRBool EventMatched ( nsIXBLPrototypeHandler* inHandler, nsIAtom* inEventType,
nsIDOMEvent* inEvent ) = 0;
nsIDOMElement* mElement; // weak ref
nsIDOMEventReceiver* mReceiver; // weak ref
nsCOMPtr<nsIXBLPrototypeHandler> mHandler; // XP bindings
nsCOMPtr<nsIXBLPrototypeHandler> mPlatformHandler; // platform-specific bindings
static nsXBLSpecialDocInfo* sXBLSpecialDocInfo; // holds document info about bindings
private:
static PRUint32 sRefCnt;
}; // class nsXBLWindowHandler
#endif