зеркало из https://github.com/mozilla/gecko-dev.git
140612: Introduce tab usage pref accessibility.tabfocus, to allow tab to go only to form elements or only to text controls. (r,sr)=(bryner,sfraser)
This commit is contained in:
Родитель
c09b924557
Коммит
75743aa0f0
|
@ -140,6 +140,8 @@ nsIContent * gLastFocusedContent = 0; // Strong reference
|
||||||
nsIDocument * gLastFocusedDocument = 0; // Strong reference
|
nsIDocument * gLastFocusedDocument = 0; // Strong reference
|
||||||
nsIPresContext* gLastFocusedPresContext = 0; // Weak reference
|
nsIPresContext* gLastFocusedPresContext = 0; // Weak reference
|
||||||
|
|
||||||
|
PRInt32 nsEventStateManager::sTabFocusModel = eTabFocus_unset;
|
||||||
|
|
||||||
PRUint32 nsEventStateManager::mInstanceCount = 0;
|
PRUint32 nsEventStateManager::mInstanceCount = 0;
|
||||||
PRInt32 nsEventStateManager::gGeneralAccesskeyModifier = -1; // magic value of -1 means uninitialized
|
PRInt32 nsEventStateManager::gGeneralAccesskeyModifier = -1; // magic value of -1 means uninitialized
|
||||||
|
|
||||||
|
@ -3286,7 +3288,7 @@ nsEventStateManager::GetNextTabbableContent(nsIContent* aRootContent, nsIFrame*
|
||||||
if (mCurrentFocus) {
|
if (mCurrentFocus) {
|
||||||
nsCOMPtr<nsIAtom> tag;
|
nsCOMPtr<nsIAtom> tag;
|
||||||
mCurrentFocus->GetTag(*getter_AddRefs(tag));
|
mCurrentFocus->GetTag(*getter_AddRefs(tag));
|
||||||
if(nsHTMLAtoms::area==tag.get()) {
|
if(nsHTMLAtoms::area==tag) {
|
||||||
//Focus is in an imagemap area
|
//Focus is in an imagemap area
|
||||||
nsCOMPtr<nsIPresShell> presShell;
|
nsCOMPtr<nsIPresShell> presShell;
|
||||||
if (mPresContext) {
|
if (mPresContext) {
|
||||||
|
@ -3366,10 +3368,22 @@ nsEventStateManager::GetNextTabbableContent(nsIContent* aRootContent, nsIFrame*
|
||||||
PRBool disabled = PR_TRUE;
|
PRBool disabled = PR_TRUE;
|
||||||
PRBool hidden = PR_FALSE;
|
PRBool hidden = PR_FALSE;
|
||||||
|
|
||||||
|
// Tab focus mode is constant across all windows.
|
||||||
|
// It would be nicer if ESM had a prefs callback,
|
||||||
|
// so we could store this and change behavior when it changes.
|
||||||
|
// But until the pref is exposed, that doesn't matter.
|
||||||
|
if (sTabFocusModel == eTabFocus_unset) {
|
||||||
|
sTabFocusModel = (eTabFocus_textControlsMask | eTabFocus_formElementsMask
|
||||||
|
| eTabFocus_linksMask);
|
||||||
|
nsresult rv = getPrefService();
|
||||||
|
if (NS_SUCCEEDED(rv))
|
||||||
|
mPrefService->GetIntPref("accessibility.tabfocus", &sTabFocusModel);
|
||||||
|
}
|
||||||
|
|
||||||
child->GetTag(*getter_AddRefs(tag));
|
child->GetTag(*getter_AddRefs(tag));
|
||||||
nsCOMPtr<nsIDOMHTMLElement> htmlElement(do_QueryInterface(child));
|
nsCOMPtr<nsIDOMHTMLElement> htmlElement(do_QueryInterface(child));
|
||||||
if (htmlElement) {
|
if (htmlElement) {
|
||||||
if (nsHTMLAtoms::input==tag.get()) {
|
if (nsHTMLAtoms::input==tag) {
|
||||||
nsCOMPtr<nsIDOMHTMLInputElement> nextInput(do_QueryInterface(child));
|
nsCOMPtr<nsIDOMHTMLInputElement> nextInput(do_QueryInterface(child));
|
||||||
if (nextInput) {
|
if (nextInput) {
|
||||||
nextInput->GetDisabled(&disabled);
|
nextInput->GetDisabled(&disabled);
|
||||||
|
@ -3377,30 +3391,49 @@ nsEventStateManager::GetNextTabbableContent(nsIContent* aRootContent, nsIFrame*
|
||||||
|
|
||||||
nsAutoString type;
|
nsAutoString type;
|
||||||
nextInput->GetType(type);
|
nextInput->GetType(type);
|
||||||
if (type.EqualsIgnoreCase("hidden")) {
|
if (type.EqualsIgnoreCase("text")) {
|
||||||
|
// It's a text field
|
||||||
|
disabled = !(sTabFocusModel & eTabFocus_textControlsMask);
|
||||||
|
}
|
||||||
|
else if (type.EqualsIgnoreCase("hidden")) {
|
||||||
hidden = PR_TRUE;
|
hidden = PR_TRUE;
|
||||||
}
|
}
|
||||||
else if (type.EqualsIgnoreCase("file")) {
|
else if (type.EqualsIgnoreCase("file")) {
|
||||||
disabled = PR_TRUE;
|
disabled = PR_TRUE;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// it's some other type of form element
|
||||||
|
disabled = !(sTabFocusModel & eTabFocus_formElementsMask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (nsHTMLAtoms::select==tag.get()) {
|
}
|
||||||
|
else if (nsHTMLAtoms::select==tag) {
|
||||||
|
// Select counts as form but not as text
|
||||||
|
disabled = !(sTabFocusModel & eTabFocus_formElementsMask);
|
||||||
|
if (!disabled) {
|
||||||
nsCOMPtr<nsIDOMHTMLSelectElement> nextSelect(do_QueryInterface(child));
|
nsCOMPtr<nsIDOMHTMLSelectElement> nextSelect(do_QueryInterface(child));
|
||||||
if (nextSelect) {
|
if (nextSelect) {
|
||||||
nextSelect->GetDisabled(&disabled);
|
nextSelect->GetDisabled(&disabled);
|
||||||
nextSelect->GetTabIndex(&tabIndex);
|
nextSelect->GetTabIndex(&tabIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (nsHTMLAtoms::textarea==tag.get()) {
|
}
|
||||||
|
else if (nsHTMLAtoms::textarea==tag) {
|
||||||
|
// it's a textarea
|
||||||
|
disabled = !(sTabFocusModel & eTabFocus_textControlsMask);
|
||||||
|
if (!disabled) {
|
||||||
nsCOMPtr<nsIDOMHTMLTextAreaElement> nextTextArea(do_QueryInterface(child));
|
nsCOMPtr<nsIDOMHTMLTextAreaElement> nextTextArea(do_QueryInterface(child));
|
||||||
if (nextTextArea) {
|
if (nextTextArea) {
|
||||||
nextTextArea->GetDisabled(&disabled);
|
nextTextArea->GetDisabled(&disabled);
|
||||||
nextTextArea->GetTabIndex(&tabIndex);
|
nextTextArea->GetTabIndex(&tabIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(nsHTMLAtoms::a==tag.get()) {
|
}
|
||||||
|
else if (nsHTMLAtoms::a==tag) {
|
||||||
|
// it's a link
|
||||||
|
disabled = !(sTabFocusModel & eTabFocus_linksMask);
|
||||||
nsCOMPtr<nsIDOMHTMLAnchorElement> nextAnchor(do_QueryInterface(child));
|
nsCOMPtr<nsIDOMHTMLAnchorElement> nextAnchor(do_QueryInterface(child));
|
||||||
|
if (!disabled) {
|
||||||
if (nextAnchor)
|
if (nextAnchor)
|
||||||
nextAnchor->GetTabIndex(&tabIndex);
|
nextAnchor->GetTabIndex(&tabIndex);
|
||||||
nsAutoString href;
|
nsAutoString href;
|
||||||
|
@ -3411,14 +3444,22 @@ nsEventStateManager::GetNextTabbableContent(nsIContent* aRootContent, nsIFrame*
|
||||||
disabled = PR_FALSE;
|
disabled = PR_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(nsHTMLAtoms::button==tag.get()) {
|
}
|
||||||
|
else if (nsHTMLAtoms::button==tag) {
|
||||||
|
// Button counts as a form element but not as text
|
||||||
|
disabled = !(sTabFocusModel & eTabFocus_formElementsMask);
|
||||||
|
if (!disabled) {
|
||||||
nsCOMPtr<nsIDOMHTMLButtonElement> nextButton(do_QueryInterface(child));
|
nsCOMPtr<nsIDOMHTMLButtonElement> nextButton(do_QueryInterface(child));
|
||||||
if (nextButton) {
|
if (nextButton) {
|
||||||
nextButton->GetTabIndex(&tabIndex);
|
nextButton->GetTabIndex(&tabIndex);
|
||||||
nextButton->GetDisabled(&disabled);
|
nextButton->GetDisabled(&disabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(nsHTMLAtoms::img==tag.get()) {
|
}
|
||||||
|
else if (nsHTMLAtoms::img==tag) {
|
||||||
|
// Images are treated like links for tab focus purposes.
|
||||||
|
disabled = !(sTabFocusModel & eTabFocus_linksMask);
|
||||||
|
if (!disabled) {
|
||||||
nsCOMPtr<nsIDOMHTMLImageElement> nextImage(do_QueryInterface(child));
|
nsCOMPtr<nsIDOMHTMLImageElement> nextImage(do_QueryInterface(child));
|
||||||
nsAutoString usemap;
|
nsAutoString usemap;
|
||||||
if (nextImage) {
|
if (nextImage) {
|
||||||
|
@ -3439,10 +3480,12 @@ nsEventStateManager::GetNextTabbableContent(nsIContent* aRootContent, nsIFrame*
|
||||||
PRInt32 val = 0;
|
PRInt32 val = 0;
|
||||||
TabIndexFrom(childArea, &val);
|
TabIndexFrom(childArea, &val);
|
||||||
if (mCurrentTabIndex == val) {
|
if (mCurrentTabIndex == val) {
|
||||||
//mCurrentFocus is in this map so we must start iterating past it.
|
// mCurrentFocus is in this map so we must start
|
||||||
//We skip the case where mCurrentFocus has the same tab index
|
// iterating past it.
|
||||||
//as mCurrentTabIndex since the next tab ordered element might
|
// We skip the case where mCurrentFocus has the
|
||||||
//be before it (or after for backwards) in the child list.
|
// same tab index as mCurrentTabIndex since the
|
||||||
|
// next tab ordered element might be before it
|
||||||
|
// (or after for backwards) in the child list.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3468,20 +3511,27 @@ nsEventStateManager::GetNextTabbableContent(nsIContent* aRootContent, nsIFrame*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(nsHTMLAtoms::object==tag.get()) {
|
}
|
||||||
|
else if (nsHTMLAtoms::object==tag) {
|
||||||
|
// OBJECT is treated as a form element.
|
||||||
|
disabled = !(sTabFocusModel & eTabFocus_formElementsMask);
|
||||||
|
if (!disabled) {
|
||||||
nsCOMPtr<nsIDOMHTMLObjectElement> nextObject(do_QueryInterface(child));
|
nsCOMPtr<nsIDOMHTMLObjectElement> nextObject(do_QueryInterface(child));
|
||||||
if (nextObject)
|
if (nextObject)
|
||||||
nextObject->GetTabIndex(&tabIndex);
|
nextObject->GetTabIndex(&tabIndex);
|
||||||
disabled = PR_FALSE;
|
disabled = PR_FALSE;
|
||||||
}
|
}
|
||||||
else if (nsHTMLAtoms::iframe==tag.get()) {
|
}
|
||||||
|
else if (nsHTMLAtoms::iframe==tag) {
|
||||||
disabled = PR_FALSE;
|
disabled = PR_FALSE;
|
||||||
}
|
}
|
||||||
else if (nsHTMLAtoms::frame==tag.get()) {
|
else if (nsHTMLAtoms::frame==tag) {
|
||||||
disabled = PR_FALSE;
|
disabled = PR_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
// Check the tabindex attribute, unless the model specifies text only.
|
||||||
|
// If the model is unset then we'll depend on tabindex.
|
||||||
|
else if (sTabFocusModel != eTabFocus_textControlsMask) {
|
||||||
nsAutoString value;
|
nsAutoString value;
|
||||||
child->GetAttr(kNameSpaceID_None, nsHTMLAtoms::disabled, value);
|
child->GetAttr(kNameSpaceID_None, nsHTMLAtoms::disabled, value);
|
||||||
nsAutoString tabStr;
|
nsAutoString tabStr;
|
||||||
|
|
|
@ -71,6 +71,13 @@ class nsEventStateManager : public nsSupportsWeakReference,
|
||||||
public nsIEventStateManager,
|
public nsIEventStateManager,
|
||||||
public nsIObserver
|
public nsIObserver
|
||||||
{
|
{
|
||||||
|
// Tab focus model bit field:
|
||||||
|
enum nsTabFocusModel {
|
||||||
|
eTabFocus_unset = 0, // unset, check preferences
|
||||||
|
eTabFocus_textControlsMask = (1<<0), // text elements
|
||||||
|
eTabFocus_formElementsMask = (1<<1), // non-text form elements
|
||||||
|
eTabFocus_linksMask = (1<<2) // links
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
nsEventStateManager();
|
nsEventStateManager();
|
||||||
|
@ -273,6 +280,10 @@ protected:
|
||||||
// So we don't have to keep checking accessibility.browsewithcaret pref
|
// So we don't have to keep checking accessibility.browsewithcaret pref
|
||||||
PRBool mBrowseWithCaret;
|
PRBool mBrowseWithCaret;
|
||||||
|
|
||||||
|
// Tab focus policy (static, constant across the app):
|
||||||
|
// Which types of elements are in the tab order?
|
||||||
|
static PRInt32 sTabFocusModel;
|
||||||
|
|
||||||
// Recursion guard for tabbing
|
// Recursion guard for tabbing
|
||||||
PRBool mTabbedThroughDocument;
|
PRBool mTabbedThroughDocument;
|
||||||
|
|
||||||
|
|
|
@ -125,6 +125,10 @@ pref("browser.helperApps.neverAsk.openFile", "");
|
||||||
|
|
||||||
pref("accessibility.browsewithcaret", false);
|
pref("accessibility.browsewithcaret", false);
|
||||||
pref("accessibility.warn_on_browsewithcaret", true);
|
pref("accessibility.warn_on_browsewithcaret", true);
|
||||||
|
// Tab focus model bit field:
|
||||||
|
// 1 focuses text controls, 2 focuses other form elements, 4 adds links.
|
||||||
|
// Most users will want 1, 3, or 7.
|
||||||
|
pref("accessibility.tabfocus", 7);
|
||||||
pref("accessibility.usetexttospeech", "");
|
pref("accessibility.usetexttospeech", "");
|
||||||
pref("accessibility.usebrailledisplay", "");
|
pref("accessibility.usebrailledisplay", "");
|
||||||
pref("accessibility.accesskeycausesactivation", true);
|
pref("accessibility.accesskeycausesactivation", true);
|
||||||
|
|
|
@ -180,6 +180,10 @@ pref("font.size.fixed.zh-CN", 16);
|
||||||
pref("font.size.variable.zh-TW", 15);
|
pref("font.size.variable.zh-TW", 15);
|
||||||
pref("font.size.fixed.zh-TW", 16);
|
pref("font.size.fixed.zh-TW", 16);
|
||||||
|
|
||||||
|
// Tab focus model bit field:
|
||||||
|
// 1 focuses text controls, 2 focuses other form elements, 4 adds links.
|
||||||
|
pref("accessibility.tabfocus", 1);
|
||||||
|
|
||||||
// Override the Windows settings: no menu key, meta accelerator key. ctrl for general access key in HTML/XUL
|
// Override the Windows settings: no menu key, meta accelerator key. ctrl for general access key in HTML/XUL
|
||||||
// Use 17 for Ctrl, 18 for Option, 224 for Cmd, 0 for none
|
// Use 17 for Ctrl, 18 for Option, 224 for Cmd, 0 for none
|
||||||
pref("ui.key.menuAccessKey", 0);
|
pref("ui.key.menuAccessKey", 0);
|
||||||
|
|
|
@ -67,6 +67,10 @@ pref("clipboard.autocopy", true);
|
||||||
|
|
||||||
pref("browser.urlbar.clickSelectsAll", false);
|
pref("browser.urlbar.clickSelectsAll", false);
|
||||||
|
|
||||||
|
// Tab focus model bit field:
|
||||||
|
// 1 focuses text controls, 2 focuses other form elements, 4 adds links.
|
||||||
|
pref("accessibility.tabfocus", 1);
|
||||||
|
|
||||||
// override double-click word selection behavior.
|
// override double-click word selection behavior.
|
||||||
pref("layout.word_select.stop_at_punctuation", false);
|
pref("layout.word_select.stop_at_punctuation", false);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче