зеркало из https://github.com/mozilla/gecko-dev.git
Adding support for advancing and rewinding the focus using the command dispatcher. r=saari, sr=jst
This commit is contained in:
Родитель
44736bce0b
Коммит
26a2d9444e
|
@ -1859,7 +1859,9 @@ nsXULElement::AddScriptEventListener(nsIAtom* aName, const nsAReadableString& aV
|
|||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
if (NodeInfo()->Equals(nsXULAtoms::window)) {
|
||||
nsCOMPtr<nsIContent> root(getter_AddRefs(mDocument->GetRootContent()));
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(NS_STATIC_CAST(nsIStyledContent*, this)));
|
||||
if ((!root || root == content) && !NodeInfo()->Equals(nsXULAtoms::overlay)) {
|
||||
nsCOMPtr<nsIDOMEventReceiver> receiver = do_QueryInterface(global);
|
||||
if (! receiver)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
|
|
@ -168,6 +168,33 @@ nsXULCommandDispatcher::SetFocusedWindow(nsIDOMWindowInternal* aWindow)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULCommandDispatcher::AdvanceFocus()
|
||||
{
|
||||
EnsureFocusController();
|
||||
if (mFocusController)
|
||||
return mFocusController->MoveFocus(PR_TRUE, nsnull);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULCommandDispatcher::RewindFocus()
|
||||
{
|
||||
EnsureFocusController();
|
||||
if (mFocusController)
|
||||
return mFocusController->MoveFocus(PR_FALSE, nsnull);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULCommandDispatcher::AdvanceFocusIntoSubtree(nsIDOMElement* aElt)
|
||||
{
|
||||
EnsureFocusController();
|
||||
if (mFocusController)
|
||||
return mFocusController->MoveFocus(PR_TRUE, aElt);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULCommandDispatcher::AddCommandUpdater(nsIDOMElement* aElement,
|
||||
const nsAReadableString& aEvents,
|
||||
|
|
|
@ -55,6 +55,8 @@ public:
|
|||
|
||||
NS_IMETHOD GetControllerForCommand(const nsAReadableString& aCommand, nsIController** aResult)=0;
|
||||
NS_IMETHOD GetControllers(nsIControllers** aResult)=0;
|
||||
|
||||
NS_IMETHOD MoveFocus(PRBool aForward, nsIDOMElement* aElt)=0;
|
||||
};
|
||||
|
||||
#endif // nsIFocusController_h__
|
||||
|
|
|
@ -13,4 +13,8 @@ interface XULCommandDispatcher {
|
|||
|
||||
xpidl nsIController getControllerForCommand(in DOMString command);
|
||||
xpidl nsIControllers getControllers();
|
||||
|
||||
void advanceFocus();
|
||||
void rewindFocus();
|
||||
void advanceFocusIntoSubtree(in Element elt);
|
||||
};
|
||||
|
|
|
@ -42,4 +42,8 @@ interface nsIDOMXULCommandDispatcher : nsISupports
|
|||
|
||||
nsIController getControllerForCommand(in DOMString command);
|
||||
nsIControllers getControllers();
|
||||
|
||||
void advanceFocus();
|
||||
void rewindFocus();
|
||||
void advanceFocusIntoSubtree(in nsIDOMElement elt);
|
||||
};
|
||||
|
|
|
@ -1035,11 +1035,14 @@ enum nsDOMProp {
|
|||
NS_DOM_PROP_XMLHTTPREQUEST_OPEN,
|
||||
NS_DOM_PROP_XULCOMMANDDISPATCHER_ACTIVE,
|
||||
NS_DOM_PROP_XULCOMMANDDISPATCHER_ADDCOMMANDUPDATER,
|
||||
NS_DOM_PROP_XULCOMMANDDISPATCHER_ADVANCEFOCUS,
|
||||
NS_DOM_PROP_XULCOMMANDDISPATCHER_ADVANCEFOCUSINTOSUBTREE,
|
||||
NS_DOM_PROP_XULCOMMANDDISPATCHER_FOCUSEDELEMENT,
|
||||
NS_DOM_PROP_XULCOMMANDDISPATCHER_FOCUSEDWINDOW,
|
||||
NS_DOM_PROP_XULCOMMANDDISPATCHER_GETCONTROLLERFORCOMMAND,
|
||||
NS_DOM_PROP_XULCOMMANDDISPATCHER_GETCONTROLLERS,
|
||||
NS_DOM_PROP_XULCOMMANDDISPATCHER_REMOVECOMMANDUPDATER,
|
||||
NS_DOM_PROP_XULCOMMANDDISPATCHER_REWINDFOCUS,
|
||||
NS_DOM_PROP_XULCOMMANDDISPATCHER_SUPPRESSFOCUS,
|
||||
NS_DOM_PROP_XULCOMMANDDISPATCHER_SUPPRESSFOCUSSCROLL,
|
||||
NS_DOM_PROP_XULCOMMANDDISPATCHER_UPDATECOMMANDS,
|
||||
|
|
|
@ -1033,11 +1033,14 @@
|
|||
"xmlhttprequest.open", \
|
||||
"xulcommanddispatcher.active", \
|
||||
"xulcommanddispatcher.addcommandupdater", \
|
||||
"xulcommanddispatcher.advancefocus", \
|
||||
"xulcommanddispatcher.advancefocusintosubtree", \
|
||||
"xulcommanddispatcher.focusedelement", \
|
||||
"xulcommanddispatcher.focusedwindow", \
|
||||
"xulcommanddispatcher.getcontrollerforcommand", \
|
||||
"xulcommanddispatcher.getcontrollers", \
|
||||
"xulcommanddispatcher.removecommandupdater", \
|
||||
"xulcommanddispatcher.rewindfocus", \
|
||||
"xulcommanddispatcher.suppressfocus", \
|
||||
"xulcommanddispatcher.suppressfocusscroll", \
|
||||
"xulcommanddispatcher.updatecommands", \
|
||||
|
|
|
@ -56,6 +56,12 @@ public:
|
|||
NS_IMETHOD GetControllerForCommand(const nsAReadableString& aCommand, nsIController** aReturn)=0;
|
||||
|
||||
NS_IMETHOD GetControllers(nsIControllers** aReturn)=0;
|
||||
|
||||
NS_IMETHOD AdvanceFocus()=0;
|
||||
|
||||
NS_IMETHOD RewindFocus()=0;
|
||||
|
||||
NS_IMETHOD AdvanceFocusIntoSubtree(nsIDOMElement* aElt)=0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -69,6 +75,9 @@ public:
|
|||
NS_IMETHOD UpdateCommands(const nsAReadableString& aEventName); \
|
||||
NS_IMETHOD GetControllerForCommand(const nsAReadableString& aCommand, nsIController** aReturn); \
|
||||
NS_IMETHOD GetControllers(nsIControllers** aReturn); \
|
||||
NS_IMETHOD AdvanceFocus(); \
|
||||
NS_IMETHOD RewindFocus(); \
|
||||
NS_IMETHOD AdvanceFocusIntoSubtree(nsIDOMElement* aElt); \
|
||||
|
||||
|
||||
|
||||
|
@ -82,6 +91,9 @@ public:
|
|||
NS_IMETHOD UpdateCommands(const nsAReadableString& aEventName) { return _to UpdateCommands(aEventName); } \
|
||||
NS_IMETHOD GetControllerForCommand(const nsAReadableString& aCommand, nsIController** aReturn) { return _to GetControllerForCommand(aCommand, aReturn); } \
|
||||
NS_IMETHOD GetControllers(nsIControllers** aReturn) { return _to GetControllers(aReturn); } \
|
||||
NS_IMETHOD AdvanceFocus() { return _to AdvanceFocus(); } \
|
||||
NS_IMETHOD RewindFocus() { return _to RewindFocus(); } \
|
||||
NS_IMETHOD AdvanceFocusIntoSubtree(nsIDOMElement* aElt) { return _to AdvanceFocusIntoSubtree(aElt); } \
|
||||
|
||||
|
||||
extern "C" NS_DOM nsresult NS_InitXULCommandDispatcherClass(nsIScriptContext *aContext, void **aPrototype);
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "nsFocusController.h"
|
||||
#include "prlog.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
|
||||
#ifdef INCLUDE_XUL
|
||||
#include "nsIDOMXULDocument.h"
|
||||
|
@ -165,6 +166,56 @@ nsFocusController::GetControllers(nsIControllers** aResult)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFocusController::MoveFocus(PRBool aForward, nsIDOMElement* aElt)
|
||||
{
|
||||
// Obtain the doc that we'll be shifting focus inside.
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
nsCOMPtr<nsIContent> content;
|
||||
if (aElt) {
|
||||
content = do_QueryInterface(aElt);
|
||||
content->GetDocument(*getter_AddRefs(doc));
|
||||
}
|
||||
else {
|
||||
if (mCurrentElement) {
|
||||
content = do_QueryInterface(mCurrentElement);
|
||||
content->GetDocument(*getter_AddRefs(doc));
|
||||
content = nsnull;
|
||||
}
|
||||
else if (mCurrentWindow) {
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
mCurrentWindow->GetDocument(getter_AddRefs(domDoc));
|
||||
doc = do_QueryInterface(domDoc);
|
||||
}
|
||||
}
|
||||
|
||||
if (!doc)
|
||||
// No way to obtain an event state manager. Give up.
|
||||
return NS_OK;
|
||||
|
||||
|
||||
// Obtain a presentation context
|
||||
PRInt32 count = doc->GetNumberOfShells();
|
||||
if (count == 0)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell(getter_AddRefs(doc->GetShellAt(0)));
|
||||
if (!shell)
|
||||
return NS_OK;
|
||||
|
||||
// Retrieve the context
|
||||
nsCOMPtr<nsIPresContext> presContext;
|
||||
shell->GetPresContext(getter_AddRefs(presContext));
|
||||
|
||||
nsCOMPtr<nsIEventStateManager> esm;
|
||||
presContext->GetEventStateManager(getter_AddRefs(esm));
|
||||
if (esm)
|
||||
// Make this ESM shift the focus per our instructions.
|
||||
esm->MoveFocus(aForward, content);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/////
|
||||
// nsIDOMFocusListener
|
||||
/////
|
||||
|
|
|
@ -65,6 +65,8 @@ public:
|
|||
NS_IMETHOD GetControllerForCommand(const nsAReadableString& aCommand, nsIController** aResult);
|
||||
NS_IMETHOD GetControllers(nsIControllers** aResult);
|
||||
|
||||
NS_IMETHOD MoveFocus(PRBool aForward, nsIDOMElement* aElt);
|
||||
|
||||
// nsIDOMFocusListener
|
||||
virtual nsresult Focus(nsIDOMEvent* aEvent);
|
||||
virtual nsresult Blur(nsIDOMEvent* aEvent);
|
||||
|
|
|
@ -445,6 +445,123 @@ XULCommandDispatcherGetControllers(JSContext *cx, JSObject *obj, uintN argc, jsv
|
|||
}
|
||||
|
||||
|
||||
//
|
||||
// Native method AdvanceFocus
|
||||
//
|
||||
PR_STATIC_CALLBACK(JSBool)
|
||||
XULCommandDispatcherAdvanceFocus(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
nsIDOMXULCommandDispatcher *nativeThis = (nsIDOMXULCommandDispatcher*)nsJSUtils::nsGetNativeThis(cx, obj);
|
||||
nsresult result = NS_OK;
|
||||
// If there's no private data, this must be the prototype, so ignore
|
||||
if (nsnull == nativeThis) {
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
{
|
||||
*rval = JSVAL_NULL;
|
||||
nsIScriptSecurityManager *secMan = nsJSUtils::nsGetSecurityManager(cx, obj);
|
||||
if (!secMan)
|
||||
return PR_FALSE;
|
||||
result = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULCOMMANDDISPATCHER_ADVANCEFOCUS, PR_FALSE);
|
||||
if (NS_FAILED(result)) {
|
||||
return nsJSUtils::nsReportError(cx, obj, result);
|
||||
}
|
||||
|
||||
result = nativeThis->AdvanceFocus();
|
||||
if (NS_FAILED(result)) {
|
||||
return nsJSUtils::nsReportError(cx, obj, result);
|
||||
}
|
||||
|
||||
*rval = JSVAL_VOID;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Native method RewindFocus
|
||||
//
|
||||
PR_STATIC_CALLBACK(JSBool)
|
||||
XULCommandDispatcherRewindFocus(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
nsIDOMXULCommandDispatcher *nativeThis = (nsIDOMXULCommandDispatcher*)nsJSUtils::nsGetNativeThis(cx, obj);
|
||||
nsresult result = NS_OK;
|
||||
// If there's no private data, this must be the prototype, so ignore
|
||||
if (nsnull == nativeThis) {
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
{
|
||||
*rval = JSVAL_NULL;
|
||||
nsIScriptSecurityManager *secMan = nsJSUtils::nsGetSecurityManager(cx, obj);
|
||||
if (!secMan)
|
||||
return PR_FALSE;
|
||||
result = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULCOMMANDDISPATCHER_REWINDFOCUS, PR_FALSE);
|
||||
if (NS_FAILED(result)) {
|
||||
return nsJSUtils::nsReportError(cx, obj, result);
|
||||
}
|
||||
|
||||
result = nativeThis->RewindFocus();
|
||||
if (NS_FAILED(result)) {
|
||||
return nsJSUtils::nsReportError(cx, obj, result);
|
||||
}
|
||||
|
||||
*rval = JSVAL_VOID;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Native method AdvanceFocusIntoSubtree
|
||||
//
|
||||
PR_STATIC_CALLBACK(JSBool)
|
||||
XULCommandDispatcherAdvanceFocusIntoSubtree(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
nsIDOMXULCommandDispatcher *nativeThis = (nsIDOMXULCommandDispatcher*)nsJSUtils::nsGetNativeThis(cx, obj);
|
||||
nsresult result = NS_OK;
|
||||
nsCOMPtr<nsIDOMElement> b0;
|
||||
// If there's no private data, this must be the prototype, so ignore
|
||||
if (nsnull == nativeThis) {
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
{
|
||||
*rval = JSVAL_NULL;
|
||||
nsIScriptSecurityManager *secMan = nsJSUtils::nsGetSecurityManager(cx, obj);
|
||||
if (!secMan)
|
||||
return PR_FALSE;
|
||||
result = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULCOMMANDDISPATCHER_ADVANCEFOCUSINTOSUBTREE, PR_FALSE);
|
||||
if (NS_FAILED(result)) {
|
||||
return nsJSUtils::nsReportError(cx, obj, result);
|
||||
}
|
||||
if (argc < 1) {
|
||||
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_TOO_FEW_PARAMETERS_ERR);
|
||||
}
|
||||
|
||||
if (JS_FALSE == nsJSUtils::nsConvertJSValToObject((nsISupports **)(void**)getter_AddRefs(b0),
|
||||
kIElementIID,
|
||||
NS_ConvertASCIItoUCS2("Element"),
|
||||
cx,
|
||||
argv[0])) {
|
||||
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_NOT_OBJECT_ERR);
|
||||
}
|
||||
|
||||
result = nativeThis->AdvanceFocusIntoSubtree(b0);
|
||||
if (NS_FAILED(result)) {
|
||||
return nsJSUtils::nsReportError(cx, obj, result);
|
||||
}
|
||||
|
||||
*rval = JSVAL_VOID;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************/
|
||||
//
|
||||
// class for XULCommandDispatcher
|
||||
|
@ -475,6 +592,9 @@ static JSFunctionSpec XULCommandDispatcherMethods[] =
|
|||
{"updateCommands", XULCommandDispatcherUpdateCommands, 1},
|
||||
{"getControllerForCommand", XULCommandDispatcherGetControllerForCommand, 1},
|
||||
{"getControllers", XULCommandDispatcherGetControllers, 0},
|
||||
{"advanceFocus", XULCommandDispatcherAdvanceFocus, 0},
|
||||
{"rewindFocus", XULCommandDispatcherRewindFocus, 0},
|
||||
{"advanceFocusIntoSubtree", XULCommandDispatcherAdvanceFocusIntoSubtree, 1},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче