XForms Bug 277543 - add default handling for xforms-focus. Patch by smaug@welho.com, r=aaronr/sr=bryner

This commit is contained in:
doronr%us.ibm.com 2005-01-27 19:30:03 +00:00
parent e9647ed503
commit 34d6553453
11 changed files with 140 additions and 0 deletions

View File

@ -60,6 +60,11 @@ interface nsIXFormsControl : nsISupports
*/
void refresh();
/**
* Tries to move focus to form control and returns true if succeeded.
*/
boolean tryFocus();
/**
* The instance node that the control is bound to.
*/

View File

@ -76,6 +76,14 @@ nsXFormsControlStub::Bind()
return NS_OK;
}
NS_IMETHODIMP
nsXFormsControlStub::TryFocus(PRBool* aOK)
{
*aOK = PR_FALSE;
return NS_OK;
}
nsresult
nsXFormsControlStub::ProcessNodeBinding(const nsString &aBindingAttr,
PRUint16 aResultType,
@ -128,6 +136,19 @@ nsXFormsControlStub::GetReadOnlyState()
return res;
}
PRBool
nsXFormsControlStub::GetRelevantState()
{
PRBool res = PR_TRUE;
if (mBoundNode && mMDG) {
const nsXFormsNodeState* ns = mMDG->GetNodeState(mBoundNode);
if (ns) {
res = ns->IsRelevant();
}
}
return res;
}
void
nsXFormsControlStub::ToggleProperty(const nsAString &aOn,
const nsAString &aOff)
@ -174,6 +195,9 @@ nsXFormsControlStub::HandleDefault(nsIDOMEvent *aEvent,
} else if (type.EqualsASCII(sXFormsEventsEntries[eEvent_Readwrite].name)) {
ToggleProperty(NS_LITERAL_STRING("read-write"),
NS_LITERAL_STRING("read-only"));
} else if (type.EqualsASCII(sXFormsEventsEntries[eEvent_Focus].name)) {
PRBool tmp;
TryFocus(&tmp);
} else {
*aHandled = PR_FALSE;
}

View File

@ -88,6 +88,7 @@ public:
NS_IMETHOD GetDependencies(nsIArray **aDependencies);
NS_IMETHOD GetElement(nsIDOMElement **aElement);
NS_IMETHOD Bind();
NS_IMETHOD TryFocus(PRBool* aOK);
// nsIXTFXMLVisual overrides
/** This sets the notification mask and initializes mElement */
@ -138,6 +139,9 @@ protected:
/** Returns the read only state of the control (ie. mBoundNode) */
PRBool GetReadOnlyState();
/** Returns the relevant state of the control */
PRBool GetRelevantState();
/**
* Processes the node binding of a control, get the current MDG (mMDG) and

View File

@ -42,6 +42,7 @@
#include "nsIDOM3Node.h"
#include "nsIDOMElement.h"
#include "nsIDOMDocument.h"
#include "nsIDOMNodeList.h"
#include "nsIDOMEventTarget.h"
#include "nsIDOMXPathResult.h"
#include "nsIDOMHTMLDivElement.h"
@ -78,6 +79,9 @@ class nsXFormsGroupElement : public nsXFormsControlStub,
public nsIXFormsContextControl
{
protected:
/** Tries to focus a child form control.*/
PRBool TryFocusChildControl(nsIDOMNode* aParent);
/** The UI HTML element used to represent the tag */
nsCOMPtr<nsIDOMHTMLDivElement> mHTMLElement;
@ -103,6 +107,7 @@ public:
// nsIXFormsControl
NS_IMETHOD Refresh();
NS_IMETHOD TryFocus(PRBool* aOK);
// nsIXFormsContextControl
NS_DECL_NSIXFORMSCONTEXTCONTROL
@ -214,6 +219,48 @@ nsXFormsGroupElement::Refresh()
return NS_OK;
}
PRBool
nsXFormsGroupElement::TryFocusChildControl(nsIDOMNode* aParent)
{
if (!aParent)
return PR_FALSE;
nsCOMPtr<nsIDOMNodeList> children;
nsresult rv = aParent->GetChildNodes(getter_AddRefs(children));
if (NS_FAILED(rv))
return PR_FALSE;
PRUint32 childCount = 0;
children->GetLength(&childCount);
nsCOMPtr<nsIDOMNode> child;
for (PRUint32 i = 0; i < childCount; ++i) {
children->Item(i, getter_AddRefs(child));
nsCOMPtr<nsIXFormsControl> control(do_QueryInterface(child));
PRBool focus = PR_FALSE;
if (control) {
control->TryFocus(&focus);
if (focus)
return PR_TRUE;
}
focus = TryFocusChildControl(child);
if (focus)
return PR_TRUE;
}
return PR_FALSE;
}
NS_IMETHODIMP
nsXFormsGroupElement::TryFocus(PRBool* aOK)
{
*aOK = PR_FALSE;
if (GetRelevantState()) {
*aOK = TryFocusChildControl(mElement);
}
return NS_OK;
}
// nsIXFormsContextControl
NS_IMETHODIMP
nsXFormsGroupElement::SetContextNode(nsIDOMNode *aContextNode)

