Adding new tab handling and focus support.

This commit is contained in:
joki%netscape.com 1999-03-02 19:19:24 +00:00
parent f246a5f0dc
commit 0baca6512f
35 changed files with 908 additions and 116 deletions

View File

@ -726,6 +726,8 @@ nsDocument::Reset(nsIURL *aURL)
}
if (nsnull != mRootContent) {
// Ensure that document is nsnull to allow validity checks on content
mRootContent->SetDocument(nsnull, PR_TRUE);
ContentRemoved(nsnull, mRootContent, 0);
NS_IF_RELEASE(mRootContent);
}

View File

@ -749,7 +749,7 @@ nsGenericElement::HandleDOMEvent(nsIPresContext& aPresContext,
}
//Bubbling stage
if ((DOM_EVENT_CAPTURE != aFlags) && (mParent != nsnull)) {
if ((DOM_EVENT_CAPTURE != aFlags) && (mParent != nsnull) && (mDocument != nsnull)) {
ret = mParent->HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
DOM_EVENT_BUBBLE, aEventStatus);
}

View File

@ -64,6 +64,8 @@ public:
NS_IMETHOD GetLinkState(nsIContent *aLink, nsLinkEventState& aState) = 0;
NS_IMETHOD SetActiveLink(nsIContent *aLink) = 0;
NS_IMETHOD SetHoverLink(nsIContent *aLink) = 0;
NS_IMETHOD SetFocusedContent(nsIContent *aContent) = 0;
};
#endif // nsIEventStateManager_h__

View File

@ -44,7 +44,7 @@ EXPORTS = \
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
REQUIRES = xpcom raptor dom js
REQUIRES = xpcom raptor dom js netlib
include $(topsrcdir)/config/config.mk

View File

@ -42,7 +42,7 @@ CPP_OBJS= .\$(OBJDIR)\nsEventListenerManager.obj \
EXPORTS= nsEventListenerManager.h nsEventStateManager.h nsDOMEvent.h nsDOMEventsIIDs.h
LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor \
-I$(PUBLIC)\dom -I$(PUBLIC)\js -I..\..\html\base\src
-I$(PUBLIC)\dom -I$(PUBLIC)\js -I..\..\html\base\src -I$(PUBLIC)\netlib
LCFLAGS = \
$(LCFLAGS) \

View File

