Bug 648235 - Use more underlying HTML input states for XUL textboxes, r=davidb
authorAlexander Surkov <surkov.alexander@gmail.com>
Sun, 10 Apr 2011 08:37:04 +0900
changeset 67789 a8449b5e644016c651b590fa9ca5b569bc3c52d5
parent 67788 028a07f2fae2d706e00e1d0e2db5e60f5e37d958
child 67790 f15bfa1cb14b56e067e1cfcf2f2eb75a6b27691d
push id19428
push usereakhgari@mozilla.com
push dateSun, 10 Apr 2011 19:11:44 +0000
treeherdermozilla-central@6eaee284fdb9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdavidb
bugs648235
milestone2.2a1pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 648235 - Use more underlying HTML input states for XUL textboxes, r=davidb
accessible/src/html/nsHTMLFormControlAccessible.cpp
accessible/src/xul/nsXULFormControlAccessible.cpp
accessible/tests/mochitest/states.js
accessible/tests/mochitest/states/Makefile.in
accessible/tests/mochitest/states/test_inputs.html
accessible/tests/mochitest/states/test_textbox.xul
--- a/accessible/src/html/nsHTMLFormControlAccessible.cpp
+++ b/accessible/src/html/nsHTMLFormControlAccessible.cpp
@@ -490,23 +490,24 @@ nsHTMLTextFieldAccessible::GetStateInter
   }
 
   if (!(*aExtraState & nsIAccessibleStates::EXT_STATE_EDITABLE))
     return NS_OK;
 
   nsCOMPtr<nsIContent> bindingContent = mContent->GetBindingParent();
   if (bindingContent &&
       bindingContent->NodeInfo()->Equals(nsAccessibilityAtoms::textbox,
-                                         kNameSpaceID_XUL) &&
-      bindingContent->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::type,
-                                  nsAccessibilityAtoms::autocomplete,
-                                  eIgnoreCase)) {
-    // If parent is XUL textbox and value of @type attribute is "autocomplete",
-    // then this accessible supports autocompletion.
-    *aExtraState |= nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION;
+                                         kNameSpaceID_XUL)) {
+     if (bindingContent->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::type,
+                                     nsAccessibilityAtoms::autocomplete,
+                                     eIgnoreCase)) {
+       // If parent is XUL textbox and value of @type attribute is "autocomplete",
+       // then this accessible supports autocompletion.
+       *aExtraState |= nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION;
+     }
   } else if (gIsFormFillEnabled && htmlInput &&
              !(*aState & nsIAccessibleStates::STATE_PROTECTED)) {
     // Check to see if autocompletion is allowed on this input. We don't expose
     // it for password fields even though the entire password can be remembered
     // for a page if the user asks it to be. However, the kind of autocomplete
     // we're talking here is based on what the user types, where a popup of
     // possible choices comes up.
     nsAutoString autocomplete;
--- a/accessible/src/xul/nsXULFormControlAccessible.cpp
+++ b/accessible/src/xul/nsXULFormControlAccessible.cpp
@@ -914,60 +914,36 @@ nsXULTextFieldAccessible::GetStateIntern
   NS_ENSURE_A11Y_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIContent> inputField(GetInputField());
   NS_ENSURE_TRUE(inputField, NS_ERROR_FAILURE);
 
   // Create a temporary accessible from the HTML text field
   // to get the accessible state from. Doesn't add to cache
   // because Init() is not called.
-  nsHTMLTextFieldAccessible* tempAccessible =
+  nsRefPtr<nsHTMLTextFieldAccessible> tempAccessible =
     new nsHTMLTextFieldAccessible(inputField, mWeakShell);
   if (!tempAccessible)
     return NS_ERROR_OUT_OF_MEMORY;
-  nsCOMPtr<nsIAccessible> kungFuDeathGrip = tempAccessible;
-  rv = tempAccessible->GetStateInternal(aState, nsnull);
+
+  rv = tempAccessible->GetStateInternal(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (gLastFocusedNode == mContent)
     *aState |= nsIAccessibleStates::STATE_FOCUSED;
 
   nsCOMPtr<nsIDOMXULMenuListElement> menuList(do_QueryInterface(mContent));
   if (menuList) {
     // <xul:menulist droppable="false">
     if (!mContent->AttrValueIs(kNameSpaceID_None,
                                nsAccessibilityAtoms::editable,
                                nsAccessibilityAtoms::_true, eIgnoreCase)) {
       *aState |= nsIAccessibleStates::STATE_READONLY;
     }
   }
-  else {
-    // <xul:textbox>
-    if (mContent->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::type,
-                              nsAccessibilityAtoms::password, eIgnoreCase)) {
-      *aState |= nsIAccessibleStates::STATE_PROTECTED;
-    }
-    if (mContent->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::readonly,
-                              nsAccessibilityAtoms::_true, eIgnoreCase)) {
-      *aState |= nsIAccessibleStates::STATE_READONLY;
-    }
-  }
-
-  if (!aExtraState)
-    return NS_OK;
-
-  PRBool isMultiLine = mContent->HasAttr(kNameSpaceID_None,
-                                         nsAccessibilityAtoms::multiline);
-
-  if (isMultiLine) {
-    *aExtraState |= nsIAccessibleStates::EXT_STATE_MULTI_LINE;
-  }
-  else {
-    *aExtraState |= nsIAccessibleStates::EXT_STATE_SINGLE_LINE;
-  }
 
   return NS_OK;
 }
 
 PRUint32
 nsXULTextFieldAccessible::NativeRole()
 {
   if (mContent->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::type,
--- a/accessible/tests/mochitest/states.js
+++ b/accessible/tests/mochitest/states.js
@@ -20,16 +20,17 @@ const STATE_FOCUSED = nsIAccessibleState
 const STATE_HASPOPUP = nsIAccessibleStates.STATE_HASPOPUP;
 const STATE_INVALID = nsIAccessibleStates.STATE_INVALID;
 const STATE_INVISIBLE = nsIAccessibleStates.STATE_INVISIBLE;
 const STATE_LINKED = nsIAccessibleStates.STATE_LINKED;
 const STATE_MIXED = nsIAccessibleStates.STATE_MIXED;
 const STATE_MULTISELECTABLE = nsIAccessibleStates.STATE_MULTISELECTABLE;
 const STATE_OFFSCREEN = nsIAccessibleStates.STATE_OFFSCREEN;
 const STATE_PRESSED = nsIAccessibleStates.STATE_PRESSED;
+const STATE_PROTECTED = nsIAccessibleStates.STATE_PROTECTED;
 const STATE_READONLY = nsIAccessibleStates.STATE_READONLY;
 const STATE_REQUIRED = nsIAccessibleStates.STATE_REQUIRED;
 const STATE_SELECTABLE = nsIAccessibleStates.STATE_SELECTABLE;
 const STATE_SELECTED = nsIAccessibleStates.STATE_SELECTED;
 const STATE_TRAVERSED = nsIAccessibleStates.STATE_TRAVERSED;
 const STATE_UNAVAILABLE = nsIAccessibleStates.STATE_UNAVAILABLE;
 
 const EXT_STATE_ACTIVE = nsIAccessibleStates.EXT_STATE_ACTIVE;
--- a/accessible/tests/mochitest/states/Makefile.in
+++ b/accessible/tests/mochitest/states/Makefile.in
@@ -51,16 +51,17 @@ include $(topsrcdir)/config/rules.mk
 		test_doc.html \
 		test_docarticle.html \
 		test_editablebody.html \
 		test_frames.html \
 		test_inputs.html \
 		test_inputs.xul \
 		test_link.html \
 		test_popup.xul \
+		test_textbox.xul \
 		test_tree.xul \
 		z_frames.html \
 		z_frames_article.html \
 		z_frames_checkbox.html \
 		z_frames_textbox.html \
 		z_frames_update.html \
 		$(NULL)
 
--- a/accessible/tests/mochitest/states/test_inputs.html
+++ b/accessible/tests/mochitest/states/test_inputs.html
@@ -126,17 +126,17 @@
   </form>
 
   <!-- bogus required usage -->
   <input id="submit" type="submit" required>
   <input id="button" type="button" required>
   <input id="reset" type="reset" required>
   <input id="image" type="image" required>
 
-  <!-- disabled -->
+  <!-- inherited disabled -->
   <fieldset id="f" disabled>
     <input id="f_input">
     <input id="f_input_disabled" disabled>
   </fieldset>
 
   <!-- invalid/valid -->
   <input id="maxlength" maxlength="1">
   <input id="maxlength2" maxlength="100" value="foo">
copy from accessible/tests/mochitest/test_textboxes.xul
copy to accessible/tests/mochitest/states/test_textbox.xul
--- a/accessible/tests/mochitest/test_textboxes.xul
+++ b/accessible/tests/mochitest/states/test_textbox.xul
@@ -1,252 +1,132 @@
 <?xml version="1.0"?>
 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
 <?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
                  type="text/css"?>
 
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-        title="nsIAccessible XUL textboxes chrome tests">
+        title="nsIAccessible XUL textboxes states tests">
 
   <script type="application/javascript" 
           src="chrome://mochikit/content/MochiKit/packed.js"></script>
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
 
   <script type="application/javascript"
-          src="common.js" />
-  <script type="application/javascript"
-          src="role.js" />
+          src="../common.js" />
   <script type="application/javascript"
-          src="states.js" />
-
+          src="../role.js" />
   <script type="application/javascript"
-          src="testTextboxes.js" />
+          src="../states.js" />
 
   <script type="application/javascript">
   <![CDATA[
     function doTest()
     {
       //////////////////////////////////////////////////////////////////////////
-      // normal textbox without content and with no proper label
-      testThis("unlabelled_Textbox", // ID
-               null, // name
-               "", // value
-               "", // description
-               ROLE_ENTRY, // role
-               (STATE_FOCUSABLE), // state
-               (EXT_STATE_EDITABLE), // extState
-               (STATE_READONLY), // absentState
-               1, // numActions
-               "activate",  // ActionName
-               "Activate"); // ActionDescription
+      // Ordinary textbox
+      testStates("textbox",
+                 STATE_FOCUSABLE, EXT_STATE_EDITABLE,
+                 STATE_PROTECTED | STATE_UNAVAILABLE, EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+                 "ordinary textbox");
 
       //////////////////////////////////////////////////////////////////////////
-      // normal textbox without content and with a proper label
-      testThis("labelled_textbox", // ID
-               "Second textbox:", // name
-               "", // value
-               "", // description
-               ROLE_ENTRY, // role
-               (STATE_FOCUSABLE), // state
-               (EXT_STATE_EDITABLE), // extState
-               (STATE_READONLY), // absentState
-               1, // numActions
-               "activate",  // ActionName
-               "Activate"); // ActionDescription
+      // Password textbox
+      testStates("password",
+                 STATE_FOCUSABLE | STATE_PROTECTED, EXT_STATE_EDITABLE,
+                 STATE_UNAVAILABLE, EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+                 "password textbox");
 
       //////////////////////////////////////////////////////////////////////////
-      // normal textbox with content and with a proper label
-      testThis("prefilled_textbox", // ID
-               "Textbox with predefined value:", // name
-               "I have some text", // value
-               "", // description
-               ROLE_ENTRY, // role
-               (STATE_FOCUSABLE), // state
-               (EXT_STATE_EDITABLE), // extState
-               (STATE_READONLY), // absentState
-               1, // numActions
-               "activate",  // ActionName
-               "Activate"); // ActionDescription
-
-      //////////////////////////////////////////////////////////////////////////
-      // password textbox with a proper label
-      testThis("password_textbox", // ID
-               "Enter some password here:", // name
-               "", // value
-               "", // description
-               ROLE_PASSWORD_TEXT, // role
-               (STATE_FOCUSABLE), // state
-               (EXT_STATE_EDITABLE), // extState
-               (STATE_READONLY), // absentState
-               1, // numActions
-               "activate",  // ActionName
-               "Activate"); // ActionDescription
+      // Textarea
+      testStates("textarea",
+                 STATE_FOCUSABLE, EXT_STATE_EDITABLE | EXT_STATE_MULTI_LINE,
+                 STATE_PROTECTED | STATE_UNAVAILABLE, EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+                 "multiline textbox");
 
       //////////////////////////////////////////////////////////////////////////
-      // textarea without content and label
-      testThis("unlabelled_Textarea", // ID
-               null, // name
-               "", // value
-               "", // description
-               ROLE_ENTRY, // role
-               (STATE_FOCUSABLE), // state
-               (EXT_STATE_EDITABLE | EXT_STATE_MULTI_LINE), // extState
-               (STATE_READONLY), // absentState
-               1, // numActions
-               "activate",  // ActionName
-               "Activate"); // ActionDescription
-
-      //////////////////////////////////////////////////////////////////////////
-      // textarea without content and with proper label
-      testThis("labelled_textarea", // ID
-               "Labelled textarea:", // name
-               "", // value
-               "", // description
-               ROLE_ENTRY, // role
-               (STATE_FOCUSABLE), // state
-               (EXT_STATE_EDITABLE | EXT_STATE_MULTI_LINE), // extState
-               (STATE_READONLY), // absentState
-               1, // numActions
-               "activate",  // ActionName
-               "Activate"); // ActionDescription
+      // Readonly textbox
+      testStates("readonly_textbox",
+                 STATE_FOCUSABLE | STATE_READONLY, 0,
+                 STATE_PROTECTED | STATE_UNAVAILABLE, EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+                 "readonly textbox");
 
       //////////////////////////////////////////////////////////////////////////
-      // textarea with content and with proper label
-      testThis("prefilled_textarea", // ID
-               "Pre-filled textarea:", // name
-               "I also have some text.", // value
-               "", // description
-               ROLE_ENTRY, // role
-               (STATE_FOCUSABLE), // state
-               (EXT_STATE_EDITABLE | EXT_STATE_MULTI_LINE), // extState
-               (STATE_READONLY), // absentState
-               1, // numActions
-               "activate",  // ActionName
-               "Activate"); // ActionDescription
+      // Disabled textbox
+      testStates("disabled_textbox",
+                 STATE_UNAVAILABLE, 0,
+                 STATE_FOCUSABLE | STATE_PROTECTED, EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+                 "readonly textbox");
 
       //////////////////////////////////////////////////////////////////////////
-      // readonly textbox with content and with proper label
-      testThis("readonly_textbox", // ID
-               "The following is a read-only textbox:", // name
-               "You cannot change me.", // value
-               "", // description
-               ROLE_ENTRY, // role
-               (STATE_FOCUSABLE | STATE_READONLY), // state
-               (0), // extState
-               (0), // absentState
-               1, // numActions
-               "activate",  // ActionName
-               "Activate"); // ActionDescription
+      // Readonly textarea
+      testStates("readonly_textarea",
+                 STATE_FOCUSABLE | STATE_READONLY, EXT_STATE_MULTI_LINE,
+                 STATE_PROTECTED | STATE_UNAVAILABLE, EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+                 "readonly multiline textbox");
 
       //////////////////////////////////////////////////////////////////////////
-      // readonly textarea with content and with proper label
-      testThis("readonly_textarea", // ID
-               "This textarea is readonly, too:", // name
-               "You cannot change me, either.", // value
-               "", // description
-               ROLE_ENTRY, // role
-               (STATE_FOCUSABLE | STATE_READONLY), // state
-               (EXT_STATE_MULTI_LINE), // extState
-               (0), // absentState
-               1, // numActions
-               "activate",  // ActionName
-               "Activate"); // ActionDescription
+      // Disabled textarea
+      testStates("disabled_textarea",
+                 STATE_UNAVAILABLE, EXT_STATE_MULTI_LINE,
+                 STATE_PROTECTED | STATE_FOCUSABLE, EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+                 "readonly multiline textbox");
 
       //////////////////////////////////////////////////////////////////////////
       // Search textbox without search button, searches as you type and filters
       // a separate control.
-      testThis("search-box", // ID
-               "Search History:", // name
-               "", // value
-               "", // description
-               ROLE_ENTRY, // role
-               (STATE_FOCUSABLE), // state
-               (EXT_STATE_SUPPORTS_AUTOCOMPLETION), // extState
-               (0), // absentState
-               1, // numActions
-               "activate",  // ActionName
-               "Activate"); // ActionDescription
+      testStates("searchbox",
+                 STATE_FOCUSABLE, EXT_STATE_EDITABLE | EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+                 STATE_PROTECTED | STATE_UNAVAILABLE, 0,
+                 "searchbox");
 
       //////////////////////////////////////////////////////////////////////////
       // Search textbox with search button, does not support autoCompletion.
-      testThis("searchfield", // ID
-               "Search all add-ons", // name
-               "", // value
-               "", // description
-               ROLE_ENTRY, // role
-               (STATE_FOCUSABLE), // state
-               (0), // extState
-               (0), // absentState
-               1, // numActions
-               "activate",  // ActionName
-               "Activate"); // ActionDescription
-      testStates("searchfield", 0, 0, 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
+      testStates("searchfield",
+                 STATE_FOCUSABLE, EXT_STATE_EDITABLE,
+                 STATE_PROTECTED | STATE_UNAVAILABLE, EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+                 "searchfield");
 
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   ]]>
   </script>
 
+  <hbox flex="1" style="overflow: auto;">
+
   <body xmlns="http://www.w3.org/1999/xhtml">
     <a target="_blank"
        href="https://bugzilla.mozilla.org/show_bug.cgi?id=442648">
       Mozilla Bug 442648
     </a>
+    <a target="_blank"
+       href="https://bugzilla.mozilla.org/show_bug.cgi?id=648235"
+       title="XUL textbox can inherit more states from underlying HTML input">
+      Mozilla Bug 648235
+    </a>
     <p id="display"></p>
     <div id="content" style="display: none"></div>
     <pre id="test">
     </pre>
   </body>
 
-  <vbox>
-    <hbox>
-      <label value="Text before input without labelling it:"/>
-      <textbox id="unlabelled_Textbox" size="50"/>
-    </hbox>
-    <hbox>
-      <label control="labelled_textbox">Second textbox:</label>
-      <textbox id="labelled_textbox"/>
-    </hbox>
-    <hbox>
-      <label control="prefilled_textbox">Textbox with predefined value:</label>
-      <textbox id="prefilled_textbox" value="I have some text" size="80"/>
-    </hbox>
-    <hbox>
-      <label control="password_textbox">Enter some password here:</label>
-      <textbox type="password" id="password_textbox"/>
-    </hbox>
-    <vbox>
-      <label value="Textarea without label:"/>
-      <textbox multiline="true" id="unlabelled_Textarea" cols="80" rows="5"/>
-    </vbox>
-    <vbox>
-      <label control="labelled_textarea">Labelled textarea:</label>
-      <textbox multiline="true" id="labelled_textarea" cols="80" rows="5"/>
-    </vbox>
-    <vbox>
-      <label control="prefilled_textarea">Pre-filled textarea:</label>
-      <textbox multiline="true" id="prefilled_textarea" cols="80" rows="5"
-               value="I also have some text."/>
-    </vbox>
-    <hbox>
-      <label control="readonly_textbox">The following is a read-only textbox:</label>
-      <textbox readonly="true" id="readonly_textbox"
-               value="You cannot change me."/>
-    </hbox>
-    <vbox>
-      <label control="readonly_textarea">This textarea is readonly, too:</label>
-      <textbox multiline="true" id="readonly_textarea" readonly="true" cols="80"
-               rows="5" value="You cannot change me, either."/>
-    </vbox>
-    <hbox>
-      <label value="Search History:" accesskey="S" 
-             control="search-box"/>
-	  <textbox id="search-box" flex="1" type="search"
-	           results="historyTree"/>
-    </hbox>
+  <vbox flex="1">
+    <textbox id="textbox"/>
+    <textbox id="password" type="password"/>
+    <textbox id="textarea" multiline="true" cols="80" rows="5"/>
+
+    <textbox id="readonly_textbox" readonly="true"/>
+    <textbox id="disabled_textbox" disabled="true"/>
+    <textbox id="readonly_textarea" multiline="true" readonly="true"
+             cols="80" rows="5"/>
+    <textbox id="disabled_textarea" multiline="true" disabled="true"
+             cols="80" rows="5"/>
+
+    <textbox id="searchbox" flex="1" type="search" results="historyTree"/>
     <textbox id="searchfield" placeholder="Search all add-ons"
              type="search" searchbutton="true"/>
   </vbox>
+  </hbox>
 </window>