Bug 445516 - Support for auto-generated=true text attribute on list bullets, r=tbsaunde
authorAndrew Quartey <andrew.quartey@gmail.com>
Thu, 07 Jun 2012 21:49:21 +0900
changeset 96067 4e45f4a0da3ad464f2d6b88abc7e616b0c8bc54e
parent 96066 c3a3ef4f4f2e45e481c4dcb0d131be045e027847
child 96068 bef0c6b570a272c17154ea5f203726fdfc318380
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerstbsaunde
bugs445516
milestone16.0a1
Bug 445516 - Support for auto-generated=true text attribute on list bullets, r=tbsaunde
accessible/src/base/TextAttrs.cpp
accessible/src/base/TextAttrs.h
accessible/src/generic/TextLeafAccessible.cpp
accessible/src/generic/TextLeafAccessible.h
accessible/tests/mochitest/attributes/test_text.html
content/base/src/nsGkAtomList.h
--- a/accessible/src/base/TextAttrs.cpp
+++ b/accessible/src/base/TextAttrs.cpp
@@ -96,31 +96,35 @@ TextAttrsMgr::GetAttributes(nsIPersisten
   FontSizeTextAttr fontSizeTextAttr(rootFrame, frame);
 
   // "font-style" text attribute
   FontStyleTextAttr fontStyleTextAttr(rootFrame, frame);
 
   // "font-weight" text attribute
   FontWeightTextAttr fontWeightTextAttr(rootFrame, frame);
 
+  // "auto-generated" text attribute
+  AutoGeneratedTextAttr autoGenTextAttr(mHyperTextAcc, mOffsetAcc);
+
   // "text-underline(line-through)-style(color)" text attributes
   TextDecorTextAttr textDecorTextAttr(rootFrame, frame);
 
   // "text-position" text attribute
   TextPosTextAttr textPosTextAttr(rootFrame, frame);
 
   TextAttr* attrArray[] =
   {
     &langTextAttr,
     &bgColorTextAttr,
     &colorTextAttr,
     &fontFamilyTextAttr,
     &fontSizeTextAttr,
     &fontStyleTextAttr,
     &fontWeightTextAttr,
+    &autoGenTextAttr,
     &textDecorTextAttr,
     &textPosTextAttr
   };
 
   // Expose text attributes if applicable.
   if (aAttributes) {
     for (PRUint32 idx = 0; idx < ArrayLength(attrArray); idx++)
       attrArray[idx]->Expose(aAttributes, mIncludeDefAttrs);
@@ -139,24 +143,20 @@ TextAttrsMgr::GetRange(TextAttr* aAttrAr
   for (PRInt32 childIdx = mOffsetAccIdx - 1; childIdx >= 0; childIdx--) {
     Accessible* currAcc = mHyperTextAcc->GetChildAt(childIdx);
 
     // Stop on embedded accessible since embedded accessibles are combined into
     // own range.
     if (nsAccUtils::IsEmbeddedObject(currAcc))
       break;
 
-    nsIContent* currElm = nsCoreUtils::GetDOMElementFor(currAcc->GetContent());
-    if (!currElm)
-      return;
-
     bool offsetFound = false;
     for (PRUint32 attrIdx = 0; attrIdx < aAttrArrayLen; attrIdx++) {
       TextAttr* textAttr = aAttrArray[attrIdx];
-      if (!textAttr->Equal(currElm)) {
+      if (!textAttr->Equal(currAcc)) {
         offsetFound = true;
         break;
       }
     }
 
     if (offsetFound)
       break;
 
@@ -165,27 +165,23 @@ TextAttrsMgr::GetRange(TextAttr* aAttrAr
 
   // Navigate forward from anchor accessible to find end offset.
   PRUint32 childLen = mHyperTextAcc->ChildCount();
   for (PRUint32 childIdx = mOffsetAccIdx + 1; childIdx < childLen; childIdx++) {
     Accessible* currAcc = mHyperTextAcc->GetChildAt(childIdx);
     if (nsAccUtils::IsEmbeddedObject(currAcc))
       break;
 
-    nsIContent* currElm = nsCoreUtils::GetDOMElementFor(currAcc->GetContent());
-    if (!currElm)
-      return;
-
     bool offsetFound = false;
     for (PRUint32 attrIdx = 0; attrIdx < aAttrArrayLen; attrIdx++) {
       TextAttr* textAttr = aAttrArray[attrIdx];
 
       // Alter the end offset when text attribute changes its value and stop
       // the search.
-      if (!textAttr->Equal(currElm)) {
+      if (!textAttr->Equal(currAcc)) {
         offsetFound = true;
         break;
       }
     }
 
     if (offsetFound)
       break;
 
@@ -201,61 +197,57 @@ TextAttrsMgr::GetRange(TextAttr* aAttrAr
 TextAttrsMgr::LangTextAttr::
   LangTextAttr(HyperTextAccessible* aRoot,
                nsIContent* aRootElm, nsIContent* aElm) :
   TTextAttr<nsString>(!aElm), mRootContent(aRootElm)
 {
   aRoot->Language(mRootNativeValue);
   mIsRootDefined =  !mRootNativeValue.IsEmpty();
 
-  if (aElm)
-    mIsDefined = GetLang(aElm, mNativeValue);
+  if (aElm) {
+    nsCoreUtils::GetLanguageFor(aElm, mRootContent, mNativeValue);
+    mIsDefined = !mNativeValue.IsEmpty();
+  }
 }
 
 bool
 TextAttrsMgr::LangTextAttr::
-  GetValueFor(nsIContent* aElm, nsString* aValue)
+  GetValueFor(Accessible* aAccessible, nsString* aValue)
 {
-  return GetLang(aElm, *aValue);
+  nsCoreUtils::GetLanguageFor(aAccessible->GetContent(), mRootContent, *aValue);
+  return !aValue->IsEmpty();
 }
 
 void
 TextAttrsMgr::LangTextAttr::
   ExposeValue(nsIPersistentProperties* aAttributes, const nsString& aValue)
 {
   nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::language, aValue);
 }
 
-bool
-TextAttrsMgr::LangTextAttr::
-  GetLang(nsIContent* aElm, nsAString& aLang)
-{
-  nsCoreUtils::GetLanguageFor(aElm, mRootContent, aLang);
-  return !aLang.IsEmpty();
-}
-
 
 ////////////////////////////////////////////////////////////////////////////////
 // BGColorTextAttr
 ////////////////////////////////////////////////////////////////////////////////
 
 TextAttrsMgr::BGColorTextAttr::
   BGColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
   TTextAttr<nscolor>(!aFrame), mRootFrame(aRootFrame)
 {
   mIsRootDefined = GetColor(mRootFrame, &mRootNativeValue);
   if (aFrame)
     mIsDefined = GetColor(aFrame, &mNativeValue);
 }
 
 bool
 TextAttrsMgr::BGColorTextAttr::
-  GetValueFor(nsIContent* aElm, nscolor* aValue)
+  GetValueFor(Accessible* aAccessible, nscolor* aValue)
 {
-  nsIFrame* frame = aElm->GetPrimaryFrame();
+  nsIContent* elm = nsCoreUtils::GetDOMElementFor(aAccessible->GetContent());
+  nsIFrame* frame = elm->GetPrimaryFrame();
   return frame ? GetColor(frame, aValue) : false;
 }
 
 void
 TextAttrsMgr::BGColorTextAttr::
   ExposeValue(nsIPersistentProperties* aAttributes, const nscolor& aValue)
 {
   nsAutoString formattedValue;
@@ -305,19 +297,20 @@ TextAttrsMgr::ColorTextAttr::
   if (aFrame) {
     mNativeValue = aFrame->GetStyleColor()->mColor;
     mIsDefined = true;
   }
 }
 
 bool
 TextAttrsMgr::ColorTextAttr::
-  GetValueFor(nsIContent* aElm, nscolor* aValue)
+  GetValueFor(Accessible* aAccessible, nscolor* aValue)
 {
-  nsIFrame* frame = aElm->GetPrimaryFrame();
+  nsIContent* elm = nsCoreUtils::GetDOMElementFor(aAccessible->GetContent());
+  nsIFrame* frame = elm->GetPrimaryFrame();
   if (frame) {
     *aValue = frame->GetStyleColor()->mColor;
     return true;
   }
 
   return false;
 }
 
@@ -342,19 +335,20 @@ TextAttrsMgr::FontFamilyTextAttr::
   mIsRootDefined = GetFontFamily(aRootFrame, mRootNativeValue);
 
   if (aFrame)
     mIsDefined = GetFontFamily(aFrame, mNativeValue);
 }
 
 bool
 TextAttrsMgr::FontFamilyTextAttr::
-  GetValueFor(nsIContent* aElm, nsString* aValue)
+  GetValueFor(Accessible* aAccessible, nsString* aValue)
 {
-  nsIFrame* frame = aElm->GetPrimaryFrame();
+  nsIContent* elm = nsCoreUtils::GetDOMElementFor(aAccessible->GetContent());
+  nsIFrame* frame = elm->GetPrimaryFrame();
   return frame ? GetFontFamily(frame, *aValue) : false;
 }
 
 void
 TextAttrsMgr::FontFamilyTextAttr::
   ExposeValue(nsIPersistentProperties* aAttributes, const nsString& aValue)
 {
   nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::font_family, aValue);
@@ -391,19 +385,20 @@ TextAttrsMgr::FontSizeTextAttr::
   if (aFrame) {
     mNativeValue = aFrame->GetStyleFont()->mSize;
     mIsDefined = true;
   }
 }
 
 bool
 TextAttrsMgr::FontSizeTextAttr::
-  GetValueFor(nsIContent* aElm, nscoord* aValue)
+  GetValueFor(Accessible* aAccessible, nscoord* aValue)
 {
-  nsIFrame* frame = aElm->GetPrimaryFrame();
+  nsIContent* content = nsCoreUtils::GetDOMElementFor(aAccessible->GetContent());
+  nsIFrame* frame = content->GetPrimaryFrame();
   if (frame) {
     *aValue = frame->GetStyleFont()->mSize;
     return true;
   }
 
   return false;
 }
 
@@ -446,19 +441,20 @@ TextAttrsMgr::FontStyleTextAttr::
   if (aFrame) {
     mNativeValue = aFrame->GetStyleFont()->mFont.style;
     mIsDefined = true;
   }
 }
 
 bool
 TextAttrsMgr::FontStyleTextAttr::
-  GetValueFor(nsIContent* aContent, nscoord* aValue)
+  GetValueFor(Accessible* aAccessible, nscoord* aValue)
 {
-  nsIFrame* frame = aContent->GetPrimaryFrame();
+  nsIContent* elm = nsCoreUtils::GetDOMElementFor(aAccessible->GetContent());
+  nsIFrame* frame = elm->GetPrimaryFrame();
   if (frame) {
     *aValue = frame->GetStyleFont()->mFont.style;
     return true;
   }
 
   return false;
 }
 
@@ -487,19 +483,20 @@ TextAttrsMgr::FontWeightTextAttr::
   if (aFrame) {
     mNativeValue = GetFontWeight(aFrame);
     mIsDefined = true;
   }
 }
 
 bool
 TextAttrsMgr::FontWeightTextAttr::
-  GetValueFor(nsIContent* aElm, PRInt32* aValue)
+  GetValueFor(Accessible* aAccessible, PRInt32* aValue)
 {
-  nsIFrame* frame = aElm->GetPrimaryFrame();
+  nsIContent* elm = nsCoreUtils::GetDOMElementFor(aAccessible->GetContent());
+  nsIFrame* frame = elm->GetPrimaryFrame();
   if (frame) {
     *aValue = GetFontWeight(frame);
     return true;
   }
 
   return false;
 }
 
@@ -545,16 +542,46 @@ TextAttrsMgr::FontWeightTextAttr::
   // On Mac, font->GetStyle()->weight will just give the same number as
   // getComputedStyle(). fontEntry->Weight() will give the weight of the font
   // face used.
   gfxFontEntry *fontEntry = font->GetFontEntry();
   return fontEntry->Weight();
 #endif
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// AutoGeneratedTextAttr
+////////////////////////////////////////////////////////////////////////////////
+TextAttrsMgr::AutoGeneratedTextAttr::
+  AutoGeneratedTextAttr(HyperTextAccessible* aHyperTextAcc,
+                        Accessible* aAccessible) :
+  TTextAttr<bool>(!aAccessible)
+{
+  mRootNativeValue = false;
+  mIsRootDefined = false;
+
+  if (aAccessible)
+    mIsDefined = mNativeValue = (aAccessible->NativeRole() == roles::STATICTEXT);
+}
+
+bool
+TextAttrsMgr::AutoGeneratedTextAttr::
+  GetValueFor(Accessible* aAccessible, bool* aValue)
+{
+  return *aValue = (aAccessible->NativeRole() == roles::STATICTEXT);
+}
+
+void
+TextAttrsMgr::AutoGeneratedTextAttr::
+  ExposeValue(nsIPersistentProperties* aAttributes, const bool& aValue)
+{
+  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::auto_generated,
+                         aValue ? NS_LITERAL_STRING("true") : NS_LITERAL_STRING("false"));
+}
+
 
 ////////////////////////////////////////////////////////////////////////////////
 // TextDecorTextAttr
 ////////////////////////////////////////////////////////////////////////////////
 
 TextAttrsMgr::TextDecorValue::
   TextDecorValue(nsIFrame* aFrame)
 {
@@ -581,19 +608,20 @@ TextAttrsMgr::TextDecorTextAttr::
   if (aFrame) {
     mNativeValue = TextDecorValue(aFrame);
     mIsDefined = mNativeValue.IsDefined();
   }
 }
 
 bool
 TextAttrsMgr::TextDecorTextAttr::
-  GetValueFor(nsIContent* aContent, TextDecorValue* aValue)
+  GetValueFor(Accessible* aAccessible, TextDecorValue* aValue)
 {
-  nsIFrame* frame = aContent->GetPrimaryFrame();
+  nsIContent* elm = nsCoreUtils::GetDOMElementFor(aAccessible->GetContent());
+  nsIFrame* frame = elm->GetPrimaryFrame();
   if (frame) {
     *aValue = TextDecorValue(frame);
     return aValue->IsDefined();
   }
 
   return false;
 }
 
@@ -643,19 +671,20 @@ TextAttrsMgr::TextPosTextAttr::
   if (aFrame) {
     mNativeValue = GetTextPosValue(aFrame);
     mIsDefined = mNativeValue != eTextPosNone;
   }
 }
 
 bool
 TextAttrsMgr::TextPosTextAttr::
-  GetValueFor(nsIContent* aContent, TextPosValue* aValue)
+  GetValueFor(Accessible* aAccessible, TextPosValue* aValue)
 {
-  nsIFrame* frame = aContent->GetPrimaryFrame();
+  nsIContent* elm = nsCoreUtils::GetDOMElementFor(aAccessible->GetContent());
+  nsIFrame* frame = elm->GetPrimaryFrame();
   if (frame) {
     *aValue = GetTextPosValue(frame);
     return *aValue != eTextPosNone;
   }
 
   return false;
 }
 
--- a/accessible/src/base/TextAttrs.h
+++ b/accessible/src/base/TextAttrs.h
@@ -105,17 +105,17 @@ protected:
      */
     virtual void Expose(nsIPersistentProperties* aAttributes,
                         bool aIncludeDefAttrValue) = 0;
 
     /**
      * Return true if the text attribute value on the given element equals with
      * predefined attribute value.
      */
-    virtual bool Equal(nsIContent* aElm) = 0;
+    virtual bool Equal(Accessible* aAccessible) = 0;
   };
 
 
   /**
    * Base class to work with text attributes. See derived classes below.
    */
   template<class T>
   class TTextAttr : public TextAttr
@@ -138,20 +138,20 @@ protected:
           ExposeValue(aAttributes, mNativeValue);
         return;
       }
 
       if (aIncludeDefAttrValue && mIsRootDefined)
         ExposeValue(aAttributes, mRootNativeValue);
     }
 
-    virtual bool Equal(nsIContent* aElm)
+    virtual bool Equal(Accessible* aAccessible)
     {
       T nativeValue;
-      bool isDefined = GetValueFor(aElm, &nativeValue);
+      bool isDefined = GetValueFor(aAccessible, &nativeValue);
 
       if (!mIsDefined && !isDefined)
         return true;
 
       if (mIsDefined && isDefined)
         return nativeValue == mNativeValue;
 
       if (mIsDefined)
@@ -162,17 +162,17 @@ protected:
 
   protected:
 
     // Expose the text attribute with the given value to attribute set.
     virtual void ExposeValue(nsIPersistentProperties* aAttributes,
                              const T& aValue) = 0;
 
     // Return native value for the given DOM element.
-    virtual bool GetValueFor(nsIContent* aElm, T* aValue) = 0;
+    virtual bool GetValueFor(Accessible* aAccessible, T* aValue) = 0;
 
     // Indicates if root value should be exposed.
     bool mGetRootValue;
 
     // Native value and flag indicating if the value is defined (initialized in
     // derived classes). Note, undefined native value means it is inherited
     // from root.
     T mNativeValue;
@@ -193,39 +193,38 @@ protected:
   public:
     LangTextAttr(HyperTextAccessible* aRoot, nsIContent* aRootElm,
                  nsIContent* aElm);
     virtual ~LangTextAttr() { }
 
   protected:
 
     // TextAttr
-    virtual bool GetValueFor(nsIContent* aElm, nsString* aValue);
+    virtual bool GetValueFor(Accessible* aAccessible, nsString* aValue);
     virtual void ExposeValue(nsIPersistentProperties* aAttributes,
                              const nsString& aValue);
 
   private:
-    bool GetLang(nsIContent* aElm, nsAString& aLang);
     nsCOMPtr<nsIContent> mRootContent;
   };
 
 
   /**
    * Class is used for the work with 'background-color' text attribute.
    */
   class BGColorTextAttr : public TTextAttr<nscolor>
   {
   public:
     BGColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
     virtual ~BGColorTextAttr() { }
 
   protected:
 
     // TextAttr
-    virtual bool GetValueFor(nsIContent* aElm, nscolor* aValue);
+    virtual bool GetValueFor(Accessible* aAccessible, nscolor* aValue);
     virtual void ExposeValue(nsIPersistentProperties* aAttributes,
                              const nscolor& aValue);
 
   private:
     bool GetColor(nsIFrame* aFrame, nscolor* aColor);
     nsIFrame* mRootFrame;
   };
 
@@ -237,17 +236,17 @@ protected:
   {
   public:
     ColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
     virtual ~ColorTextAttr() { }
 
   protected:
 
     // TTextAttr
-    virtual bool GetValueFor(nsIContent* aElm, nscolor* aValue);
+    virtual bool GetValueFor(Accessible* aAccessible, nscolor* aValue);
     virtual void ExposeValue(nsIPersistentProperties* aAttributes,
                              const nscolor& aValue);
   };
 
 
   /**
    * Class is used for the work with "font-family" text attribute.
    */
@@ -255,17 +254,17 @@ protected:
   {
   public:
     FontFamilyTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
     virtual ~FontFamilyTextAttr() { }
 
   protected:
 
     // TTextAttr
-    virtual bool GetValueFor(nsIContent* aElm, nsString* aValue);
+    virtual bool GetValueFor(Accessible* aAccessible, nsString* aValue);
     virtual void ExposeValue(nsIPersistentProperties* aAttributes,
                              const nsString& aValue);
 
   private:
 
     bool GetFontFamily(nsIFrame* aFrame, nsString& aFamily);
   };
 
@@ -274,20 +273,20 @@ protected:
    * Class is used for the work with "font-size" text attribute.
    */
   class FontSizeTextAttr : public TTextAttr<nscoord>
   {
   public:
     FontSizeTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
     virtual ~FontSizeTextAttr() { }
 
-  protected:
+  protected: 
 
     // TTextAttr
-    virtual bool GetValueFor(nsIContent* aElm, nscoord* aValue);
+    virtual bool GetValueFor(Accessible* aAccessible, nscoord* aValue);
     virtual void ExposeValue(nsIPersistentProperties* aAttributes,
                              const nscoord& aValue);
 
   private:
     nsDeviceContext* mDC;
   };
 
 
