Bug 445510 - Support ARIA-based text attributes, r=tbsaunde
authorAlexander Surkov <surkov.alexander@gmail.com>
Sat, 09 Feb 2013 13:36:34 +0900
changeset 121430 b27ce57600632a018de7a0d5432fa6bde555221b
parent 121429 57aed25c64eb6844e4a9cca7f72d87e13274b805
child 121431 0d1a3f041a8fcac54307c4f033a58eb4387d3d71
push id24284
push userryanvm@gmail.com
push dateSat, 09 Feb 2013 15:43:50 +0000
treeherdermozilla-central@08388ff940df [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstbsaunde
bugs445510
milestone21.0a1
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 445510 - Support ARIA-based text attributes, r=tbsaunde
accessible/src/base/TextAttrs.cpp
accessible/src/base/TextAttrs.h
accessible/tests/mochitest/Makefile.in
accessible/tests/mochitest/attributes/Makefile.in
accessible/tests/mochitest/attributes/test_text.html
accessible/tests/mochitest/textattrs/Makefile.in
accessible/tests/mochitest/textattrs/test_general.html
accessible/tests/mochitest/textattrs/test_invalid.html
content/base/src/nsGkAtomList.h
--- a/accessible/src/base/TextAttrs.cpp
+++ b/accessible/src/base/TextAttrs.cpp
@@ -78,16 +78,19 @@ TextAttrsMgr::GetAttributes(nsIPersisten
     offsetNode = mOffsetAcc->GetContent();
     offsetElm = nsCoreUtils::GetDOMElementFor(offsetNode);
     frame = offsetElm->GetPrimaryFrame();
   }
 
   // "language" text attribute
   LangTextAttr langTextAttr(mHyperTextAcc, hyperTextElm, offsetNode);
 
+  // "aria-invalid" text attribute
+  InvalidTextAttr invalidTextAttr(hyperTextElm, offsetNode);
+
   // "background-color" text attribute
   BGColorTextAttr bgColorTextAttr(rootFrame, frame);
 
   // "color" text attribute
   ColorTextAttr colorTextAttr(rootFrame, frame);
 
   // "font-family" text attribute
   FontFamilyTextAttr fontFamilyTextAttr(rootFrame, frame);
@@ -108,16 +111,17 @@ TextAttrsMgr::GetAttributes(nsIPersisten
   TextDecorTextAttr textDecorTextAttr(rootFrame, frame);
 
   // "text-position" text attribute
   TextPosTextAttr textPosTextAttr(rootFrame, frame);
 
   TextAttr* attrArray[] =
   {
     &langTextAttr,
+    &invalidTextAttr,
     &bgColorTextAttr,
     &colorTextAttr,
     &fontFamilyTextAttr,
     &fontSizeTextAttr,
     &fontStyleTextAttr,
     &fontWeightTextAttr,
     &autoGenTextAttr,
     &textDecorTextAttr,
@@ -221,16 +225,98 @@ TextAttrsMgr::LangTextAttr::
 
 void
 TextAttrsMgr::LangTextAttr::
   ExposeValue(nsIPersistentProperties* aAttributes, const nsString& aValue)
 {
   nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::language, aValue);
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// InvalidTextAttr
+////////////////////////////////////////////////////////////////////////////////
+
+TextAttrsMgr::InvalidTextAttr::
+  InvalidTextAttr(nsIContent* aRootElm, nsIContent* aElm) :
+  TTextAttr<uint32_t>(!aElm), mRootElm(aRootElm)
+{
+  mIsRootDefined = GetValue(mRootElm, &mRootNativeValue);
+  if (aElm)
+    mIsDefined = GetValue(aElm, &mNativeValue);
+}
+
+bool
+TextAttrsMgr::InvalidTextAttr::
+  GetValueFor(Accessible* aAccessible, uint32_t* aValue)
+{
+  nsIContent* elm = nsCoreUtils::GetDOMElementFor(aAccessible->GetContent());
+  return elm ? GetValue(elm, aValue) : false;
+}
+
+void
+TextAttrsMgr::InvalidTextAttr::
+  ExposeValue(nsIPersistentProperties* aAttributes, const uint32_t& aValue)
+{
+  switch (aValue) {
+    case eFalse:
+      nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::invalid,
+                             NS_LITERAL_STRING("false"));
+      break;
+
+    case eGrammar:
+      nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::invalid,
+                             NS_LITERAL_STRING("grammar"));
+      break;
+
+    case eSpelling:
+      nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::invalid,
+                             NS_LITERAL_STRING("spelling"));
+      break;
+
+    case eTrue:
+      nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::invalid,
+                             NS_LITERAL_STRING("true"));
+      break;
+  }
+}
+
+bool
+TextAttrsMgr::InvalidTextAttr::
+  GetValue(nsIContent* aElm, uint32_t* aValue)
+{
+  nsIContent* elm = aElm;
+  do {
+    if (nsAccUtils::HasDefinedARIAToken(elm, nsGkAtoms::aria_invalid)) {
+      static nsIContent::AttrValuesArray tokens[] =
+        { &nsGkAtoms::_false, &nsGkAtoms::grammar, &nsGkAtoms::spelling,
+          nullptr };
+
+      int32_t idx = elm->FindAttrValueIn(kNameSpaceID_None,
+                                         nsGkAtoms::aria_invalid, tokens,
+                                         eCaseMatters);
+      switch (idx) {
+        case 0:
+          *aValue = eFalse;
+          return true;
+        case 1:
+          *aValue = eGrammar;
+          return true;
+        case 2:
+          *aValue = eSpelling;
+          return true;
+        default:
+          *aValue = eTrue;
+          return true;
+      }
+    }
+  } while ((elm = elm->GetParent()) && elm != mRootElm);
+
+  return false;
+}
+
 
 ////////////////////////////////////////////////////////////////////////////////
 // BGColorTextAttr
 ////////////////////////////////////////////////////////////////////////////////
 
 TextAttrsMgr::BGColorTextAttr::
   BGColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
   TTextAttr<nscolor>(!aFrame), mRootFrame(aRootFrame)