View File

@ -80,6 +80,7 @@ public:
// nsIXFormsControl
NS_IMETHOD Bind();
NS_IMETHOD Refresh();
NS_IMETHOD TryFocus(PRBool* aOK);
// nsIDOMEventListener
NS_IMETHOD HandleEvent(nsIDOMEvent *aEvent);
@ -343,6 +344,13 @@ nsXFormsInputElement::Refresh()
return NS_OK;
}
NS_IMETHODIMP
nsXFormsInputElement::TryFocus(PRBool* aOK)
{
*aOK = GetRelevantState() && nsXFormsUtils::FocusControl(mControl);
return NS_OK;
}
NS_HIDDEN_(nsresult)
NS_NewXFormsInputElement(nsIXTFElement **aResult)
{

View File

@ -160,6 +160,7 @@ public:
// nsIXFormsControl
NS_IMETHOD Refresh();
NS_IMETHOD TryFocus(PRBool* aOK);
nsXFormsRepeatElement() : mAddingChildren(PR_FALSE) {};
};
@ -427,6 +428,17 @@ nsXFormsRepeatElement::Refresh()
return NS_OK;
}
/**
* @todo "Setting focus to a repeating structure sets the focus to
* the repeat item represented by the repeat index."
*/
NS_IMETHODIMP
nsXFormsRepeatElement::TryFocus(PRBool* aOK)
{
*aOK = PR_FALSE;
return NS_OK;
}
/**
* @todo This function will be part of the general schema support, so it will
* only live here until this is implemented there. (XXX)

View File

@ -79,6 +79,7 @@ public:
// nsIXFormsControl
NS_IMETHOD Refresh();
NS_IMETHOD TryFocus(PRBool* aOK);
// nsIDOMEventListener
NS_DECL_NSIDOMEVENTLISTENER
@ -343,6 +344,13 @@ nsXFormsSelectElement::Refresh()
return NS_OK;
}
NS_IMETHODIMP
nsXFormsSelectElement::TryFocus(PRBool* aOK)
{
*aOK = GetRelevantState() && nsXFormsUtils::FocusControl(mSelect);
return NS_OK;
}
// nsIDOMEventListener
NS_IMETHODIMP

View File

@ -63,6 +63,7 @@ public:
// nsIXFormsControl
NS_IMETHOD Refresh();
NS_IMETHOD TryFocus(PRBool* aOK);
protected:
nsCOMPtr<nsIDOMHTMLButtonElement> mButton;
@ -136,6 +137,13 @@ nsXFormsTriggerElement::Refresh()
return NS_OK;
}
NS_IMETHODIMP
nsXFormsTriggerElement::TryFocus(PRBool* aOK)
{
*aOK = GetRelevantState() && nsXFormsUtils::FocusControl(mButton);
return NS_OK;
}
//-----------------------------------------------------------------------------
class nsXFormsSubmitElement : public nsXFormsTriggerElement

View File

@ -89,6 +89,7 @@ public:
// nsIXFormsControl
NS_IMETHOD Refresh();
NS_IMETHOD TryFocus(PRBool* aOK);
// nsIDOMEventListener
NS_IMETHOD HandleEvent(nsIDOMEvent *aEvent);
@ -281,6 +282,13 @@ nsXFormsUploadElement::Refresh()
return NS_OK;
}
NS_IMETHODIMP
nsXFormsUploadElement::TryFocus(PRBool* aOK)
{
*aOK = GetRelevantState() && nsXFormsUtils::FocusControl(mInput);
return NS_OK;
}
NS_HIDDEN_(nsresult)
NS_NewXFormsUploadElement(nsIXTFElement **aResult)
{

View File

@ -41,6 +41,7 @@
#include "nsString.h"
#include "nsXFormsAtoms.h"
#include "nsIDOMElement.h"
#include "nsIDOMNSHTMLElement.h"
#include "nsIDocument.h"
#include "nsINameSpaceManager.h"
#include "nsINodeInfo.h"
@ -939,3 +940,13 @@ nsXFormsUtils::IsLabelElement(nsIDOMNode *aElement)
return PR_FALSE;
}
/* static */ PRBool
nsXFormsUtils::FocusControl(nsIDOMElement *aElement)
{
PRBool ret = PR_FALSE;
nsCOMPtr<nsIDOMNSHTMLElement> element(do_QueryInterface(aElement));
if (element && NS_SUCCEEDED(element->Focus()))
ret = PR_TRUE;
return ret;
}

View File

@ -324,6 +324,11 @@ public:
* Returns true if the given element is an XForms label.
*/
static NS_HIDDEN_(PRBool) IsLabelElement(nsIDOMNode *aElement);
/**
* Tries to focus a form control and returns true if succeeds.
*/
static NS_HIDDEN_(PRBool) FocusControl(nsIDOMElement *aElement);
};