зеркало из https://github.com/mozilla/pjs.git
Bug 174889 - unable to get keyboard shortcut for treeitem node, r=smaug, ginn.chen, mats, sr=mats, a=sicking
This commit is contained in:
Родитель
63092ee320
Коммит
9f86cbcecf
|
@ -46,6 +46,9 @@
|
|||
#include "nsIDOMXULSelectCntrlEl.h"
|
||||
#include "nsIDOMXULSelectCntrlItemEl.h"
|
||||
#include "nsIEventListenerManager.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsISelection2.h"
|
||||
#include "nsISelectionController.h"
|
||||
|
||||
|
@ -176,6 +179,39 @@ nsAccUtils::HasListener(nsIContent *aContent, const nsAString& aEventType)
|
|||
return listenerManager && listenerManager->HasListenersFor(aEventType);
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsAccUtils::GetAccessKeyFor(nsIContent *aContent)
|
||||
{
|
||||
if (!aContent)
|
||||
return 0;
|
||||
|
||||
// Accesskeys are registered by @accesskey attribute only. At first check
|
||||
// whether it is presented on the given element to avoid the slow
|
||||
// nsIEventStateManager::GetRegisteredAccessKey() method.
|
||||
if (!aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::accesskey))
|
||||
return 0;
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = aContent->GetOwnerDoc();
|
||||
if (!doc)
|
||||
return 0;
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell = doc->GetPrimaryShell();
|
||||
if (!presShell)
|
||||
return 0;
|
||||
|
||||
nsPresContext *presContext = presShell->GetPresContext();
|
||||
if (!presContext)
|
||||
return 0;
|
||||
|
||||
nsIEventStateManager *esm = presContext->EventStateManager();
|
||||
if (!esm)
|
||||
return 0;
|
||||
|
||||
PRUint32 key = 0;
|
||||
esm->GetRegisteredAccessKey(aContent, &key);
|
||||
return key;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAccUtils::FireAccEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
|
||||
PRBool aIsAsynch)
|
||||
|
|
|
@ -109,6 +109,14 @@ public:
|
|||
*/
|
||||
static PRBool HasListener(nsIContent *aContent, const nsAString& aEventType);
|
||||
|
||||
/**
|
||||
* Return an accesskey registered on the given element by
|
||||
* nsIEventStateManager or 0 if there is no registered accesskey.
|
||||
*
|
||||
* @param aContent - the given element.
|
||||
*/
|
||||
static PRUint32 GetAccessKeyFor(nsIContent *aContent);
|
||||
|
||||
/**
|
||||
* Fire accessible event of the given type for the given accessible.
|
||||
*/
|
||||
|
|
|
@ -349,7 +349,7 @@ NS_IMETHODIMP nsAccessible::GetDescription(nsAString& aDescription)
|
|||
// returns the accesskey modifier mask used in the given node's context
|
||||
// (i.e. chrome or content), or 0 if an error occurs
|
||||
static PRInt32
|
||||
GetAccessModifierMask(nsIDOMElement* aDOMNode)
|
||||
GetAccessModifierMask(nsIContent* aContent)
|
||||
{
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch =
|
||||
do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
|
@ -370,8 +370,7 @@ GetAccessModifierMask(nsIDOMElement* aDOMNode)
|
|||
}
|
||||
|
||||
// get the docShell to this DOMNode, return 0 on failure
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aDOMNode));
|
||||
nsCOMPtr<nsIDocument> document = content->GetCurrentDoc();
|
||||
nsCOMPtr<nsIDocument> document = aContent->GetCurrentDoc();
|
||||
if (!document)
|
||||
return 0;
|
||||
nsCOMPtr<nsISupports> container = document->GetContainer();
|
||||
|
@ -398,47 +397,49 @@ GetAccessModifierMask(nsIDOMElement* aDOMNode)
|
|||
return NS_SUCCEEDED(rv) ? accessModifierMask : 0;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAccessible::GetKeyboardShortcut(nsAString& _retval)
|
||||
NS_IMETHODIMP
|
||||
nsAccessible::GetKeyboardShortcut(nsAString& aAccessKey)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(mDOMNode));
|
||||
if (elt) {
|
||||
nsAutoString accesskey;
|
||||
elt->GetAttribute(NS_LITERAL_STRING("accesskey"), accesskey);
|
||||
if (accesskey.IsEmpty()) {
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(elt);
|
||||
nsIContent *labelContent = GetLabelContent(content);
|
||||
if (labelContent) {
|
||||
labelContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::accesskey, accesskey);
|
||||
}
|
||||
if (accesskey.IsEmpty()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
aAccessKey.Truncate();
|
||||
|
||||
// append the modifiers in reverse order
|
||||
// (result: Control+Alt+Shift+Meta+<key>)
|
||||
nsAutoString propertyKey;
|
||||
PRInt32 modifierMask = GetAccessModifierMask(elt);
|
||||
if (modifierMask & NS_MODIFIER_META) {
|
||||
propertyKey.AssignLiteral("VK_META");
|
||||
nsAccessible::GetFullKeyName(propertyKey, accesskey, accesskey);
|
||||
}
|
||||
if (modifierMask & NS_MODIFIER_SHIFT) {
|
||||
propertyKey.AssignLiteral("VK_SHIFT");
|
||||
nsAccessible::GetFullKeyName(propertyKey, accesskey, accesskey);
|
||||
}
|
||||
if (modifierMask & NS_MODIFIER_ALT) {
|
||||
propertyKey.AssignLiteral("VK_ALT");
|
||||
nsAccessible::GetFullKeyName(propertyKey, accesskey, accesskey);
|
||||
}
|
||||
if (modifierMask & NS_MODIFIER_CONTROL) {
|
||||
propertyKey.AssignLiteral("VK_CONTROL");
|
||||
nsAccessible::GetFullKeyName(propertyKey, accesskey, accesskey);
|
||||
}
|
||||
_retval= accesskey;
|
||||
return NS_OK;
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
if (!content)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PRUint32 key = nsAccUtils::GetAccessKeyFor(content);
|
||||
if (!key) {
|
||||
nsCOMPtr<nsIContent> labelContent(GetLabelContent(content));
|
||||
if (labelContent)
|
||||
key = nsAccUtils::GetAccessKeyFor(labelContent);
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!key)
|
||||
return NS_OK;
|
||||
|
||||
nsAutoString accesskey(key);
|
||||
|
||||
// Append the modifiers in reverse order, result: Control+Alt+Shift+Meta+<key>
|
||||
nsAutoString propertyKey;
|
||||
PRInt32 modifierMask = GetAccessModifierMask(content);
|
||||
if (modifierMask & NS_MODIFIER_META) {
|
||||
propertyKey.AssignLiteral("VK_META");
|
||||
nsAccessible::GetFullKeyName(propertyKey, accesskey, accesskey);
|
||||
}
|
||||
if (modifierMask & NS_MODIFIER_SHIFT) {
|
||||
propertyKey.AssignLiteral("VK_SHIFT");
|
||||
nsAccessible::GetFullKeyName(propertyKey, accesskey, accesskey);
|
||||
}
|
||||
if (modifierMask & NS_MODIFIER_ALT) {
|
||||
propertyKey.AssignLiteral("VK_ALT");
|
||||
nsAccessible::GetFullKeyName(propertyKey, accesskey, accesskey);
|
||||
}
|
||||
if (modifierMask & NS_MODIFIER_CONTROL) {
|
||||
propertyKey.AssignLiteral("VK_CONTROL");
|
||||
nsAccessible::GetFullKeyName(propertyKey, accesskey, accesskey);
|
||||
}
|
||||
|
||||
aAccessKey = accesskey;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAccessible::SetParent(nsIAccessible *aParent)
|
||||
|
|
|
@ -391,13 +391,18 @@ NS_IMETHODIMP nsXULMenuitemAccessible::GetDescription(nsAString& aDescription)
|
|||
}
|
||||
|
||||
//return menu accesskey: N or Alt+F
|
||||
NS_IMETHODIMP nsXULMenuitemAccessible::GetKeyboardShortcut(nsAString& _retval)
|
||||
NS_IMETHODIMP
|
||||
nsXULMenuitemAccessible::GetKeyboardShortcut(nsAString& aAccessKey)
|
||||
{
|
||||
aAccessKey.Truncate();
|
||||
|
||||
static PRInt32 gMenuAccesskeyModifier = -1; // magic value of -1 indicates unitialized state
|
||||
|
||||
nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(mDOMNode));
|
||||
if (elt) {
|
||||
nsAutoString accesskey;
|
||||
// We do not use nsAccUtils::GetAccesskeyFor() because accesskeys for
|
||||
// menu are't registered by nsIEventStateManager.
|
||||
elt->GetAttribute(NS_LITERAL_STRING("accesskey"), accesskey);
|
||||
if (accesskey.IsEmpty())
|
||||
return NS_OK;
|
||||
|
@ -423,11 +428,11 @@ NS_IMETHODIMP nsXULMenuitemAccessible::GetKeyboardShortcut(nsAString& _retval)
|
|||
case nsIDOMKeyEvent::DOM_VK_META: propertyKey.AssignLiteral("VK_META"); break;
|
||||
}
|
||||
if (!propertyKey.IsEmpty())
|
||||
nsAccessible::GetFullKeyName(propertyKey, accesskey, _retval);
|
||||
nsAccessible::GetFullKeyName(propertyKey, accesskey, aAccessKey);
|
||||
}
|
||||
}
|
||||
if (_retval.IsEmpty())
|
||||
_retval = accesskey;
|
||||
if (aAccessKey.IsEmpty())
|
||||
aAccessKey = accesskey;
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
|
|
|
@ -54,8 +54,8 @@ class imgIContainer;
|
|||
*/
|
||||
// {fb7516ff-2f01-4893-84e8-e4b282813023}
|
||||
#define NS_IEVENTSTATEMANAGER_IID \
|
||||
{ 0xfb7516ff, 0x2f01, 0x4893, \
|
||||
{ 0x84, 0xe8, 0xe4, 0xb2, 0x82, 0x81, 0x30, 0x23 } }
|
||||
{ 0x522d12ec, 0xde51, 0x4635, \
|
||||
{ 0xb0, 0x10, 0x4, 0x2a, 0x6d, 0x5, 0xa0, 0x3e } }
|
||||
|
||||
#define NS_EVENT_NEEDS_FRAME(event) (!NS_IS_FOCUS_EVENT(event))
|
||||
|
||||
|
@ -132,9 +132,33 @@ public:
|
|||
NS_IMETHOD ChangeFocusWith(nsIContent *aFocusContent, EFocusedWithType aFocusedWith) = 0;
|
||||
|
||||
// Access Key Registration
|
||||
|
||||
/**
|
||||
* Register accesskey on the given element. When accesskey is activated then
|
||||
* the element will be notified via nsIContent::PerformAccesskey() method.
|
||||
*
|
||||
* @param aContent the given element
|
||||
* @param aKey accesskey
|
||||
*/
|
||||
NS_IMETHOD RegisterAccessKey(nsIContent* aContent, PRUint32 aKey) = 0;
|
||||
|
||||
/**
|
||||
* Unregister accesskey for the given element.
|
||||
*
|
||||
* @param aContent the given element
|
||||
* @param aKey accesskey
|
||||
*/
|
||||
NS_IMETHOD UnregisterAccessKey(nsIContent* aContent, PRUint32 aKey) = 0;
|
||||
|
||||
/**
|
||||
* Get accesskey registered on the given element or 0 if there is none.
|
||||
*
|
||||
* @param aContent the given element
|
||||
* @param aKey registered accesskey
|
||||
* @return NS_OK
|
||||
*/
|
||||
NS_IMETHOD GetRegisteredAccessKey(nsIContent* aContent, PRUint32* aKey) = 0;
|
||||
|
||||
NS_IMETHOD SetCursor(PRInt32 aCursor, imgIContainer* aContainer,
|
||||
PRBool aHaveHotspot, float aHotspotX, float aHotspotY,
|
||||
nsIWidget* aWidget, PRBool aLockCursor) = 0;
|
||||
|
|
|
@ -179,6 +179,27 @@ enum {
|
|||
MOUSE_SCROLL_PIXELS
|
||||
};
|
||||
|
||||
struct AccessKeyInfo {
|
||||
PRUint32 mAccessKey;
|
||||
nsIContent* mTarget;
|
||||
|
||||
AccessKeyInfo(nsIContent* aTarget) : mAccessKey(0), mTarget(aTarget) {}
|
||||
};
|
||||
|
||||
static PRIntn PR_CALLBACK
|
||||
FindTargetForAccessKey(nsHashKey *aKey, void *aData, void* aClosure)
|
||||
{
|
||||
AccessKeyInfo* info = static_cast<AccessKeyInfo*>(aClosure);
|
||||
nsIContent* aTarget = static_cast<nsIContent*>(aData);
|
||||
|
||||
if (aTarget == info->mTarget) {
|
||||
info->mAccessKey = aKey->HashCode();
|
||||
return kHashEnumerateStop;
|
||||
}
|
||||
|
||||
return kHashEnumerateNext;
|
||||
}
|
||||
|
||||
// mask values for ui.key.chromeAccess and ui.key.contentAccess
|
||||
#define NS_MODIFIER_SHIFT 1
|
||||
#define NS_MODIFIER_CONTROL 2
|
||||
|
@ -4659,6 +4680,8 @@ nsEventStateManager::RegisterAccessKey(nsIContent* aContent, PRUint32 aKey)
|
|||
PRUint32 accKey = (IS_IN_BMP(aKey)) ? ToLowerCase((PRUnichar)aKey) : aKey;
|
||||
|
||||
nsVoidKey key(NS_INT32_TO_PTR(accKey));
|
||||
NS_ASSERTION(key.HashCode() == accKey,
|
||||
"nsHashKey::HashCode() doesn't return an accesskey");
|
||||
|
||||
#ifdef DEBUG_jag
|
||||
nsCOMPtr<nsIContent> oldContent = dont_AddRef(static_cast<nsIContent*>(mAccessKeys->Get(&key)));
|
||||
|
@ -4694,6 +4717,24 @@ nsEventStateManager::UnregisterAccessKey(nsIContent* aContent, PRUint32 aKey)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEventStateManager::GetRegisteredAccessKey(nsIContent* aContent,
|
||||
PRUint32* aKey)
|
||||
{
|
||||
NS_ENSURE_ARG(aContent);
|
||||
NS_ENSURE_ARG_POINTER(aKey);
|
||||
*aKey = 0;
|
||||
|
||||
if (!mAccessKeys)
|
||||
return NS_OK;
|
||||
|
||||
AccessKeyInfo info(aContent);
|
||||
mAccessKeys->Enumerate(FindTargetForAccessKey, &info);
|
||||
|
||||
*aKey = info.mAccessKey;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsEventStateManager::ForceViewUpdate(nsIView* aView)
|
||||
{
|
||||
|
|
|
@ -127,6 +127,7 @@ public:
|
|||
// Access Key Registration
|
||||
NS_IMETHOD RegisterAccessKey(nsIContent* aContent, PRUint32 aKey);
|
||||
NS_IMETHOD UnregisterAccessKey(nsIContent* aContent, PRUint32 aKey);
|
||||
NS_IMETHOD GetRegisteredAccessKey(nsIContent* aContent, PRUint32* aKey);
|
||||
|
||||
NS_IMETHOD SetCursor(PRInt32 aCursor, imgIContainer* aContainer,
|
||||
PRBool aHaveHotspot, float aHotspotX, float aHotspotY,
|
||||
|
|
Загрузка…
Ссылка в новой задаче