Back to index

lightning-sunbird  0.9+nobinonly
nsHTMLTextAccessible.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Aaron Leventhal (aaronl@netscape.com)
00024  *   Kyle Yuan (kyle.yuan@sun.com)
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either of the GNU General Public License Version 2 or later (the "GPL"),
00028  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #include "nsHTMLTextAccessible.h"
00041 #include "nsAccessibleTreeWalker.h"
00042 #include "nsBulletFrame.h"
00043 #include "nsIAccessibleDocument.h"
00044 #include "nsIAccessibleEvent.h"
00045 #include "nsIFrame.h"
00046 #include "nsPresContext.h"
00047 #include "nsIPresShell.h"
00048 #include "nsISelection.h"
00049 #include "nsISelectionController.h"
00050 
00051 nsHTMLTextAccessible::nsHTMLTextAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell, nsIFrame *aFrame):
00052 nsTextAccessibleWrap(aDomNode, aShell)
00053 { 
00054 }
00055 
00056 NS_IMETHODIMP nsHTMLTextAccessible::GetName(nsAString& aName)
00057 {
00058   aName.Truncate();
00059   if (!mDOMNode) {
00060     return NS_ERROR_FAILURE;
00061   }
00062 
00063   nsIFrame *frame = GetFrame();
00064   NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
00065 
00066   nsAutoString name;
00067   nsresult rv = mDOMNode->GetNodeValue(name);
00068   NS_ENSURE_SUCCESS(rv, rv);
00069 
00070   if (!frame->GetStyleText()->WhiteSpaceIsSignificant()) {
00071     // Replace \r\n\t in markup with space unless in this is preformatted text
00072     // where those characters are significant
00073     name.ReplaceChar("\r\n\t", ' ');
00074   }
00075   aName = name;
00076   return rv;
00077 }
00078 
00079 NS_IMETHODIMP nsHTMLTextAccessible::GetState(PRUint32 *aState)
00080 {
00081   nsTextAccessible::GetState(aState);
00082 
00083   nsCOMPtr<nsIAccessibleDocument> docAccessible(GetDocAccessible());
00084   if (docAccessible) {
00085     PRBool isEditable;
00086     docAccessible->GetIsEditable(&isEditable);
00087     if (!isEditable) {
00088       *aState |= STATE_READONLY;
00089     }
00090   }
00091 
00092   return NS_OK;
00093 }
00094 
00095 nsHTMLHRAccessible::nsHTMLHRAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell):
00096 nsLeafAccessible(aDomNode, aShell)
00097 { 
00098 }
00099 
00100 NS_IMETHODIMP nsHTMLHRAccessible::GetRole(PRUint32 *aRole)
00101 {
00102   *aRole = ROLE_SEPARATOR;
00103   return NS_OK;
00104 }
00105 
00106 NS_IMETHODIMP nsHTMLHRAccessible::GetState(PRUint32 *aState)
00107 {
00108   nsLeafAccessible::GetState(aState);
00109   *aState &= ~STATE_FOCUSABLE;
00110   return NS_OK;
00111 }
00112 
00113 nsHTMLLabelAccessible::nsHTMLLabelAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell):
00114 nsTextAccessible(aDomNode, aShell)
00115 { 
00116 }
00117 
00118 NS_IMETHODIMP nsHTMLLabelAccessible::GetName(nsAString& aReturn)
00119 { 
00120   nsresult rv = NS_ERROR_FAILURE;
00121   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
00122 
00123   nsAutoString name;
00124   if (content)
00125     rv = AppendFlatStringFromSubtree(content, &name);
00126 
00127   if (NS_SUCCEEDED(rv)) {
00128     // Temp var needed until CompressWhitespace built for nsAString
00129     name.CompressWhitespace();
00130     aReturn = name;
00131   }
00132 
00133   return rv;
00134 }
00135 
00136 NS_IMETHODIMP nsHTMLLabelAccessible::GetRole(PRUint32 *aRole)
00137 {
00138   *aRole = ROLE_STATICTEXT;
00139   return NS_OK;
00140 }
00141 
00142 NS_IMETHODIMP nsHTMLLabelAccessible::GetState(PRUint32 *aState)
00143 {
00144   nsTextAccessible::GetState(aState);
00145   *aState &= (STATE_LINKED|STATE_TRAVERSED);  // Only use link states
00146   return NS_OK;
00147 }
00148 
00149 NS_IMETHODIMP nsHTMLLabelAccessible::GetFirstChild(nsIAccessible **aFirstChild) 
00150 {  
00151   // A <label> is not necessarily a leaf!
00152   return nsAccessible::GetFirstChild(aFirstChild);
00153 }
00154 
00155   /* readonly attribute nsIAccessible accFirstChild; */
00156 NS_IMETHODIMP nsHTMLLabelAccessible::GetLastChild(nsIAccessible **aLastChild)
00157 {  
00158   // A <label> is not necessarily a leaf!
00159   return nsAccessible::GetLastChild(aLastChild);
00160 }
00161 
00162 /* readonly attribute long accChildCount; */
00163 NS_IMETHODIMP nsHTMLLabelAccessible::GetChildCount(PRInt32 *aAccChildCount) 
00164 {
00165   // A <label> is not necessarily a leaf!
00166   return nsAccessible::GetChildCount(aAccChildCount);
00167 }
00168 
00169 nsHTMLLIAccessible::nsHTMLLIAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell, 
00170                    nsIFrame *aBulletFrame, const nsAString& aBulletText):
00171   nsBlockAccessible(aDOMNode, aShell)
00172 {
00173   if (!aBulletText.IsEmpty()) {
00174     mBulletAccessible = new nsHTMLListBulletAccessible(mDOMNode, mWeakShell, 
00175                                                        aBulletFrame, aBulletText);
00176     nsCOMPtr<nsPIAccessNode> bulletANode(mBulletAccessible);
00177     if (bulletANode) {
00178       bulletANode->Init();
00179     }
00180   }
00181 }
00182 
00183 NS_IMETHODIMP nsHTMLLIAccessible::Shutdown()
00184 {
00185   if (mBulletAccessible) {
00186     // Ensure that weak pointer to this is nulled out
00187     mBulletAccessible->Shutdown();
00188   }
00189   nsresult rv = nsAccessibleWrap::Shutdown();
00190   mBulletAccessible = nsnull;
00191   return rv;
00192 }
00193 
00194 NS_IMETHODIMP nsHTMLLIAccessible::GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height)
00195 {
00196   nsresult rv = nsAccessibleWrap::GetBounds(x, y, width, height);
00197   if (NS_FAILED(rv) || !mBulletAccessible) {
00198     return rv;
00199   }
00200 
00201   PRInt32 bulletX, bulletY, bulletWidth, bulletHeight;
00202   rv = mBulletAccessible->GetBounds(&bulletX, &bulletY, &bulletWidth, &bulletHeight);
00203   NS_ENSURE_SUCCESS(rv, rv);
00204 
00205   *x = bulletX; // Move x coordinate of list item over to cover bullet as well
00206   *width += bulletWidth;
00207   return NS_OK;
00208 }
00209 
00210 void nsHTMLLIAccessible::CacheChildren(PRBool aWalkAnonContent)
00211 {
00212   if (!mBulletAccessible || !mWeakShell) {
00213     nsAccessibleWrap::CacheChildren(aWalkAnonContent);
00214     return;
00215   }
00216 
00217   if (mAccChildCount == eChildCountUninitialized) {
00218     SetFirstChild(mBulletAccessible);
00219     mBulletAccessible->SetParent(this);
00220     mAccChildCount = 1;
00221     nsAccessibleTreeWalker walker(mWeakShell, mDOMNode, aWalkAnonContent);
00222     walker.mState.frame = GetFrame();
00223     walker.GetFirstChild();
00224 
00225     nsCOMPtr<nsPIAccessible> privatePrevAccessible = mBulletAccessible.get();
00226     while (walker.mState.accessible) {
00227       ++mAccChildCount;
00228       privatePrevAccessible->SetNextSibling(walker.mState.accessible);
00229       privatePrevAccessible = do_QueryInterface(walker.mState.accessible);
00230       privatePrevAccessible->SetParent(this);
00231       walker.GetNextSibling();
00232     }
00233   }
00234 }
00235 
00236 
00237 nsHTMLListBulletAccessible::nsHTMLListBulletAccessible(nsIDOMNode* aDomNode, 
00238   nsIWeakReference* aShell, nsIFrame *aFrame, const nsAString& aBulletText): 
00239   nsHTMLTextAccessible(aDomNode, aShell, aFrame), mWeakParent(nsnull), mBulletText(aBulletText)
00240 {
00241 }
00242 
00243 NS_IMETHODIMP nsHTMLListBulletAccessible::GetUniqueID(void **aUniqueID)
00244 {
00245   // Since mDOMNode is same as for list item, use |this| pointer as the unique Id
00246   *aUniqueID = NS_STATIC_CAST(void*, this);
00247   return NS_OK;
00248 }
00249 
00250 
00251 NS_IMETHODIMP nsHTMLListBulletAccessible::Shutdown()
00252 {
00253   mBulletText.Truncate();
00254   mWeakParent = nsnull;
00255   return nsHTMLTextAccessible::Shutdown();
00256 }
00257 
00258 NS_IMETHODIMP nsHTMLListBulletAccessible::GetName(nsAString &aName)
00259 {
00260   aName = mBulletText;
00261   return NS_OK;
00262 }
00263