зеркало из https://github.com/mozilla/gecko-dev.git
First Checked In.
This commit is contained in:
Родитель
53513eb58e
Коммит
b2df6c619b
|
@ -0,0 +1,389 @@
|
|||
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMFocusListener.h"
|
||||
#include "nsIDOMKeyListener.h"
|
||||
#include "nsIDOMMouseListener.h"
|
||||
#include "nsIDOMUIEvent.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIDOMXULDocument.h"
|
||||
#include "nsINSEvent.h"
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIScriptContextOwner.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIDlgDefaultKeys.h"
|
||||
#include "nsRDFCID.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static NS_DEFINE_IID(kDlgDefaultKeysCID, NS_DLGDEFAULTKEYS_CID);
|
||||
static NS_DEFINE_IID(kIDlgDefaultKeysIID, NS_IDLGDEFAULTKEYS_IID);
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
|
||||
static NS_DEFINE_IID(kIDomNodeIID, NS_IDOMNODE_IID);
|
||||
static NS_DEFINE_IID(kIDomElementIID, NS_IDOMELEMENT_IID);
|
||||
static NS_DEFINE_IID(kIDomEventListenerIID, NS_IDOMEVENTLISTENER_IID);
|
||||
static NS_DEFINE_IID(kIDomUIEventIID, NS_IDOMUIEVENT_IID);
|
||||
|
||||
enum eEventType {
|
||||
eKeyPress,
|
||||
eKeyDown,
|
||||
eKeyUp
|
||||
};
|
||||
|
||||
// DialogDefaultKeysImpl
|
||||
//
|
||||
// This is the key listener implementation for default keys in dialogs
|
||||
//
|
||||
class nsDlgDefaultKeysImpl : public nsIDlgDefaultKeys,
|
||||
public nsIDOMKeyListener
|
||||
{
|
||||
public:
|
||||
nsDlgDefaultKeysImpl(void);
|
||||
virtual ~nsDlgDefaultKeysImpl(void);
|
||||
|
||||
public:
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIDlgDefaultKeys
|
||||
NS_IMETHOD Init(
|
||||
nsIDOMElement * aElement,
|
||||
nsIDOMDocument * aDocument);
|
||||
|
||||
// The KeyDown event is what handles the
|
||||
virtual nsresult KeyDown(nsIDOMEvent* aKeyEvent);
|
||||
|
||||
// We don't really care about these events but since we look like a listener we handle 'em
|
||||
virtual nsresult KeyUp(nsIDOMEvent* aKeyEvent);
|
||||
virtual nsresult KeyPress(nsIDOMEvent* aKeyEvent);
|
||||
|
||||
// nsIDOMEventListener
|
||||
virtual nsresult HandleEvent(nsIDOMEvent* anEvent) { return NS_OK; };
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
nsresult DoKey(nsIDOMEvent* aKeyEvent, eEventType aEventType);
|
||||
|
||||
nsIDOMElement* element; // Weak reference. The element will go away first.
|
||||
nsIDOMDocument* mDOMDocument; // Weak reference.
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsDlgDefaultKeysImpl::nsDlgDefaultKeysImpl(void)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
}
|
||||
|
||||
nsDlgDefaultKeysImpl::~nsDlgDefaultKeysImpl(void)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsDlgDefaultKeysImpl)
|
||||
NS_IMPL_RELEASE(nsDlgDefaultKeysImpl)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDlgDefaultKeysImpl::QueryInterface(REFNSIID iid, void** result)
|
||||
{
|
||||
if (! result)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*result = nsnull;
|
||||
if (iid.Equals(nsIDlgDefaultKeys::GetIID()) ||
|
||||
iid.Equals(kISupportsIID)) {
|
||||
*result = NS_STATIC_CAST(nsIDlgDefaultKeys*, this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
else if (iid.Equals(nsIDOMKeyListener::GetIID())) {
|
||||
*result = NS_STATIC_CAST(nsIDOMKeyListener*, this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
else if (iid.Equals(kIDomEventListenerIID)) {
|
||||
*result = (nsIDOMEventListener*)(nsIDOMMouseListener*)this;
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDlgDefaultKeysImpl::Init(
|
||||
nsIDOMElement * aElement,
|
||||
nsIDOMDocument * aDocument)
|
||||
{
|
||||
element = aElement; // Weak reference. Don't addref it.
|
||||
mDOMDocument = aDocument; // Weak reference.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// nsIDOMKeyListener
|
||||
|
||||
/**
|
||||
* Processes a key down event to see if it is a default key for ok
|
||||
* or cancel for the dialog
|
||||
* @param aKeyEvent @see nsIDOMEvent.h
|
||||
* @returns whether the event was consumed or ignored. @see nsresult
|
||||
*/
|
||||
nsresult nsDlgDefaultKeysImpl::KeyDown(nsIDOMEvent* aKeyEvent)
|
||||
{
|
||||
return DoKey(aKeyEvent, eKeyDown);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Stub for a key release event
|
||||
*/
|
||||
nsresult nsDlgDefaultKeysImpl::KeyUp(nsIDOMEvent* aKeyEvent)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Stub for a key typed event
|
||||
*/
|
||||
nsresult nsDlgDefaultKeysImpl::KeyPress(nsIDOMEvent* aKeyEvent)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Here's where the actual work happens
|
||||
*/
|
||||
nsresult nsDlgDefaultKeysImpl::DoKey(nsIDOMEvent* aKeyEvent, eEventType aEventType)
|
||||
{
|
||||
static PRBool inDlgDefaultKey = PR_FALSE;
|
||||
|
||||
if(inDlgDefaultKey)
|
||||
return NS_OK;
|
||||
else
|
||||
inDlgDefaultKey = PR_TRUE;
|
||||
|
||||
if(aKeyEvent && mDOMDocument)
|
||||
{
|
||||
// Get DOMEvent target
|
||||
nsIDOMNode* target = nsnull;
|
||||
aKeyEvent->GetTarget(&target);
|
||||
|
||||
nsIDOMUIEvent * theEvent;
|
||||
aKeyEvent->QueryInterface(kIDomUIEventIID, (void**)&theEvent);
|
||||
|
||||
// locate the window element which holds the top level key bindings
|
||||
nsCOMPtr<nsIDOMElement> rootElement;
|
||||
mDOMDocument->GetDocumentElement(getter_AddRefs(rootElement));
|
||||
if (!rootElement) {
|
||||
inDlgDefaultKey = PR_FALSE;
|
||||
return !NS_OK;
|
||||
}
|
||||
nsString rootName;
|
||||
rootElement->GetNodeName(rootName);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> rootNode(do_QueryInterface(rootElement));
|
||||
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> keysetNode;
|
||||
rootNode->GetFirstChild(getter_AddRefs(keysetNode));
|
||||
while (keysetNode)
|
||||
{
|
||||
nsString keysetNodeType;
|
||||
nsCOMPtr<nsIDOMElement> keysetElement(do_QueryInterface(keysetNode));
|
||||
if(!keysetElement)
|
||||
{
|
||||
inDlgDefaultKey = PR_FALSE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
keysetElement->GetNodeName(keysetNodeType);
|
||||
if (keysetNodeType.Equals("keyset"))
|
||||
{
|
||||
// Given the DOM node and Key Event
|
||||
// Walk the node's children looking for 'key' types
|
||||
|
||||
// If the node isn't tagged disabled
|
||||
// Compares the received key code to found 'key' types
|
||||
// Executes command if found
|
||||
// Marks event as consumed
|
||||
nsCOMPtr<nsIDOMNode> keyNode;
|
||||
keysetNode->GetFirstChild(getter_AddRefs(keyNode));
|
||||
while (keyNode)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> keyElement(do_QueryInterface(keyNode));
|
||||
if (keyElement)
|
||||
{
|
||||
nsString keyNodeType;
|
||||
nsString keyName;
|
||||
nsString disabled;
|
||||
nsString cmdToExecute;
|
||||
keyElement->GetNodeName(keyNodeType);
|
||||
|
||||
if (keyNodeType.Equals("key"))
|
||||
{
|
||||
keyElement->GetAttribute(nsAutoString("key"), keyName);
|
||||
|
||||
keyElement->GetAttribute(nsAutoString("disabled"), disabled);
|
||||
if (disabled == "false")
|
||||
{
|
||||
PRUint32 theChar;
|
||||
|
||||
switch(aEventType)
|
||||
{
|
||||
case eKeyPress:
|
||||
theEvent->GetCharCode(&theChar);
|
||||
break;
|
||||
case eKeyUp:
|
||||
case eKeyDown:
|
||||
theEvent->GetKeyCode(&theChar);
|
||||
break;
|
||||
}
|
||||
|
||||
char tempChar[2];
|
||||
tempChar[0] = theChar;
|
||||
tempChar[1] = 0;
|
||||
nsString tempChar2 = tempChar;
|
||||
//printf("compare key [%s] \n", tempChar2.ToNewCString()); // this leaks
|
||||
// NOTE - convert theChar and keyName to upper
|
||||
keyName.ToUpperCase();
|
||||
tempChar2.ToUpperCase();
|
||||
if (tempChar2 == keyName)
|
||||
{
|
||||
switch(aEventType)
|
||||
{
|
||||
case eKeyPress:
|
||||
keyElement->GetAttribute(nsAutoString("oncommand"), cmdToExecute);
|
||||
break;
|
||||
case eKeyDown:
|
||||
keyElement->GetAttribute(nsAutoString("onkeydown"), cmdToExecute);
|
||||
break;
|
||||
case eKeyUp:
|
||||
keyElement->GetAttribute(nsAutoString("onkeyup"), cmdToExecute);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
//printf("onkeypress [%s] \n", cmdToExecute.ToNewCString()); // this leaks
|
||||
do
|
||||
{
|
||||
|
||||
// Modifier tests passed so execute onclick command
|
||||
|
||||
|
||||
// This code executes in every presentation context in which this
|
||||
// document is appearing.
|
||||
nsCOMPtr<nsIContent> content;
|
||||
content = do_QueryInterface(keyElement);
|
||||
if (!content)
|
||||
{
|
||||
inDlgDefaultKey = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> document;
|
||||
content->GetDocument(*getter_AddRefs(document));
|
||||
|
||||
if (!document)
|
||||
{
|
||||
inDlgDefaultKey = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRInt32 count = document->GetNumberOfShells();
|
||||
for (PRInt32 i = 0; i < count; i++)
|
||||
{
|
||||
nsIPresShell* shell = document->GetShellAt(i);
|
||||
if (nsnull == shell)
|
||||
continue;
|
||||
|
||||
// Retrieve the context in which our DOM event will fire.
|
||||
nsCOMPtr<nsIPresContext> aPresContext;
|
||||
shell->GetPresContext(getter_AddRefs(aPresContext));
|
||||
|
||||
NS_RELEASE(shell);
|
||||
|
||||
// Handle the DOM event
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsKeyEvent event;
|
||||
event.eventStructType = NS_KEY_EVENT;
|
||||
switch (aEventType)
|
||||
{
|
||||
case eKeyPress: event.message = NS_KEY_PRESS; break;
|
||||
case eKeyDown: event.message = NS_KEY_DOWN; break;
|
||||
default: event.message = NS_KEY_UP; break;
|
||||
}
|
||||
aKeyEvent->PreventBubble();
|
||||
aKeyEvent->PreventCapture();
|
||||
content->HandleDOMEvent(*aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
|
||||
|
||||
if (aEventType == eKeyPress)
|
||||
{
|
||||
// Also execute the oncommand handler on a key press.
|
||||
// Execute the oncommand event handler.
|
||||
nsEventStatus stat = nsEventStatus_eIgnore;
|
||||
nsMouseEvent evt;
|
||||
evt.eventStructType = NS_EVENT;
|
||||
evt.message = NS_MENU_ACTION;
|
||||
content->HandleDOMEvent(*aPresContext, &evt, nsnull, NS_EVENT_FLAG_INIT, stat);
|
||||
}
|
||||
}
|
||||
} while (PR_FALSE);
|
||||
} // end if (theChar == keyName)
|
||||
} // end if (disabled == "false")
|
||||
} // end if (keyNodeType.Equals("key"))
|
||||
} // end if(keyelement)
|
||||
|
||||
nsCOMPtr<nsIDOMNode> oldkeyNode(keyNode);
|
||||
oldkeyNode->GetNextSibling(getter_AddRefs(keyNode));
|
||||
|
||||
} // end while(keynode)
|
||||
} // end if (keysetNodeType.Equals("keyset")) {
|
||||
|
||||
nsCOMPtr<nsIDOMNode> oldkeysetNode(keysetNode);
|
||||
oldkeysetNode->GetNextSibling(getter_AddRefs(keysetNode));
|
||||
|
||||
} // end while(keysetNode)
|
||||
} // end if(aKeyEvent && mDOMDocument)
|
||||
|
||||
inDlgDefaultKey = PR_FALSE;
|
||||
return NS_ERROR_BASE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
nsresult
|
||||
NS_NewDlgDefaultKeys(nsIDlgDefaultKeys** aHandler)
|
||||
{
|
||||
nsDlgDefaultKeysImpl * handler = new nsDlgDefaultKeysImpl();
|
||||
if (!handler)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(handler);
|
||||
*aHandler = handler;
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsIDlgDefaultKeys_h__
|
||||
#define nsIDlgDefaultKeys_h__
|
||||
|
||||
// {daedcb42-1dd1-11b2-b1d2-caf06cb40387}
|
||||
#define NS_IDLGDEFAULTKEYS_IID \
|
||||
{ 0xdaedcb42, 0x1dd1, 0x11b2, { 0xb1, 0xd2, 0xca, 0xf0, 0x6c, 0xb4, 0x3, 0x87 } }
|
||||
|
||||
class nsIDOMElement;
|
||||
|
||||
class nsIDlgDefaultKeys: public nsISupports {
|
||||
public:
|
||||
static const nsIID& GetIID() { static nsIID iid = NS_IDLGDEFAULTKEYS_IID; return iid; }
|
||||
|
||||
NS_IMETHOD Init(nsIDOMElement* anElement, nsIDOMDocument* aDocument) = 0;
|
||||
};
|
||||
|
||||
extern nsresult
|
||||
NS_NewDlgDefaultKeys(nsIDlgDefaultKeys** result);
|
||||
|
||||
#endif // nsIDlgDefaultKeys_h__
|
Загрузка…
Ссылка в новой задаче