--- a/accessible/src/base/TextAttrs.h
+++ b/accessible/src/base/TextAttrs.h
@@ -208,16 +208,48 @@ protected:
                              const nsString& aValue);
 
   private:
     nsCOMPtr<nsIContent> mRootContent;
   };
 
 
   /**
+   * Class is used for the 'invalid' text attribute. Note, it calculated
+   * the attribute from aria-invalid attribute only; invalid:spelling attribute
+   * calculated from misspelled text in the editor is managed by
+   * HyperTextAccessible and applied on top of the value from aria-invalid.
+   */
+  class InvalidTextAttr : public TTextAttr<uint32_t>
+  {
+  public:
+    InvalidTextAttr(nsIContent* aRootElm, nsIContent* aElm);
+    virtual ~InvalidTextAttr() { };
+
+  protected:
+
+    enum {
+      eFalse,
+      eGrammar,
+      eSpelling,
+      eTrue
+    };
+
+    // TextAttr
+    virtual bool GetValueFor(Accessible* aAccessible, uint32_t* aValue);
+    virtual void ExposeValue(nsIPersistentProperties* aAttributes,
+                             const uint32_t& aValue);
+
+  private:
+    bool GetValue(nsIContent* aElm, uint32_t* aValue);
+    nsIContent* mRootElm;
+  };
+
+
+  /**
    * Class is used for the work with 'background-color' text attribute.
    */
   class BGColorTextAttr : public TTextAttr<nscolor>
   {
   public:
     BGColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
     virtual ~BGColorTextAttr() { }
 
--- a/accessible/tests/mochitest/Makefile.in
+++ b/accessible/tests/mochitest/Makefile.in
@@ -24,16 +24,17 @@ DIRS	= \
   pivot \
   relations \
   role \
   scroll \
   selectable \
   states \
   table \
   text \
+  textattrs \
   textcaret \
   textselection \
   tree \
   treeupdate \
   value \
   $(null)
 
 include $(DEPTH)/config/autoconf.mk
--- a/accessible/tests/mochitest/attributes/Makefile.in
+++ b/accessible/tests/mochitest/attributes/Makefile.in
@@ -14,13 +14,12 @@ include $(DEPTH)/config/autoconf.mk
 MOCHITEST_A11Y_FILES =\
 		test_obj.html \
 		test_obj_css.html \
 		test_obj_css.xul \
 		test_obj_group.html \
 		test_obj_group.xul \
 		test_obj_group_tree.xul \
 		test_tag.html \
-		test_text.html \
 		test_xml-roles.html \
 		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/textattrs/Makefile.in
@@ -0,0 +1,19 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DEPTH		= @DEPTH@
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+relativesrcdir  = accessible/textattrs
+
+include $(DEPTH)/config/autoconf.mk
+
+MOCHITEST_A11Y_FILES =\
+		test_general.html \
+		test_invalid.html \
+		$(NULL)
+
+include $(topsrcdir)/config/rules.mk
rename from accessible/tests/mochitest/attributes/test_text.html
rename to accessible/tests/mochitest/textattrs/test_general.html
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/textattrs/test_invalid.html
@@ -0,0 +1,62 @@
+<html>
+
+<head>
+  <title>Invalid text attribute</title>
+
+  <link rel="stylesheet" type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+
+  <script type="application/javascript"
+          src="../common.js"></script>
+  <script type="application/javascript"
+          src="../role.js"></script>
+  <script type="application/javascript"
+          src="../states.js"></script>
+  <script type="application/javascript"
+          src="../events.js"></script>
+  <script type="application/javascript"
+          src="../attributes.js"></script>
+
+  <script type="application/javascript">
+    function doTests()
+    {
+      testDefaultTextAttrs("aria_invalid_empty", {}, true);
+      testDefaultTextAttrs("aria_invalid_true", { "invalid": "true" }, true);
+      testDefaultTextAttrs("aria_invalid_false", { "invalid": "false" }, true);
+      testDefaultTextAttrs("aria_invalid_grammar", { "invalid": "grammar" }, true);
+      testDefaultTextAttrs("aria_invalid_spelling", { "invalid": "spelling" }, true);
+      testDefaultTextAttrs("aria_invalid_erroneous", { "invalid": "true" }, true);
+
+      SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTests);
+  </script>
+</head>
+
+<body>
+
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=445510"
+     title="Support ARIA-based text attributes">
+    Mozilla Bug 445510
+  </a>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+
+  <div id="aria_invalid_empty" aria-invalid="">no invalid</div>
+  <div id="aria_invalid_true" aria-invalid="true">invalid:true</div>
+  <div id="aria_invalid_false" aria-invalid="false">invalid:false</div>
+  <div id="aria_invalid_grammar" aria-invalid="grammar">invalid:grammar</div>
+  <div id="aria_invalid_spelling" aria-invalid="spelling">invalid:spelling</div>
+  <div id="aria_invalid_erroneous" aria-invalid="erroneous">invalid:true</div>
+</body>
+</html>
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -2095,16 +2095,17 @@ GK_ATOM(containerBusy, "container-busy")
 GK_ATOM(containerLive, "container-live")
 GK_ATOM(containerLiveRole, "container-live-role")
 GK_ATOM(containerRelevant, "container-relevant")
 GK_ATOM(cycles, "cycles")
 GK_ATOM(datatable, "datatable")
 GK_ATOM(directory, "directory")
 GK_ATOM(droppable, "droppable")
 GK_ATOM(eventFromInput, "event-from-input")
+GK_ATOM(grammar, "grammar")
 GK_ATOM(gridcell, "gridcell")
 GK_ATOM(heading, "heading")
 GK_ATOM(InlineBlockFrame, "InlineBlockFrame")
 GK_ATOM(inlinevalue, "inline")
 GK_ATOM(invalid, "invalid")
 GK_ATOM(item, "item")
 GK_ATOM(itemset, "itemset")
 GK_ATOM(lineNumber, "line-number")
@@ -2122,16 +2123,17 @@ GK_ATOM(password, "password")
 GK_ATOM(posinset, "posinset")
 GK_ATOM(presentation, "presentation")
 GK_ATOM(progressbar, "progressbar")
 GK_ATOM(region, "region")
 GK_ATOM(rowgroup, "rowgroup")
 GK_ATOM(rowheader, "rowheader")
 GK_ATOM(select1, "select1")
 GK_ATOM(setsize, "setsize")
+GK_ATOM(spelling, "spelling")
 GK_ATOM(spinbutton, "spinbutton")
 GK_ATOM(status, "status")
 GK_ATOM(tableCellIndex, "table-cell-index")
 GK_ATOM(tablist, "tablist")
 GK_ATOM(textAlign, "text-align")
 GK_ATOM(textIndent, "text-indent")
 GK_ATOM(textLineThroughColor, "text-line-through-color")
 GK_ATOM(textLineThroughStyle, "text-line-through-style")