@@ -298,17 +297,17 @@ protected:
   {
   public:
     FontStyleTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
     virtual ~FontStyleTextAttr() { }
 
   protected:
 
     // TTextAttr
-    virtual bool GetValueFor(nsIContent* aContent, nscoord* aValue);
+    virtual bool GetValueFor(Accessible* aContent, nscoord* aValue);
     virtual void ExposeValue(nsIPersistentProperties* aAttributes,
                              const nscoord& aValue);
   };
 
 
   /**
    * Class is used for the work with "font-weight" text attribute.
    */
@@ -316,24 +315,41 @@ protected:
   {
   public:
     FontWeightTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
     virtual ~FontWeightTextAttr() { }
 
   protected:
 
     // TTextAttr
-    virtual bool GetValueFor(nsIContent* aElm, PRInt32* aValue);
+    virtual bool GetValueFor(Accessible* aAccessible, PRInt32* aValue);
     virtual void ExposeValue(nsIPersistentProperties* aAttributes,
                              const PRInt32& aValue);
 
   private:
     PRInt32 GetFontWeight(nsIFrame* aFrame);
   };
 
+  /**
+   * Class is used for the work with 'auto-generated' text attribute.
+   */
+  class AutoGeneratedTextAttr : public TTextAttr<bool>
+  {
+  public:
+    AutoGeneratedTextAttr(HyperTextAccessible* aHyperTextAcc,
+                          Accessible* aAccessible);
+    virtual ~AutoGeneratedTextAttr() { }
+
+  protected:
+    // TextAttr
+    virtual bool GetValueFor(Accessible* aAccessible, bool* aValue);
+    virtual void ExposeValue(nsIPersistentProperties* aAttributes,
+                             const bool& aValue);
+  };
+
 
   /**
    * TextDecorTextAttr class is used for the work with
    * "text-line-through-style", "text-line-through-color",
    * "text-underline-style" and "text-underline-color" text attributes.
    */
 
   class TextDecorValue