@ -31,6 +31,12 @@
#include "nsIDOMHTMLInputElement.h"
#include "nsIDOMHTMLSelectElement.h"
#include "nsIDOMHTMLTextAreaElement.h"
#include "nsIDOMHTMLAreaElement.h"
#include "nsIDOMHTMLButtonElement.h"
#include "nsIDOMHTMLObjectElement.h"
#include "nsINameSpaceManager.h" // for kNameSpaceID_HTML
#include "nsIWebShell.h"
#include "nsIFocusableContent.h"
static NS_DEFINE_IID(kIEventStateManagerIID, NS_IEVENTSTATEMANAGER_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
@ -38,6 +44,11 @@ static NS_DEFINE_IID(kIDOMHTMLAnchorElementIID, NS_IDOMHTMLANCHORELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLInputElementIID, NS_IDOMHTMLINPUTELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLSelectElementIID, NS_IDOMHTMLSELECTELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLTextAreaElementIID, NS_IDOMHTMLTEXTAREAELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLAreaElementIID, NS_IDOMHTMLAREAELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLObjectElementIID, NS_IDOMHTMLOBJECTELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLButtonElementIID, NS_IDOMHTMLBUTTONELEMENT_IID);
static NS_DEFINE_IID(kIWebShellIID, NS_IWEB_SHELL_IID);
static NS_DEFINE_IID(kIFocusableContentIID, NS_IFOCUSABLECONTENT_IID);
nsEventStateManager::nsEventStateManager() {
mLastMouseOverFrame = nsnull;
@ -51,6 +62,7 @@ nsEventStateManager::nsEventStateManager() {
mCurrentFocus = nsnull;
mDocument = nsnull;
mPresContext = nsnull;
mCurrentTabIndex = 0;
NS_INIT_REFCNT();
}
@ -89,10 +101,7 @@ nsEventStateManager::PreHandleEvent(nsIPresContext& aPresContext,
//GenerateMouseEnterExit(aPresContext, aEvent, aTargetFrame);
break;
case NS_GOTFOCUS:
NS_IF_RELEASE(mCurrentFocus);
if (nsnull != mCurrentTarget) {
mCurrentTarget->GetContent(&mCurrentFocus);
}
//XXX Do we need window related focus change stuff here?
break;
}
return NS_OK;
@ -117,8 +126,14 @@ nsEventStateManager::PostHandleEvent(nsIPresContext& aPresContext,
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
case NS_MOUSE_RIGHT_BUTTON_DOWN:
{
if (nsnull != aEvent->widget) {
aEvent->widget->SetFocus();
nsIContent* newFocus;
mCurrentTarget->GetContent(&newFocus);
if (newFocus) {
if (!ChangeFocus(newFocus, PR_TRUE)) {
if (nsnull != aEvent->widget) {
aEvent->widget->SetFocus();
}
}
}
}
//Break left out on purpose
@ -132,7 +147,8 @@ nsEventStateManager::PostHandleEvent(nsIPresContext& aPresContext,
if (nsEventStatus_eConsumeNoDefault != aStatus) {
switch(((nsKeyEvent*)aEvent)->keyCode) {
case NS_VK_TAB:
ShiftFocus();
//Shift focus forward or back depending on shift key
ShiftFocus(!((nsInputEvent*)aEvent)->isShift);
aStatus = nsEventStatus_eConsumeNoDefault;
break;
case NS_VK_PAGE_DOWN:
@ -417,8 +433,28 @@ nsEventStateManager::DispatchKeyPressEvent(nsIPresContext& aPresContext,
return ret;
}
PRBool
nsEventStateManager::ChangeFocus(nsIContent* aFocus, PRBool aSetFocus)
{
nsIFocusableContent *focusChange;
if (NS_OK == aFocus->QueryInterface(kIFocusableContentIID,(void **)&focusChange)) {
if (aSetFocus) {
focusChange->SetFocus(mPresContext);
}
else {
focusChange->RemoveFocus(mPresContext);
}
NS_RELEASE(focusChange);
return PR_TRUE;
}
//XXX Need to deal with Object tag
return PR_FALSE;
}
void
nsEventStateManager::ShiftFocus()
nsEventStateManager::ShiftFocus(PRBool forward)
{
if (nsnull == mPresContext) {
return;
@ -439,36 +475,34 @@ nsEventStateManager::ShiftFocus()
if (nsnull == mCurrentFocus) {
return;
}
mCurrentTabIndex = forward ? 1 : 0;
}
nsIContent* next = GetNextTabbableContent(mCurrentFocus, nsnull, mCurrentFocus);
nsIContent* next = GetNextTabbableContent(mCurrentFocus, nsnull, mCurrentFocus, forward);
if (nsnull == next) {
NS_IF_RELEASE(mCurrentFocus);
//XXX pass focus up to webshellcontainer FocusAvailable
//Pass focus up to nsIWebShellContainer FocusAvailable
nsISupports* container;
mPresContext->GetContainer(&container);
if (nsnull != container) {
nsIWebShell* webShell;
if (NS_OK == container->QueryInterface(kIWebShellIID, (void**)&webShell)) {
nsIWebShellContainer* webShellContainer;
webShell->GetContainer(webShellContainer);
if (nsnull != webShellContainer) {
webShellContainer->FocusAvailable(webShell);
NS_RELEASE(webShellContainer);
}
NS_RELEASE(webShell);
}
NS_RELEASE(container);
}
return;
}
nsIDOMHTMLAnchorElement *nextAnchor;
nsIDOMHTMLInputElement *nextInput;
nsIDOMHTMLSelectElement *nextSelect;
nsIDOMHTMLTextAreaElement *nextTextArea;
if (NS_OK == next->QueryInterface(kIDOMHTMLAnchorElementIID,(void **)&nextAnchor)) {
nextAnchor->Focus();
NS_RELEASE(nextAnchor);
}
else if (NS_OK == next->QueryInterface(kIDOMHTMLInputElementIID,(void **)&nextInput)) {
nextInput->Focus();
NS_RELEASE(nextInput);
}
else if (NS_OK == next->QueryInterface(kIDOMHTMLSelectElementIID,(void **)&nextSelect)) {
nextSelect->Focus();
NS_RELEASE(nextSelect);
}
else if (NS_OK == next->QueryInterface(kIDOMHTMLTextAreaElementIID,(void **)&nextTextArea)) {
nextTextArea->Focus();
NS_RELEASE(nextTextArea);
}
ChangeFocus(next, PR_TRUE);
NS_IF_RELEASE(mCurrentFocus);
mCurrentFocus = next;
@ -478,29 +512,31 @@ nsEventStateManager::ShiftFocus()
* At some point this will need to be linked into HTML 4.0 tabindex
*/
nsIContent*
nsEventStateManager::GetNextTabbableContent(nsIContent* aParent, nsIContent* aChild, nsIContent* aTop)
nsEventStateManager::GetNextTabbableContent(nsIContent* aParent, nsIContent* aChild, nsIContent* aTop, PRBool forward)
{
PRInt32 count, index;
aParent->ChildCount(count);
if (nsnull != aChild) {
aParent->IndexOf(aChild, index);
index += 1;
index += forward ? 1 : -1;
}
else {
index = 0;
index = forward ? 0 : count;
}
for (;index < count;index++) {
for (;index < count && index >= 0;index += forward ? 1 : -1) {
nsIContent* child;
aParent->ChildAt(index, child);
nsIContent* content = GetNextTabbableContent(child, nsnull, aTop);
nsIContent* content = GetNextTabbableContent(child, nsnull, aTop, forward);
if (content != nsnull) {
NS_IF_RELEASE(child);
return content;
}
if (nsnull != child) {
nsIAtom* tag;
PRInt32 tabIndex = -1;
PRBool disabled = PR_TRUE;
PRBool hidden = PR_FALSE;
@ -509,6 +545,7 @@ nsEventStateManager::GetNextTabbableContent(nsIContent* aParent, nsIContent* aCh
nsIDOMHTMLInputElement *nextInput;
if (NS_OK == child->QueryInterface(kIDOMHTMLInputElementIID,(void **)&nextInput)) {
nextInput->GetDisabled(&disabled);
nextInput->GetTabIndex(&tabIndex);
nsAutoString type;
nextInput->GetType(type);
@ -522,6 +559,7 @@ nsEventStateManager::GetNextTabbableContent(nsIContent* aParent, nsIContent* aCh
nsIDOMHTMLSelectElement *nextSelect;
if (NS_OK == child->QueryInterface(kIDOMHTMLSelectElementIID,(void **)&nextSelect)) {
nextSelect->GetDisabled(&disabled);
nextSelect->GetTabIndex(&tabIndex);
NS_RELEASE(nextSelect);
}
}
@ -529,20 +567,48 @@ nsEventStateManager::GetNextTabbableContent(nsIContent* aParent, nsIContent* aCh
nsIDOMHTMLTextAreaElement *nextTextArea;
if (NS_OK == child->QueryInterface(kIDOMHTMLTextAreaElementIID,(void **)&nextTextArea)) {
nextTextArea->GetDisabled(&disabled);
nextTextArea->GetTabIndex(&tabIndex);
NS_RELEASE(nextTextArea);
}
}
//XXX Not all of these are focusable yet.
else if(nsHTMLAtoms::a==tag
//nsHTMLAtoms::area==tag ||
//nsHTMLAtoms::button==tag ||
//nsHTMLAtoms::object==tag
) {
else if(nsHTMLAtoms::a==tag) {
nsIDOMHTMLAnchorElement *nextAnchor;
if (NS_OK == child->QueryInterface(kIDOMHTMLAnchorElementIID,(void **)&nextAnchor)) {
nextAnchor->GetTabIndex(&tabIndex);
NS_RELEASE(nextAnchor);
}
disabled = PR_FALSE;
}
else if(nsHTMLAtoms::button==tag) {
nsIDOMHTMLButtonElement *nextButton;
if (NS_OK == child->QueryInterface(kIDOMHTMLButtonElementIID,(void **)&nextButton)) {
nextButton->GetTabIndex(&tabIndex);
nextButton->GetDisabled(&disabled);
NS_RELEASE(nextButton);
}
}
else if(nsHTMLAtoms::area==tag) {
nsIDOMHTMLAreaElement *nextArea;
if (NS_OK == child->QueryInterface(kIDOMHTMLAreaElementIID,(void **)&nextArea)) {
nextArea->GetTabIndex(&tabIndex);
NS_RELEASE(nextArea);
}
disabled = PR_FALSE;
}
else if(nsHTMLAtoms::object==tag) {
nsIDOMHTMLObjectElement *nextObject;
if (NS_OK == child->QueryInterface(kIDOMHTMLObjectElementIID,(void **)&nextObject)) {
nextObject->GetTabIndex(&tabIndex);
NS_RELEASE(nextObject);
}
disabled = PR_FALSE;
}
if (!disabled && !hidden) {
//TabIndex not set (-1) treated at same level as set to 0
tabIndex = tabIndex < 0 ? 0 : tabIndex;
if (!disabled && !hidden && mCurrentTabIndex == tabIndex) {
return child;
}
NS_RELEASE(child);
@ -553,15 +619,56 @@ nsEventStateManager::GetNextTabbableContent(nsIContent* aParent, nsIContent* aCh
nsIContent* nextParent;
aParent->GetParent(nextParent);
if (nsnull != nextParent) {
nsIContent* content = GetNextTabbableContent(nextParent, aParent, nextParent);
nsIContent* content = GetNextTabbableContent(nextParent, aParent, nextParent, forward);
NS_RELEASE(nextParent);
return content;
}
//Reached end of document
else {
//If already at lowest priority tab (0), end
if (0 == mCurrentTabIndex) {
return nsnull;
}
//else continue looking for next highest priority tab
mCurrentTabIndex = GetNextTabIndex(aParent, forward);
nsIContent* content = GetNextTabbableContent(aParent, nsnull, aParent, forward);
return content;
}
}
return nsnull;
}
PRInt32
nsEventStateManager::GetNextTabIndex(nsIContent* aParent, PRBool forward)
{
PRInt32 count, tabIndex = 0;
aParent->ChildCount(count);
for (PRInt32 index = 0; index < count; index++) {
nsIContent* child;
PRInt32 childTabIndex;
aParent->ChildAt(index, child);
childTabIndex = GetNextTabIndex(child, forward);
if (childTabIndex > mCurrentTabIndex && childTabIndex != tabIndex) {
tabIndex = (tabIndex == 0 || childTabIndex < tabIndex) ? childTabIndex : tabIndex;
}
nsAutoString tabIndexStr;
child->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::tabindex, tabIndexStr);
PRInt32 ec, val = tabIndexStr.ToInteger(&ec);
if (NS_OK == ec && val > mCurrentTabIndex && val != tabIndex) {
tabIndex = (tabIndex == 0 || val < tabIndex) ? val : tabIndex;
}
NS_RELEASE(child);
}
return tabIndex;
}
NS_IMETHODIMP
nsEventStateManager::GetEventTarget(nsIFrame **aFrame)
{
@ -636,6 +743,51 @@ nsEventStateManager::SetHoverLink(nsIContent *aLink)
return NS_OK;
}
NS_IMETHODIMP
nsEventStateManager::SetFocusedContent(nsIContent *aContent)
{
if (mCurrentFocus == aContent) {
return NS_OK;
}
if (mCurrentFocus) {
ChangeFocus(mCurrentFocus, PR_FALSE);
//fire blur
nsEventStatus status = nsEventStatus_eIgnore;
nsEvent event;
event.eventStructType = NS_EVENT;
event.message = NS_BLUR_CONTENT;
if (nsnull != mPresContext) {
mCurrentFocus->HandleDOMEvent(*mPresContext, &event, nsnull, DOM_EVENT_INIT, status);
}
NS_RELEASE(mCurrentFocus);
}
//fire focus
nsEventStatus status = nsEventStatus_eIgnore;
nsEvent event;
event.eventStructType = NS_EVENT;
event.message = NS_FOCUS_CONTENT;
if (nsnull != mPresContext) {
aContent->HandleDOMEvent(*mPresContext, &event, nsnull, DOM_EVENT_INIT, status);
}
nsAutoString tabIndex;
aContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::tabindex, tabIndex);
PRInt32 ec, val = tabIndex.ToInteger(&ec);
if (NS_OK == ec) {
mCurrentTabIndex = val;
}
mCurrentFocus = aContent;
NS_IF_ADDREF(mCurrentFocus);
return NS_OK;
}
nsresult NS_NewEventStateManager(nsIEventStateManager** aInstancePtrResult)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "nsnull ptr");

View File

@ -54,13 +54,17 @@ public:
NS_IMETHOD SetActiveLink(nsIContent *aLink);
NS_IMETHOD SetHoverLink(nsIContent *aLink);
NS_IMETHOD SetFocusedContent(nsIContent *aContent);
protected:
void UpdateCursor(nsIPresContext& aPresContext, nsPoint& aPoint, nsIFrame* aTargetFrame, nsEventStatus& aStatus);
void GenerateMouseEnterExit(nsIPresContext& aPresContext, nsGUIEvent* aEvent);
NS_IMETHOD DispatchKeyPressEvent(nsIPresContext& aPresContext, nsKeyEvent *aEvent, nsEventStatus& aStatus);
NS_IMETHOD CheckForAndDispatchClick(nsIPresContext& aPresContext, nsMouseEvent *aEvent, nsEventStatus& aStatus);
void ShiftFocus();
nsIContent* GetNextTabbableContent(nsIContent* aParent, nsIContent* aChild, nsIContent* aTop);
PRBool ChangeFocus(nsIContent* aFocus, PRBool aSetFocus);
void ShiftFocus(PRBool foward);
nsIContent* GetNextTabbableContent(nsIContent* aParent, nsIContent* aChild, nsIContent* aTop, PRBool foward);
PRInt32 GetNextTabIndex(nsIContent* aParent, PRBool foward);
//Any frames here must be checked for validity in ClearFrameRefs
nsIFrame* mCurrentTarget;
@ -72,6 +76,7 @@ protected:
nsIContent* mActiveLink;
nsIContent* mHoverLink;
nsIContent* mCurrentFocus;
PRInt32 mCurrentTabIndex;
//Not refcnted
nsIPresContext* mPresContext;

View File

@ -25,6 +25,7 @@ include $(DEPTH)/config/autoconf.mk
EXPORTS = \
nsIFormControl.h \
nsIForm.h \
nsIFocusableContent.h \
$(NULL)
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))

View File

@ -17,7 +17,7 @@
DEPTH=..\..\..\..
EXPORTS=nsIFormControl.h nsIForm.h
EXPORTS=nsIFormControl.h nsIForm.h nsIFocusableContent.h
MODULE=raptor

View File

@ -28,6 +28,7 @@
#include "nsIPresContext.h"
#include "nsINameSpaceManager.h"
#include "nsIURL.h"
#include "nsIFocusableContent.h"
#include "nsIEventStateManager.h"
#include "nsDOMEvent.h"
@ -38,11 +39,13 @@
// custom frame
static NS_DEFINE_IID(kIDOMHTMLAnchorElementIID, NS_IDOMHTMLANCHORELEMENT_IID);
static NS_DEFINE_IID(kIFocusableContentIID, NS_IFOCUSABLECONTENT_IID);
class nsHTMLAnchorElement : public nsIDOMHTMLAnchorElement,
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent
public nsIHTMLContent,
public nsIFocusableContent
{
public:
nsHTMLAnchorElement(nsIAtom* aTag);
@ -100,6 +103,10 @@ public:
// nsIHTMLContent
NS_IMPL_IHTMLCONTENT_USING_GENERIC(mInner)
// nsIFocusableContent
NS_IMETHOD SetFocus(nsIPresContext* aPresContext);
NS_IMETHOD RemoveFocus(nsIPresContext* aPresContext);
protected:
nsGenericHTMLContainerElement mInner;
};
@ -142,6 +149,11 @@ nsHTMLAnchorElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
mRefCnt++;
return NS_OK;
}
else if (aIID.Equals(kIFocusableContentIID)) {
*aInstancePtr = (void*)(nsIFocusableContent*) this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
@ -183,6 +195,26 @@ nsHTMLAnchorElement::Focus()
return NS_OK;
}
NS_IMETHODIMP
nsHTMLAnchorElement::SetFocus(nsIPresContext* aPresContext)
{
nsIEventStateManager* esm;
if (NS_OK == aPresContext->GetEventStateManager(&esm)) {
esm->SetFocusedContent(this);
NS_RELEASE(esm);
}
// XXX write me
return NS_OK;
}
NS_IMETHODIMP
nsHTMLAnchorElement::RemoveFocus(nsIPresContext* aPresContext)
{
// XXX write me
return NS_OK;
}
NS_IMETHODIMP
nsHTMLAnchorElement::StringToAttribute(nsIAtom* aAttribute,
const nsString& aValue,
@ -261,7 +293,7 @@ nsHTMLAnchorElement::HandleDOMEvent(nsIPresContext& aPresContext,
}
break;
case NS_MOUSE_LEFT_BUTTON_UP:
case NS_MOUSE_LEFT_CLICK:
{
nsIEventStateManager *stateManager;
nsLinkEventState linkState;

View File

@ -26,13 +26,17 @@
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "nsIFocusableContent.h"
#include "nsIEventStateManager.h"
static NS_DEFINE_IID(kIDOMHTMLAreaElementIID, NS_IDOMHTMLAREAELEMENT_IID);
static NS_DEFINE_IID(kIFocusableContentIID, NS_IFOCUSABLECONTENT_IID);
class nsHTMLAreaElement : public nsIDOMHTMLAreaElement,
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent
public nsIHTMLContent,
public nsIFocusableContent
{
public:
nsHTMLAreaElement(nsIAtom* aTag);
@ -80,6 +84,10 @@ public:
// nsIHTMLContent
NS_IMPL_IHTMLCONTENT_USING_GENERIC(mInner)
// nsIFocusableContent
NS_IMETHOD SetFocus(nsIPresContext* aPresContext);
NS_IMETHOD RemoveFocus(nsIPresContext* aPresContext);
protected:
nsGenericHTMLLeafElement mInner;
};
@ -122,6 +130,11 @@ nsHTMLAreaElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
NS_ADDREF_THIS();
return NS_OK;
}
else if (aIID.Equals(kIFocusableContentIID)) {
*aInstancePtr = (void*)(nsIFocusableContent*) this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
@ -191,6 +204,7 @@ nsHTMLAreaElement::HandleDOMEvent(nsIPresContext& aPresContext,
NS_IMETHODIMP
nsHTMLAreaElement::GetStyleHintForAttributeChange(const nsIAtom* aAttribute,
PRInt32 *aHint) const
{
if ((aAttribute == nsHTMLAtoms::alt) ||
(aAttribute == nsHTMLAtoms::coords) ||
@ -208,5 +222,27 @@ nsHTMLAreaElement::GetStyleHintForAttributeChange(const nsIAtom* aAttribute,
else {
nsGenericHTMLElement::GetStyleHintForCommonAttributes(this, aAttribute, aHint);
}
return NS_OK;
}
NS_IMETHODIMP
nsHTMLAreaElement::SetFocus(nsIPresContext* aPresContext)
{
nsIEventStateManager* esm;
if (NS_OK == aPresContext->GetEventStateManager(&esm)) {
esm->SetFocusedContent(this);
NS_RELEASE(esm);
}
// XXX write me
return NS_OK;
}
NS_IMETHODIMP
nsHTMLAreaElement::RemoveFocus(nsIPresContext* aPresContext)
{
// XXX write me
return NS_OK;
}

View File

@ -31,17 +31,20 @@
#include "nsIFormControl.h"
#include "nsIForm.h"
#include "nsIURL.h"
#include "nsIFocusableContent.h"
#include "nsIEventStateManager.h"
#include "nsDOMEvent.h"
static NS_DEFINE_IID(kIDOMHTMLButtonElementIID, NS_IDOMHTMLBUTTONELEMENT_IID);
static NS_DEFINE_IID(kIFocusableContentIID, NS_IFOCUSABLECONTENT_IID);
class nsHTMLButtonElement : public nsIDOMHTMLButtonElement,
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent,
public nsIFormControl
public nsIFormControl,
public nsIFocusableContent
{
public:
nsHTMLButtonElement(nsIAtom* aTag);
@ -95,6 +98,10 @@ public:
NS_IMETHOD SetWidget(nsIWidget* aWidget) { return NS_OK; };
NS_IMETHOD Init() { return NS_OK; }
// nsIFocusableContent
NS_IMETHOD SetFocus(nsIPresContext* aPresContext);
NS_IMETHOD RemoveFocus(nsIPresContext* aPresContext);
protected:
nsGenericHTMLContainerElement mInner;
nsIForm* mForm;
@ -160,6 +167,11 @@ nsHTMLButtonElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
NS_ADDREF_THIS();
return NS_OK;
}
else if (aIID.Equals(kIFocusableContentIID)) {
*aInstancePtr = (void*)(nsIFocusableContent*) this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
@ -259,6 +271,26 @@ nsHTMLButtonElement::Focus()
return NS_OK;
}
NS_IMETHODIMP
nsHTMLButtonElement::SetFocus(nsIPresContext* aPresContext)
{
nsIEventStateManager* esm;
if (NS_OK == aPresContext->GetEventStateManager(&esm)) {
esm->SetFocusedContent(this);
NS_RELEASE(esm);
}
// XXX write me
return NS_OK;
}
NS_IMETHODIMP
nsHTMLButtonElement::RemoveFocus(nsIPresContext* aPresContext)
{
// XXX write me
return NS_OK;
}
static nsGenericHTMLElement::EnumTable kButtonTypeTable[] = {
{ "button", NS_FORM_BUTTON_BUTTON },
{ "reset", NS_FORM_BUTTON_RESET },

View File

@ -41,6 +41,8 @@
#include "nsIPresShell.h"
#include "nsIFormControlFrame.h"
#include "nsIFrame.h"
#include "nsIFocusableContent.h"
#include "nsIEventStateManager.h"
// XXX align=left, hspace, vspace, border? other nav4 attrs
@ -52,12 +54,14 @@ static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID);
static NS_DEFINE_IID(kIRadioIID, NS_IRADIOBUTTON_IID);
static NS_DEFINE_IID(kICheckButtonIID, NS_ICHECKBUTTON_IID);
static NS_DEFINE_IID(kIFormControlFrameIID, NS_IFORMCONTROLFRAME_IID);
static NS_DEFINE_IID(kIFocusableContentIID, NS_IFOCUSABLECONTENT_IID);
class nsHTMLInputElement : public nsIDOMHTMLInputElement,
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent,
public nsIFormControl
public nsIFormControl,
public nsIFocusableContent
{
public:
nsHTMLInputElement(nsIAtom* aTag);
@ -133,6 +137,10 @@ public:
NS_IMETHOD SetWidget(nsIWidget* aWidget);
NS_IMETHOD Init() { return NS_OK; }
// nsIFocusableContent
NS_IMETHOD SetFocus(nsIPresContext* aPresContext);
NS_IMETHOD RemoveFocus(nsIPresContext* aPresContext);
protected:
nsGenericHTMLLeafElement mInner;
nsIWidget* mWidget; // XXX this needs to go away when FindFrameWithContent is efficient
@ -206,6 +214,11 @@ nsHTMLInputElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
NS_ADDREF_THIS();
return NS_OK;
}
else if (aIID.Equals(kIFocusableContentIID)) {
*aInstancePtr = (void*)(nsIFocusableContent*) this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
@ -404,6 +417,29 @@ nsHTMLInputElement::Focus()
return NS_OK;
}
NS_IMETHODIMP
nsHTMLInputElement::SetFocus(nsIPresContext* aPresContext)
{
nsIEventStateManager* esm;
if (NS_OK == aPresContext->GetEventStateManager(&esm)) {
esm->SetFocusedContent(this);
NS_RELEASE(esm);
}
// XXX Should focus only this presContext
Focus();
return NS_OK;
}
NS_IMETHODIMP
nsHTMLInputElement::RemoveFocus(nsIPresContext* aPresContext)
{
// XXX Should focus only this presContext
Blur();
return NS_OK;
}
NS_IMETHODIMP
nsHTMLInputElement::Select()
{

View File

@ -33,6 +33,8 @@
#include "nsIWidget.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIDOMHTMLOptionElement.h"
#include "nsIFocusableContent.h"
#include "nsIEventStateManager.h"
// Notify/query select frame for selectedIndex
#include "nsIDocument.h"
@ -46,6 +48,7 @@ static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIFormIID, NS_IFORM_IID);
static NS_DEFINE_IID(kIFormControlFrameIID, NS_IFORMCONTROLFRAME_IID);
static NS_DEFINE_IID(kIFocusableContentIID, NS_IFOCUSABLECONTENT_IID);
class nsHTMLSelectElement;
@ -77,7 +80,8 @@ class nsHTMLSelectElement : public nsIDOMHTMLSelectElement,
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent,
public nsIFormControl
public nsIFormControl,
public nsIFocusableContent
{
public:
nsHTMLSelectElement(nsIAtom* aTag);
@ -137,6 +141,9 @@ public:
NS_IMETHOD SetWidget(nsIWidget* aWidget);
NS_IMETHOD Init();
NS_IMETHOD SetFocus(nsIPresContext* aPresContext);
NS_IMETHOD RemoveFocus(nsIPresContext* aPresContext);
protected:
nsGenericHTMLContainerElement mInner;
nsIWidget* mWidget; // XXX this needs to go away when FindFrameWithContent is efficient
@ -205,6 +212,11 @@ nsHTMLSelectElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
mRefCnt++;
return NS_OK;
}
else if (aIID.Equals(kIFocusableContentIID)) {
*aInstancePtr = (void*)(nsIFocusableContent*) this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
@ -398,6 +410,28 @@ nsHTMLSelectElement::Focus()
return NS_OK;
}
NS_IMETHODIMP
nsHTMLSelectElement::SetFocus(nsIPresContext* aPresContext)
{
nsIEventStateManager* esm;
if (NS_OK == aPresContext->GetEventStateManager(&esm)) {
esm->SetFocusedContent(this);
NS_RELEASE(esm);
}
// XXX Should focus only this presContext
Focus();
return NS_OK;
}
NS_IMETHODIMP
nsHTMLSelectElement::RemoveFocus(nsIPresContext* aPresContext)
{
// XXX Should focus only this presContext
Blur();
return NS_OK;
}
NS_IMETHODIMP
nsHTMLSelectElement::StringToAttribute(nsIAtom* aAttribute,
const nsString& aValue,

View File

@ -33,18 +33,22 @@
#include "nsITextAreaWidget.h"
#include "nsIHTMLAttributes.h"
#include "nsIFormControlFrame.h"
#include "nsIFocusableContent.h"
#include "nsIEventStateManager.h"
static NS_DEFINE_IID(kIDOMHTMLTextAreaElementIID, NS_IDOMHTMLTEXTAREAELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIFormIID, NS_IFORM_IID);
static NS_DEFINE_IID(kITextAreaWidgetIID, NS_ITEXTAREAWIDGET_IID);
static NS_DEFINE_IID(kIFocusableContentIID, NS_IFOCUSABLECONTENT_IID);
class nsHTMLTextAreaElement : public nsIDOMHTMLTextAreaElement,
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent,
public nsIFormControl
public nsIFormControl,
public nsIFocusableContent
{
public:
nsHTMLTextAreaElement(nsIAtom* aTag);
@ -105,6 +109,10 @@ public:
NS_IMETHOD SetWidget(nsIWidget* aWidget);
NS_IMETHOD Init() { return NS_OK; }
// nsIFocusableContent
NS_IMETHOD SetFocus(nsIPresContext* aPresContext);
NS_IMETHOD RemoveFocus(nsIPresContext* aPresContext);
protected:
nsGenericHTMLContainerElement mInner;
nsIWidget* mWidget; // XXX this needs to go away when FindFrameWithContent is efficient
@ -163,6 +171,11 @@ nsHTMLTextAreaElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
mRefCnt++;
return NS_OK;
}
else if (aIID.Equals(kIFocusableContentIID)) {
*aInstancePtr = (void*)(nsIFocusableContent*) this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
@ -233,6 +246,29 @@ nsHTMLTextAreaElement::Focus() // XXX not tested
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTextAreaElement::SetFocus(nsIPresContext* aPresContext)
{
nsIEventStateManager* esm;
if (NS_OK == aPresContext->GetEventStateManager(&esm)) {
esm->SetFocusedContent(this);
NS_RELEASE(esm);
}
// XXX Should focus only this presContext
Focus();
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTextAreaElement::RemoveFocus(nsIPresContext* aPresContext)
{
// XXX Should focus only this presContext
Blur();
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTextAreaElement::Select() // XXX not tested
{

View File

@ -1638,7 +1638,32 @@ nsWebShell::FindWebShellWithName(const PRUnichar* aName, nsIWebShell*& aResult)
NS_IMETHODIMP
nsWebShell::FocusAvailable(nsIWebShell* aFocusedWebShell)
{
//XXX Move focus to next child, or if on last child, call focus available on next container
//If the WebShell with focus is us, pass this up to container
if (this == aFocusedWebShell && nsnull != mContainer) {
mContainer->FocusAvailable(this);
}
nsIWebShell* shell = nsnull;
//Other wise, check children and move focus to next one
PRInt32 i, n = mChildren.Count();
for (i = 0; i < n; i++) {
shell = (nsIWebShell*)mChildren.ElementAt(i);
if (shell == aFocusedWebShell) {
if (++i < n) {
NS_RELEASE(shell);
shell = (nsIWebShell*)mChildren.ElementAt(i);
shell->SetFocus();
break;
}
else if (nsnull != mContainer) {
mContainer->FocusAvailable(this);
break;
}
}
}
NS_IF_RELEASE(shell);
return NS_OK;
}
//----------------------------------------------------------------------

View File

@ -726,6 +726,8 @@ nsDocument::Reset(nsIURL *aURL)
}
if (nsnull != mRootContent) {
// Ensure that document is nsnull to allow validity checks on content
mRootContent->SetDocument(nsnull, PR_TRUE);
ContentRemoved(nsnull, mRootContent, 0);
NS_IF_RELEASE(mRootContent);
}

View File

@ -749,7 +749,7 @@ nsGenericElement::HandleDOMEvent(nsIPresContext& aPresContext,
}
//Bubbling stage
if ((DOM_EVENT_CAPTURE != aFlags) && (mParent != nsnull)) {
if ((DOM_EVENT_CAPTURE != aFlags) && (mParent != nsnull) && (mDocument != nsnull)) {
ret = mParent->HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
DOM_EVENT_BUBBLE, aEventStatus);
}

View File

@ -64,6 +64,8 @@ public:
NS_IMETHOD GetLinkState(nsIContent *aLink, nsLinkEventState& aState) = 0;
NS_IMETHOD SetActiveLink(nsIContent *aLink) = 0;
NS_IMETHOD SetHoverLink(nsIContent *aLink) = 0;
NS_IMETHOD SetFocusedContent(nsIContent *aContent) = 0;
};
#endif // nsIEventStateManager_h__

View File

@ -44,7 +44,7 @@ EXPORTS = \
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
REQUIRES = xpcom raptor dom js
REQUIRES = xpcom raptor dom js netlib
include $(topsrcdir)/config/config.mk

View File

@ -42,7 +42,7 @@ CPP_OBJS= .\$(OBJDIR)\nsEventListenerManager.obj \
EXPORTS= nsEventListenerManager.h nsEventStateManager.h nsDOMEvent.h nsDOMEventsIIDs.h
LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor \
-I$(PUBLIC)\dom -I$(PUBLIC)\js -I..\..\html\base\src
-I$(PUBLIC)\dom -I$(PUBLIC)\js -I..\..\html\base\src -I$(PUBLIC)\netlib
LCFLAGS = \
$(LCFLAGS) \

View File

@ -31,6 +31,12 @@
#include "nsIDOMHTMLInputElement.h"
#include "nsIDOMHTMLSelectElement.h"
#include "nsIDOMHTMLTextAreaElement.h"
#include "nsIDOMHTMLAreaElement.h"
#include "nsIDOMHTMLButtonElement.h"
#include "nsIDOMHTMLObjectElement.h"
#include "nsINameSpaceManager.h" // for kNameSpaceID_HTML
#include "nsIWebShell.h"
#include "nsIFocusableContent.h"
static NS_DEFINE_IID(kIEventStateManagerIID, NS_IEVENTSTATEMANAGER_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
@ -38,6 +44,11 @@ static NS_DEFINE_IID(kIDOMHTMLAnchorElementIID, NS_IDOMHTMLANCHORELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLInputElementIID, NS_IDOMHTMLINPUTELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLSelectElementIID, NS_IDOMHTMLSELECTELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLTextAreaElementIID, NS_IDOMHTMLTEXTAREAELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLAreaElementIID, NS_IDOMHTMLAREAELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLObjectElementIID, NS_IDOMHTMLOBJECTELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLButtonElementIID, NS_IDOMHTMLBUTTONELEMENT_IID);
static NS_DEFINE_IID(kIWebShellIID, NS_IWEB_SHELL_IID);
static NS_DEFINE_IID(kIFocusableContentIID, NS_IFOCUSABLECONTENT_IID);
nsEventStateManager::nsEventStateManager() {
mLastMouseOverFrame = nsnull;
@ -51,6 +62,7 @@ nsEventStateManager::nsEventStateManager() {
mCurrentFocus = nsnull;
mDocument = nsnull;
mPresContext = nsnull;
mCurrentTabIndex = 0;
NS_INIT_REFCNT();
}
@ -89,10 +101,7 @@ nsEventStateManager::PreHandleEvent(nsIPresContext& aPresContext,
//GenerateMouseEnterExit(aPresContext, aEvent, aTargetFrame);
break;
case NS_GOTFOCUS:
NS_IF_RELEASE(mCurrentFocus);
if (nsnull != mCurrentTarget) {
mCurrentTarget->GetContent(&mCurrentFocus);
}
//XXX Do we need window related focus change stuff here?
break;
}
return NS_OK;
@ -117,8 +126,14 @@ nsEventStateManager::PostHandleEvent(nsIPresContext& aPresContext,
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
case NS_MOUSE_RIGHT_BUTTON_DOWN:
{
if (nsnull != aEvent->widget) {
aEvent->widget->SetFocus();
nsIContent* newFocus;
mCurrentTarget->GetContent(&newFocus);
if (newFocus) {
if (!ChangeFocus(newFocus, PR_TRUE)) {
if (nsnull != aEvent->widget) {
aEvent->widget->SetFocus();
}
}
}
}
//Break left out on purpose
@ -132,7 +147,8 @@ nsEventStateManager::PostHandleEvent(nsIPresContext& aPresContext,
if (nsEventStatus_eConsumeNoDefault != aStatus) {
switch(((nsKeyEvent*)aEvent)->keyCode) {
case NS_VK_TAB:
ShiftFocus();
//Shift focus forward or back depending on shift key
ShiftFocus(!((nsInputEvent*)aEvent)->isShift);
aStatus = nsEventStatus_eConsumeNoDefault;
break;
case NS_VK_PAGE_DOWN:
@ -417,8 +433,28 @@ nsEventStateManager::DispatchKeyPressEvent(nsIPresContext& aPresContext,
return ret;
}
PRBool
nsEventStateManager::ChangeFocus(nsIContent* aFocus, PRBool aSetFocus)
{
nsIFocusableContent *focusChange;
if (NS_OK == aFocus->QueryInterface(kIFocusableContentIID,(void **)&focusChange)) {
if (aSetFocus) {
focusChange->SetFocus(mPresContext);
}
else {
focusChange->RemoveFocus(mPresContext);
}
NS_RELEASE(focusChange);
return PR_TRUE;
}
//XXX Need to deal with Object tag
return PR_FALSE;
}
void
nsEventStateManager::ShiftFocus()
nsEventStateManager::ShiftFocus(PRBool forward)
{
if (nsnull == mPresContext) {
return;
@ -439,36 +475,34 @@ nsEventStateManager::ShiftFocus()
if (nsnull == mCurrentFocus) {
return;
}
mCurrentTabIndex = forward ? 1 : 0;
}
nsIContent* next = GetNextTabbableContent(mCurrentFocus, nsnull, mCurrentFocus);
nsIContent* next = GetNextTabbableContent(mCurrentFocus, nsnull, mCurrentFocus, forward);
if (nsnull == next) {
NS_IF_RELEASE(mCurrentFocus);
//XXX pass focus up to webshellcontainer FocusAvailable
//Pass focus up to nsIWebShellContainer FocusAvailable
nsISupports* container;
mPresContext->GetContainer(&container);
if (nsnull != container) {
nsIWebShell* webShell;
if (NS_OK == container->QueryInterface(kIWebShellIID, (void**)&webShell)) {
nsIWebShellContainer* webShellContainer;
webShell->GetContainer(webShellContainer);
if (nsnull != webShellContainer) {
webShellContainer->FocusAvailable(webShell);
NS_RELEASE(webShellContainer);
}
NS_RELEASE(webShell);
}
NS_RELEASE(container);
}
return;
}
nsIDOMHTMLAnchorElement *nextAnchor;
nsIDOMHTMLInputElement *nextInput;
nsIDOMHTMLSelectElement *nextSelect;
nsIDOMHTMLTextAreaElement *nextTextArea;
if (NS_OK == next->QueryInterface(kIDOMHTMLAnchorElementIID,(void **)&nextAnchor)) {
nextAnchor->Focus();
NS_RELEASE(nextAnchor);
}
else if (NS_OK == next->QueryInterface(kIDOMHTMLInputElementIID,(void **)&nextInput)) {
nextInput->Focus();
NS_RELEASE(nextInput);
}
else if (NS_OK == next->QueryInterface(kIDOMHTMLSelectElementIID,(void **)&nextSelect)) {
nextSelect->Focus();
NS_RELEASE(nextSelect);
}
else if (NS_OK == next->QueryInterface(kIDOMHTMLTextAreaElementIID,(void **)&nextTextArea)) {
nextTextArea->Focus();
NS_RELEASE(nextTextArea);
}
ChangeFocus(next, PR_TRUE);
NS_IF_RELEASE(mCurrentFocus);
mCurrentFocus = next;
@ -478,29 +512,31 @@ nsEventStateManager::ShiftFocus()
* At some point this will need to be linked into HTML 4.0 tabindex
*/
nsIContent*
nsEventStateManager::GetNextTabbableContent(nsIContent* aParent, nsIContent* aChild, nsIContent* aTop)
nsEventStateManager::GetNextTabbableContent(nsIContent* aParent, nsIContent* aChild, nsIContent* aTop, PRBool forward)
{
PRInt32 count, index;
aParent->ChildCount(count);
if (nsnull != aChild) {
aParent->IndexOf(aChild, index);
index += 1;
index += forward ? 1 : -1;
}
else {
index = 0;
index = forward ? 0 : count;
}
for (;index < count;index++) {
for (;index < count && index >= 0;index += forward ? 1 : -1) {
nsIContent* child;
aParent->ChildAt(index, child);
nsIContent* content = GetNextTabbableContent(child, nsnull, aTop);
nsIContent* content = GetNextTabbableContent(child, nsnull, aTop, forward);
if (content != nsnull) {
NS_IF_RELEASE(child);
return content;
}
if (nsnull != child) {
nsIAtom* tag;
PRInt32 tabIndex = -1;
PRBool disabled = PR_TRUE;
PRBool hidden = PR_FALSE;
@ -509,6 +545,7 @@ nsEventStateManager::GetNextTabbableContent(nsIContent* aParent, nsIContent* aCh
nsIDOMHTMLInputElement *nextInput;
if (NS_OK == child->QueryInterface(kIDOMHTMLInputElementIID,(void **)&nextInput)) {
nextInput->GetDisabled(&disabled);
nextInput->GetTabIndex(&tabIndex);
nsAutoString type;
nextInput->GetType(type);
@ -522,6 +559,7 @@ nsEventStateManager::GetNextTabbableContent(nsIContent* aParent, nsIContent* aCh
nsIDOMHTMLSelectElement *nextSelect;
if (NS_OK == child->QueryInterface(kIDOMHTMLSelectElementIID,(void **)&nextSelect)) {
nextSelect->GetDisabled(&disabled);
nextSelect->GetTabIndex(&tabIndex);
NS_RELEASE(nextSelect);
}
}
@ -529,20 +567,48 @@ nsEventStateManager::GetNextTabbableContent(nsIContent* aParent, nsIContent* aCh
nsIDOMHTMLTextAreaElement *nextTextArea;
if (NS_OK == child->QueryInterface(kIDOMHTMLTextAreaElementIID,(void **)&nextTextArea)) {
nextTextArea->GetDisabled(&disabled);
nextTextArea->GetTabIndex(&tabIndex);
NS_RELEASE(nextTextArea);
}
}
//XXX Not all of these are focusable yet.
else if(nsHTMLAtoms::a==tag
//nsHTMLAtoms::area==tag ||
//nsHTMLAtoms::button==tag ||
//nsHTMLAtoms::object==tag
) {
else if(nsHTMLAtoms::a==tag) {
nsIDOMHTMLAnchorElement *nextAnchor;
if (NS_OK == child->QueryInterface(kIDOMHTMLAnchorElementIID,(void **)&nextAnchor)) {
nextAnchor->GetTabIndex(&tabIndex);
NS_RELEASE(nextAnchor);
}
disabled = PR_FALSE;
}
else if(nsHTMLAtoms::button==tag) {
nsIDOMHTMLButtonElement *nextButton;
if (NS_OK == child->QueryInterface(kIDOMHTMLButtonElementIID,(void **)&nextButton)) {
nextButton->GetTabIndex(&tabIndex);
nextButton->GetDisabled(&disabled);
NS_RELEASE(nextButton);
}
}
else if(nsHTMLAtoms::area==tag) {
nsIDOMHTMLAreaElement *nextArea;
if (NS_OK == child->QueryInterface(kIDOMHTMLAreaElementIID,(void **)&nextArea)) {
nextArea->GetTabIndex(&tabIndex);
NS_RELEASE(nextArea);
}
disabled = PR_FALSE;
}
else if(nsHTMLAtoms::object==tag) {
nsIDOMHTMLObjectElement *nextObject;
if (NS_OK == child->QueryInterface(kIDOMHTMLObjectElementIID,(void **)&nextObject)) {
nextObject->GetTabIndex(&tabIndex);
NS_RELEASE(nextObject);
}
disabled = PR_FALSE;
}
if (!disabled && !hidden) {
//TabIndex not set (-1) treated at same level as set to 0
tabIndex = tabIndex < 0 ? 0 : tabIndex;
if (!disabled && !hidden && mCurrentTabIndex == tabIndex) {
return child;
}
NS_RELEASE(child);
@ -553,15 +619,56 @@ nsEventStateManager::GetNextTabbableContent(nsIContent* aParent, nsIContent* aCh
nsIContent* nextParent;
aParent->GetParent(nextParent);
if (nsnull != nextParent) {
nsIContent* content = GetNextTabbableContent(nextParent, aParent, nextParent);
nsIContent* content = GetNextTabbableContent(nextParent, aParent, nextParent, forward);
NS_RELEASE(nextParent);
return content;
}
//Reached end of document
else {
//If already at lowest priority tab (0), end
if (0 == mCurrentTabIndex) {
return nsnull;
}
//else continue looking for next highest priority tab
mCurrentTabIndex = GetNextTabIndex(aParent, forward);
nsIContent* content = GetNextTabbableContent(aParent, nsnull, aParent, forward);
return content;
}
}
return nsnull;
}
PRInt32
nsEventStateManager::GetNextTabIndex(nsIContent* aParent, PRBool forward)
{
PRInt32 count, tabIndex = 0;
aParent->ChildCount(count);
for (PRInt32 index = 0; index < count; index++) {
nsIContent* child;
PRInt32 childTabIndex;
aParent->ChildAt(index, child);
childTabIndex = GetNextTabIndex(child, forward);
if (childTabIndex > mCurrentTabIndex && childTabIndex != tabIndex) {
tabIndex = (tabIndex == 0 || childTabIndex < tabIndex) ? childTabIndex : tabIndex;
}
nsAutoString tabIndexStr;
child->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::tabindex, tabIndexStr);
PRInt32 ec, val = tabIndexStr.ToInteger(&ec);
if (NS_OK == ec && val > mCurrentTabIndex && val != tabIndex) {
tabIndex = (tabIndex == 0 || val < tabIndex) ? val : tabIndex;
}
NS_RELEASE(child);
}
return tabIndex;
}
NS_IMETHODIMP
nsEventStateManager::GetEventTarget(nsIFrame **aFrame)
{
@ -636,6 +743,51 @@ nsEventStateManager::SetHoverLink(nsIContent *aLink)
return NS_OK;
}
NS_IMETHODIMP
nsEventStateManager::SetFocusedContent(nsIContent *aContent)
{
if (mCurrentFocus == aContent) {
return NS_OK;
}
if (mCurrentFocus) {
ChangeFocus(mCurrentFocus, PR_FALSE);
//fire blur
nsEventStatus status = nsEventStatus_eIgnore;
nsEvent event;
event.eventStructType = NS_EVENT;
event.message = NS_BLUR_CONTENT;
if (nsnull != mPresContext) {
mCurrentFocus->HandleDOMEvent(*mPresContext, &event, nsnull, DOM_EVENT_INIT, status);
}
NS_RELEASE(mCurrentFocus);
}
//fire focus
nsEventStatus status = nsEventStatus_eIgnore;
nsEvent event;
event.eventStructType = NS_EVENT;
event.message = NS_FOCUS_CONTENT;
if (nsnull != mPresContext) {
aContent->HandleDOMEvent(*mPresContext, &event, nsnull, DOM_EVENT_INIT, status);
}
nsAutoString tabIndex;
aContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::tabindex, tabIndex);
PRInt32 ec, val = tabIndex.ToInteger(&ec);
if (NS_OK == ec) {
mCurrentTabIndex = val;
}
mCurrentFocus = aContent;
NS_IF_ADDREF(mCurrentFocus);
return NS_OK;
}
nsresult NS_NewEventStateManager(nsIEventStateManager** aInstancePtrResult)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "nsnull ptr");

View File

@ -54,13 +54,17 @@ public:
NS_IMETHOD SetActiveLink(nsIContent *aLink);
NS_IMETHOD SetHoverLink(nsIContent *aLink);
NS_IMETHOD SetFocusedContent(nsIContent *aContent);
protected:
void UpdateCursor(nsIPresContext& aPresContext, nsPoint& aPoint, nsIFrame* aTargetFrame, nsEventStatus& aStatus);
void GenerateMouseEnterExit(nsIPresContext& aPresContext, nsGUIEvent* aEvent);
NS_IMETHOD DispatchKeyPressEvent(nsIPresContext& aPresContext, nsKeyEvent *aEvent, nsEventStatus& aStatus);
NS_IMETHOD CheckForAndDispatchClick(nsIPresContext& aPresContext, nsMouseEvent *aEvent, nsEventStatus& aStatus);
void ShiftFocus();
nsIContent* GetNextTabbableContent(nsIContent* aParent, nsIContent* aChild, nsIContent* aTop);
PRBool ChangeFocus(nsIContent* aFocus, PRBool aSetFocus);
void ShiftFocus(PRBool foward);
nsIContent* GetNextTabbableContent(nsIContent* aParent, nsIContent* aChild, nsIContent* aTop, PRBool foward);
PRInt32 GetNextTabIndex(nsIContent* aParent, PRBool foward);
//Any frames here must be checked for validity in ClearFrameRefs
nsIFrame* mCurrentTarget;
@ -72,6 +76,7 @@ protected:
nsIContent* mActiveLink;
nsIContent* mHoverLink;
nsIContent* mCurrentFocus;
PRInt32 mCurrentTabIndex;
//Not refcnted
nsIPresContext* mPresContext;

View File

@ -444,7 +444,7 @@ nsHTMLButtonControlFrame::ShiftContents(nsIPresContext& aPresContext, PRBool aDo
mStyleContext->RecalcAutomaticData(&aPresContext);
nsRect rect(0, 0, mRect.width, mRect.height);
ReflowTemp(aPresContext, this, rect);
//ReflowTemp(aPresContext, this, rect);
}
void

View File

@ -25,6 +25,7 @@ include $(DEPTH)/config/autoconf.mk
EXPORTS = \
nsIFormControl.h \
nsIForm.h \
nsIFocusableContent.h \
$(NULL)
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))

View File

@ -17,7 +17,7 @@
DEPTH=..\..\..\..
EXPORTS=nsIFormControl.h nsIForm.h
EXPORTS=nsIFormControl.h nsIForm.h nsIFocusableContent.h
MODULE=raptor

View File

@ -28,6 +28,7 @@
#include "nsIPresContext.h"
#include "nsINameSpaceManager.h"
#include "nsIURL.h"
#include "nsIFocusableContent.h"
#include "nsIEventStateManager.h"
#include "nsDOMEvent.h"
@ -38,11 +39,13 @@
// custom frame
static NS_DEFINE_IID(kIDOMHTMLAnchorElementIID, NS_IDOMHTMLANCHORELEMENT_IID);
static NS_DEFINE_IID(kIFocusableContentIID, NS_IFOCUSABLECONTENT_IID);
class nsHTMLAnchorElement : public nsIDOMHTMLAnchorElement,
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent
public nsIHTMLContent,
public nsIFocusableContent
{
public:
nsHTMLAnchorElement(nsIAtom* aTag);
@ -100,6 +103,10 @@ public:
// nsIHTMLContent
NS_IMPL_IHTMLCONTENT_USING_GENERIC(mInner)
// nsIFocusableContent
NS_IMETHOD SetFocus(nsIPresContext* aPresContext);
NS_IMETHOD RemoveFocus(nsIPresContext* aPresContext);
protected:
nsGenericHTMLContainerElement mInner;
};
@ -142,6 +149,11 @@ nsHTMLAnchorElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
mRefCnt++;
return NS_OK;
}
else if (aIID.Equals(kIFocusableContentIID)) {
*aInstancePtr = (void*)(nsIFocusableContent*) this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
@ -183,6 +195,26 @@ nsHTMLAnchorElement::Focus()
return NS_OK;
}
NS_IMETHODIMP
nsHTMLAnchorElement::SetFocus(nsIPresContext* aPresContext)
{
nsIEventStateManager* esm;
if (NS_OK == aPresContext->GetEventStateManager(&esm)) {
esm->SetFocusedContent(this);
NS_RELEASE(esm);
}
// XXX write me
return NS_OK;
}
NS_IMETHODIMP
nsHTMLAnchorElement::RemoveFocus(nsIPresContext* aPresContext)
{
// XXX write me
return NS_OK;
}
NS_IMETHODIMP
nsHTMLAnchorElement::StringToAttribute(nsIAtom* aAttribute,
const nsString& aValue,
@ -261,7 +293,7 @@ nsHTMLAnchorElement::HandleDOMEvent(nsIPresContext& aPresContext,
}
break;
case NS_MOUSE_LEFT_BUTTON_UP:
case NS_MOUSE_LEFT_CLICK:
{
nsIEventStateManager *stateManager;
nsLinkEventState linkState;

View File

@ -26,13 +26,17 @@
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "nsIFocusableContent.h"
#include "nsIEventStateManager.h"
static NS_DEFINE_IID(kIDOMHTMLAreaElementIID, NS_IDOMHTMLAREAELEMENT_IID);
static NS_DEFINE_IID(kIFocusableContentIID, NS_IFOCUSABLECONTENT_IID);
class nsHTMLAreaElement : public nsIDOMHTMLAreaElement,
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent
public nsIHTMLContent,
public nsIFocusableContent
{
public:
nsHTMLAreaElement(nsIAtom* aTag);
@ -80,6 +84,10 @@ public:
// nsIHTMLContent
NS_IMPL_IHTMLCONTENT_USING_GENERIC(mInner)
// nsIFocusableContent
NS_IMETHOD SetFocus(nsIPresContext* aPresContext);
NS_IMETHOD RemoveFocus(nsIPresContext* aPresContext);
protected:
nsGenericHTMLLeafElement mInner;
};
@ -122,6 +130,11 @@ nsHTMLAreaElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
NS_ADDREF_THIS();
return NS_OK;
}
else if (aIID.Equals(kIFocusableContentIID)) {
*aInstancePtr = (void*)(nsIFocusableContent*) this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
@ -191,6 +204,7 @@ nsHTMLAreaElement::HandleDOMEvent(nsIPresContext& aPresContext,
NS_IMETHODIMP
nsHTMLAreaElement::GetStyleHintForAttributeChange(const nsIAtom* aAttribute,
PRInt32 *aHint) const
{
if ((aAttribute == nsHTMLAtoms::alt) ||
(aAttribute == nsHTMLAtoms::coords) ||
@ -208,5 +222,27 @@ nsHTMLAreaElement::GetStyleHintForAttributeChange(const nsIAtom* aAttribute,
else {
nsGenericHTMLElement::GetStyleHintForCommonAttributes(this, aAttribute, aHint);
}
return NS_OK;
}
NS_IMETHODIMP
nsHTMLAreaElement::SetFocus(nsIPresContext* aPresContext)
{
nsIEventStateManager* esm;
if (NS_OK == aPresContext->GetEventStateManager(&esm)) {
esm->SetFocusedContent(this);
NS_RELEASE(esm);
}
// XXX write me
return NS_OK;
}
NS_IMETHODIMP
nsHTMLAreaElement::RemoveFocus(nsIPresContext* aPresContext)
{
// XXX write me
return NS_OK;
}

View File

@ -31,17 +31,20 @@
#include "nsIFormControl.h"
#include "nsIForm.h"
#include "nsIURL.h"
#include "nsIFocusableContent.h"
#include "nsIEventStateManager.h"
#include "nsDOMEvent.h"
static NS_DEFINE_IID(kIDOMHTMLButtonElementIID, NS_IDOMHTMLBUTTONELEMENT_IID);
static NS_DEFINE_IID(kIFocusableContentIID, NS_IFOCUSABLECONTENT_IID);
class nsHTMLButtonElement : public nsIDOMHTMLButtonElement,
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent,
public nsIFormControl
public nsIFormControl,
public nsIFocusableContent
{
public:
nsHTMLButtonElement(nsIAtom* aTag);
@ -95,6 +98,10 @@ public:
NS_IMETHOD SetWidget(nsIWidget* aWidget) { return NS_OK; };
NS_IMETHOD Init() { return NS_OK; }
// nsIFocusableContent
NS_IMETHOD SetFocus(nsIPresContext* aPresContext);
NS_IMETHOD RemoveFocus(nsIPresContext* aPresContext);
protected:
nsGenericHTMLContainerElement mInner;
nsIForm* mForm;
@ -160,6 +167,11 @@ nsHTMLButtonElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
NS_ADDREF_THIS();
return NS_OK;
}
else if (aIID.Equals(kIFocusableContentIID)) {
*aInstancePtr = (void*)(nsIFocusableContent*) this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
@ -259,6 +271,26 @@ nsHTMLButtonElement::Focus()
return NS_OK;
}
NS_IMETHODIMP
nsHTMLButtonElement::SetFocus(nsIPresContext* aPresContext)
{
nsIEventStateManager* esm;
if (NS_OK == aPresContext->GetEventStateManager(&esm)) {
esm->SetFocusedContent(this);
NS_RELEASE(esm);
}
// XXX write me
return NS_OK;
}
NS_IMETHODIMP
nsHTMLButtonElement::RemoveFocus(nsIPresContext* aPresContext)
{
// XXX write me
return NS_OK;
}
static nsGenericHTMLElement::EnumTable kButtonTypeTable[] = {
{ "button", NS_FORM_BUTTON_BUTTON },
{ "reset", NS_FORM_BUTTON_RESET },

View File

@ -41,6 +41,8 @@
#include "nsIPresShell.h"
#include "nsIFormControlFrame.h"
#include "nsIFrame.h"
#include "nsIFocusableContent.h"
#include "nsIEventStateManager.h"
// XXX align=left, hspace, vspace, border? other nav4 attrs
@ -52,12 +54,14 @@ static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID);
static NS_DEFINE_IID(kIRadioIID, NS_IRADIOBUTTON_IID);
static NS_DEFINE_IID(kICheckButtonIID, NS_ICHECKBUTTON_IID);
static NS_DEFINE_IID(kIFormControlFrameIID, NS_IFORMCONTROLFRAME_IID);
static NS_DEFINE_IID(kIFocusableContentIID, NS_IFOCUSABLECONTENT_IID);
class nsHTMLInputElement : public nsIDOMHTMLInputElement,
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent,
public nsIFormControl
public nsIFormControl,
public nsIFocusableContent
{
public:
nsHTMLInputElement(nsIAtom* aTag);
@ -133,6 +137,10 @@ public:
NS_IMETHOD SetWidget(nsIWidget* aWidget);
NS_IMETHOD Init() { return NS_OK; }
// nsIFocusableContent
NS_IMETHOD SetFocus(nsIPresContext* aPresContext);
NS_IMETHOD RemoveFocus(nsIPresContext* aPresContext);
protected:
nsGenericHTMLLeafElement mInner;
nsIWidget* mWidget; // XXX this needs to go away when FindFrameWithContent is efficient
@ -206,6 +214,11 @@ nsHTMLInputElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
NS_ADDREF_THIS();
return NS_OK;
}
else if (aIID.Equals(kIFocusableContentIID)) {
*aInstancePtr = (void*)(nsIFocusableContent*) this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
@ -404,6 +417,29 @@ nsHTMLInputElement::Focus()
return NS_OK;
}
NS_IMETHODIMP
nsHTMLInputElement::SetFocus(nsIPresContext* aPresContext)
{
nsIEventStateManager* esm;
if (NS_OK == aPresContext->GetEventStateManager(&esm)) {
esm->SetFocusedContent(this);
NS_RELEASE(esm);
}
// XXX Should focus only this presContext
Focus();
return NS_OK;
}
NS_IMETHODIMP
nsHTMLInputElement::RemoveFocus(nsIPresContext* aPresContext)
{
// XXX Should focus only this presContext
Blur();
return NS_OK;
}
NS_IMETHODIMP
nsHTMLInputElement::Select()
{

View File

@ -33,6 +33,8 @@
#include "nsIWidget.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIDOMHTMLOptionElement.h"
#include "nsIFocusableContent.h"
#include "nsIEventStateManager.h"
// Notify/query select frame for selectedIndex
#include "nsIDocument.h"
@ -46,6 +48,7 @@ static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIFormIID, NS_IFORM_IID);
static NS_DEFINE_IID(kIFormControlFrameIID, NS_IFORMCONTROLFRAME_IID);
static NS_DEFINE_IID(kIFocusableContentIID, NS_IFOCUSABLECONTENT_IID);
class nsHTMLSelectElement;
@ -77,7 +80,8 @@ class nsHTMLSelectElement : public nsIDOMHTMLSelectElement,
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent,
public nsIFormControl
public nsIFormControl,
public nsIFocusableContent
{
public:
nsHTMLSelectElement(nsIAtom* aTag);
@ -137,6 +141,9 @@ public:
NS_IMETHOD SetWidget(nsIWidget* aWidget);
NS_IMETHOD Init();
NS_IMETHOD SetFocus(nsIPresContext* aPresContext);
NS_IMETHOD RemoveFocus(nsIPresContext* aPresContext);
protected:
nsGenericHTMLContainerElement mInner;
nsIWidget* mWidget; // XXX this needs to go away when FindFrameWithContent is efficient
@ -205,6 +212,11 @@ nsHTMLSelectElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
mRefCnt++;
return NS_OK;
}
else if (aIID.Equals(kIFocusableContentIID)) {
*aInstancePtr = (void*)(nsIFocusableContent*) this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
@ -398,6 +410,28 @@ nsHTMLSelectElement::Focus()
return NS_OK;
}
NS_IMETHODIMP
nsHTMLSelectElement::SetFocus(nsIPresContext* aPresContext)
{
nsIEventStateManager* esm;
if (NS_OK == aPresContext->GetEventStateManager(&esm)) {
esm->SetFocusedContent(this);
NS_RELEASE(esm);
}
// XXX Should focus only this presContext
Focus();
return NS_OK;
}
NS_IMETHODIMP
nsHTMLSelectElement::RemoveFocus(nsIPresContext* aPresContext)
{
// XXX Should focus only this presContext
Blur();
return NS_OK;
}
NS_IMETHODIMP
nsHTMLSelectElement::StringToAttribute(nsIAtom* aAttribute,
const nsString& aValue,

View File

@ -33,18 +33,22 @@
#include "nsITextAreaWidget.h"
#include "nsIHTMLAttributes.h"
#include "nsIFormControlFrame.h"
#include "nsIFocusableContent.h"
#include "nsIEventStateManager.h"
static NS_DEFINE_IID(kIDOMHTMLTextAreaElementIID, NS_IDOMHTMLTEXTAREAELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIFormIID, NS_IFORM_IID);
static NS_DEFINE_IID(kITextAreaWidgetIID, NS_ITEXTAREAWIDGET_IID);
static NS_DEFINE_IID(kIFocusableContentIID, NS_IFOCUSABLECONTENT_IID);
class nsHTMLTextAreaElement : public nsIDOMHTMLTextAreaElement,
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent,
public nsIFormControl
public nsIFormControl,
public nsIFocusableContent
{
public:
nsHTMLTextAreaElement(nsIAtom* aTag);
@ -105,6 +109,10 @@ public:
NS_IMETHOD SetWidget(nsIWidget* aWidget);
NS_IMETHOD Init() { return NS_OK; }
// nsIFocusableContent
NS_IMETHOD SetFocus(nsIPresContext* aPresContext);
NS_IMETHOD RemoveFocus(nsIPresContext* aPresContext);
protected:
nsGenericHTMLContainerElement mInner;
nsIWidget* mWidget; // XXX this needs to go away when FindFrameWithContent is efficient
@ -163,6 +171,11 @@ nsHTMLTextAreaElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
mRefCnt++;
return NS_OK;
}
else if (aIID.Equals(kIFocusableContentIID)) {
*aInstancePtr = (void*)(nsIFocusableContent*) this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
@ -233,6 +246,29 @@ nsHTMLTextAreaElement::Focus() // XXX not tested
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTextAreaElement::SetFocus(nsIPresContext* aPresContext)
{
nsIEventStateManager* esm;
if (NS_OK == aPresContext->GetEventStateManager(&esm)) {
esm->SetFocusedContent(this);
NS_RELEASE(esm);
}
// XXX Should focus only this presContext
Focus();
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTextAreaElement::RemoveFocus(nsIPresContext* aPresContext)
{
// XXX Should focus only this presContext
Blur();
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTextAreaElement::Select() // XXX not tested
{

View File

@ -444,7 +444,7 @@ nsHTMLButtonControlFrame::ShiftContents(nsIPresContext& aPresContext, PRBool aDo
mStyleContext->RecalcAutomaticData(&aPresContext);
nsRect rect(0, 0, mRect.width, mRect.height);
ReflowTemp(aPresContext, this, rect);
//ReflowTemp(aPresContext, this, rect);
}
void

View File

@ -1638,7 +1638,32 @@ nsWebShell::FindWebShellWithName(const PRUnichar* aName, nsIWebShell*& aResult)
NS_IMETHODIMP
nsWebShell::FocusAvailable(nsIWebShell* aFocusedWebShell)
{
//XXX Move focus to next child, or if on last child, call focus available on next container
//If the WebShell with focus is us, pass this up to container
if (this == aFocusedWebShell && nsnull != mContainer) {
mContainer->FocusAvailable(this);
}
nsIWebShell* shell = nsnull;
//Other wise, check children and move focus to next one
PRInt32 i, n = mChildren.Count();
for (i = 0; i < n; i++) {
shell = (nsIWebShell*)mChildren.ElementAt(i);
if (shell == aFocusedWebShell) {
if (++i < n) {
NS_RELEASE(shell);
shell = (nsIWebShell*)mChildren.ElementAt(i);
shell->SetFocus();
break;
}
else if (nsnull != mContainer) {
mContainer->FocusAvailable(this);
break;
}
}
}
NS_IF_RELEASE(shell);
return NS_OK;
}
//----------------------------------------------------------------------

View File

@ -242,6 +242,12 @@ struct nsMenuEvent : public nsGUIEvent {
#define NS_FORM_SUBMIT (NS_FORM_EVENT_START)
#define NS_FORM_RESET (NS_FORM_EVENT_START + 1)
#define NS_FORM_CHANGE (NS_FORM_EVENT_START + 2)
//Need separate focus/blur notifications for non-native widgets
#define NS_FOCUS_EVENT_START 1300
#define NS_FOCUS_CONTENT (NS_FOCUS_EVENT_START)
#define NS_BLUR_CONTENT (NS_FOCUS_EVENT_START + 1)
//@}