@@ -370,17 +386,17 @@ protected:
   {
   public:
     TextDecorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
     virtual ~TextDecorTextAttr() { }
 
   protected:
 
     // TextAttr
-    virtual bool GetValueFor(nsIContent* aElm, TextDecorValue* aValue);
+    virtual bool GetValueFor(Accessible* aAccessible, TextDecorValue* aValue);
     virtual void ExposeValue(nsIPersistentProperties* aAttributes,
                              const TextDecorValue& aValue);
   };
 
   /**
    * Class is used for the work with "text-position" text attribute.
    */
 
@@ -395,17 +411,17 @@ protected:
   {
   public:
     TextPosTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
     virtual ~TextPosTextAttr() { }
 
   protected:
 
     // TextAttr
-    virtual bool GetValueFor(nsIContent* aElm, TextPosValue* aValue);
+    virtual bool GetValueFor(Accessible* aAccessible, TextPosValue* aValue);
     virtual void ExposeValue(nsIPersistentProperties* aAttributes,
                              const TextPosValue& aValue);
 
   private:
     TextPosValue GetTextPosValue(nsIFrame* aFrame) const;
   };
 
 }; // TextAttrMgr
--- a/accessible/src/generic/TextLeafAccessible.cpp
+++ b/accessible/src/generic/TextLeafAccessible.cpp
@@ -46,25 +46,13 @@ TextLeafAccessible::AppendTextTo(nsAStri
 ENameValueFlag
 TextLeafAccessible::Name(nsString& aName)
 {
   // Text node, ARIA can't be used.
   aName = mText;
   return eNameOK;
 }
 
-nsresult
-TextLeafAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
-{
-  if (NativeRole() == roles::STATICTEXT) {
-    nsAutoString oldValueUnused;
-    aAttributes->SetStringProperty(NS_LITERAL_CSTRING("auto-generated"),
-                                  NS_LITERAL_STRING("true"), oldValueUnused);
-  }
-
-  return NS_OK;
-}
-
 void
 TextLeafAccessible::CacheChildren()
 {
   // No children for text accessible.
 }
--- a/accessible/src/generic/TextLeafAccessible.h
+++ b/accessible/src/generic/TextLeafAccessible.h
@@ -20,17 +20,16 @@ public:
   TextLeafAccessible(nsIContent* aContent, DocAccessible* aDoc);
   virtual ~TextLeafAccessible();
 
   // Accessible
   virtual mozilla::a11y::role NativeRole();
   virtual void AppendTextTo(nsAString& aText, PRUint32 aStartOffset = 0,
                             PRUint32 aLength = PR_UINT32_MAX);
   virtual ENameValueFlag Name(nsString& aName);
-  virtual nsresult GetAttributesInternal(nsIPersistentProperties* aAttributes);
 
   // TextLeafAccessible
   void SetText(const nsAString& aText) { mText = aText; }
   const nsString& Text() const { return mText; }
 
 protected:
   // Accessible
   virtual void CacheChildren();
--- a/accessible/tests/mochitest/attributes/test_text.html
+++ b/accessible/tests/mochitest/attributes/test_text.html
@@ -1,15 +1,20 @@
 <html>
 
 <head>
   <title>Text attributes tests</title>
   <meta charset="utf-8" />
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
 
+  <style type="text/css">
+    .gencontent:before { content: "*"; }
+    .gencontent:after  { content: "*"; }
+  </style>
+
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
 
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="../attributes.js"></script>
   <script type="application/javascript"
@@ -501,16 +506,29 @@
       testTextAttrs(ID, 34, attrs, defAttrs, 34, 39);
 
       attrs = {
         "text-line-through-style": "wavy",
         "text-line-through-color": "rgb(0, 0, 0)",
       };
       testTextAttrs(ID, 39, attrs, defAttrs, 39, 44);
 
+      //////////////////////////////////////////////////////////////////////////
+      // area18, "auto-generation text" tests
+      ID = "area18";
+      defAttrs = buildDefaultTextAttrs(ID, "12pt");
+      testDefaultTextAttrs(ID, defAttrs);
+
+      var attrs = {
+        "auto-generated": "true"
+      };
+      testTextAttrs(ID, 0, attrs, defAttrs, 0, 2);
+      testTextAttrs(ID, 2, { }, defAttrs, 2, 6);
+      testTextAttrs(ID, 6, attrs, defAttrs, 6, 7);
+
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
 <body style="font-size: 12pt">
@@ -535,16 +553,21 @@
      title="expose text-underline-color and text-line-through-color text attributes">
     Mozilla Bug 523304
   </a>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=735645"
      title="expose sub and sup elements in text attributes">
     Mozilla Bug 735645
   </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=445516"
+     title="Support auto-generated text attribute on bullet lists">
+    Mozilla Bug 445516
+  </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <p id="area1" style="font-size: smaller">Normal <b>Bold</b> Normal</p>
   <p id="area2" style="font-size: 120%">Normal <b>Bold <i>Italic </i>Bold</b> Normal</p>
   <p id="area3" style="background-color: blue;">
@@ -639,10 +662,15 @@
     <span style="-moz-text-decoration-line: underline;">underline
     </span><span style="text-decoration: underline; -moz-text-decoration-color: blue;">blue
     </span><span style="text-decoration: underline; -moz-text-decoration-style: dotted;">dotted
     </span><span style="-moz-text-decoration-line: line-through;">linethrough
     </span><span style="text-decoration: line-through; -moz-text-decoration-color: blue;">blue
     </span><span style="text-decoration: line-through; -moz-text-decoration-style: wavy;">wavy
     </span>
   </p>
+
+  <ul>
+    <li id="area18" class="gencontent">item</li>
+  </ul>
+
 </body>
 </html>
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1969,16 +1969,17 @@ GK_ATOM(aria_required, "aria-required")
 GK_ATOM(aria_selected, "aria-selected")
 GK_ATOM(aria_setsize, "aria-setsize")
 GK_ATOM(aria_sort, "aria-sort")
 GK_ATOM(aria_valuenow, "aria-valuenow")
 GK_ATOM(aria_valuemin, "aria-valuemin")
 GK_ATOM(aria_valuemax, "aria-valuemax")
 GK_ATOM(aria_valuetext, "aria-valuetext")
 GK_ATOM(AreaFrame, "AreaFrame")
+GK_ATOM(auto_generated, "auto-generated")
 GK_ATOM(backgroundColor, "background-color")
 GK_ATOM(checkable, "checkable")
 GK_ATOM(choices, "choices")
 GK_ATOM(containerAtomic, "container-atomic")
 GK_ATOM(containerBusy, "container-busy")
 GK_ATOM(containerLive, "container-live")
 GK_ATOM(containerLiveRole, "container-live-role")
 GK_ATOM(containerRelevant, "container-relevant")