2009-02-18 23:06:14 -08:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
|
|
|
*/
|
|
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
|
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
|
|
* the License. You may obtain a copy of the License at
|
|
|
|
* http://www.mozilla.org/MPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
* License.
|
|
|
|
*
|
|
|
|
* The Original Code is mozilla.org code.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Mozilla Foundation
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 2008
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
* Alexander Surkov <surkov.alexander@gmail.com> (original author)
|
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
|
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
|
|
* the provisions above, a recipient may use your version of this file under
|
|
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
|
|
*
|
|
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
|
|
|
|
#include "nsTextEquivUtils.h"
|
|
|
|
|
2011-08-09 18:44:00 -07:00
|
|
|
#include "AccIterator.h"
|
2010-04-26 23:52:03 -07:00
|
|
|
#include "nsAccessibilityService.h"
|
2009-02-18 23:06:14 -08:00
|
|
|
#include "nsAccessible.h"
|
2010-04-26 23:52:03 -07:00
|
|
|
#include "nsAccUtils.h"
|
2009-02-18 23:06:14 -08:00
|
|
|
|
|
|
|
#include "nsIDOMXULLabeledControlEl.h"
|
|
|
|
|
|
|
|
#include "nsArrayUtils.h"
|
|
|
|
|
|
|
|
#define NS_OK_NO_NAME_CLAUSE_HANDLED \
|
|
|
|
NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_GENERAL, 0x24)
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsTextEquivUtils. Public.
|
|
|
|
|
|
|
|
nsresult
|
2010-06-11 01:23:18 -07:00
|
|
|
nsTextEquivUtils::GetNameFromSubtree(nsAccessible *aAccessible,
|
2009-02-18 23:06:14 -08:00
|
|
|
nsAString& aName)
|
|
|
|
{
|
|
|
|
aName.Truncate();
|
|
|
|
|
|
|
|
if (gInitiatorAcc)
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
gInitiatorAcc = aAccessible;
|
|
|
|
|
2010-09-06 19:41:53 -07:00
|
|
|
PRUint32 nameRule = gRoleToNameRulesMap[aAccessible->Role()];
|
2009-02-18 23:06:14 -08:00
|
|
|
if (nameRule == eFromSubtree) {
|
2010-06-11 01:23:18 -07:00
|
|
|
//XXX: is it necessary to care the accessible is not a document?
|
|
|
|
if (aAccessible->IsContent()) {
|
2009-02-18 23:06:14 -08:00
|
|
|
nsAutoString name;
|
|
|
|
AppendFromAccessibleChildren(aAccessible, &name);
|
|
|
|
name.CompressWhitespace();
|
2009-06-12 18:06:02 -07:00
|
|
|
if (!IsWhitespaceString(name))
|
|
|
|
aName = name;
|
2009-02-18 23:06:14 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gInitiatorAcc = nsnull;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2010-06-11 01:23:18 -07:00
|
|
|
nsTextEquivUtils::GetTextEquivFromIDRefs(nsAccessible *aAccessible,
|
2009-02-18 23:06:14 -08:00
|
|
|
nsIAtom *aIDRefsAttr,
|
|
|
|
nsAString& aTextEquiv)
|
|
|
|
{
|
|
|
|
aTextEquiv.Truncate();
|
|
|
|
|
2010-06-11 01:23:18 -07:00
|
|
|
nsIContent* content = aAccessible->GetContent();
|
2009-02-18 23:06:14 -08:00
|
|
|
if (!content)
|
|
|
|
return NS_OK;
|
|
|
|
|
2010-11-16 19:32:15 -08:00
|
|
|
nsIContent* refContent = nsnull;
|
|
|
|
IDRefsIterator iter(content, aIDRefsAttr);
|
|
|
|
while ((refContent = iter.NextElem())) {
|
2009-02-18 23:06:14 -08:00
|
|
|
if (!aTextEquiv.IsEmpty())
|
|
|
|
aTextEquiv += ' ';
|
|
|
|
|
2010-11-16 19:32:15 -08:00
|
|
|
nsresult rv = AppendTextEquivFromContent(aAccessible, refContent,
|
|
|
|
&aTextEquiv);
|
2009-02-18 23:06:14 -08:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2010-06-11 01:23:18 -07:00
|
|
|
nsTextEquivUtils::AppendTextEquivFromContent(nsAccessible *aInitiatorAcc,
|
2009-02-18 23:06:14 -08:00
|
|
|
nsIContent *aContent,
|
|
|
|
nsAString *aString)
|
|
|
|
{
|
|
|
|
// Prevent recursion which can cause infinite loops.
|
|
|
|
if (gInitiatorAcc)
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
gInitiatorAcc = aInitiatorAcc;
|
|
|
|
|
2012-02-09 08:49:17 -08:00
|
|
|
nsIPresShell* shell = nsCoreUtils::GetPresShellFor(aContent);
|
2009-02-18 23:06:14 -08:00
|
|
|
if (!shell) {
|
2011-10-17 07:59:28 -07:00
|
|
|
NS_ASSERTION(true, "There is no presshell!");
|
2009-02-18 23:06:14 -08:00
|
|
|
gInitiatorAcc = nsnull;
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the given content is not visible or isn't accessible then go down
|
|
|
|
// through the DOM subtree otherwise go down through accessible subtree and
|
|
|
|
// calculate the flat string.
|
2009-12-24 13:20:05 -08:00
|
|
|
nsIFrame *frame = aContent->GetPrimaryFrame();
|
2011-09-28 23:19:26 -07:00
|
|
|
bool isVisible = frame && frame->GetStyleVisibility()->IsVisible();
|
2009-02-18 23:06:14 -08:00
|
|
|
|
2010-02-01 18:27:32 -08:00
|
|
|
nsresult rv = NS_ERROR_FAILURE;
|
2011-09-28 23:19:26 -07:00
|
|
|
bool goThroughDOMSubtree = true;
|
2009-02-18 23:06:14 -08:00
|
|
|
|
|
|
|
if (isVisible) {
|
2012-02-09 08:49:17 -08:00
|
|
|
nsAccessible* accessible =
|
|
|
|
GetAccService()->GetAccessible(aContent, shell);
|
2010-02-01 18:27:32 -08:00
|
|
|
if (accessible) {
|
2009-02-18 23:06:14 -08:00
|
|
|
rv = AppendFromAccessible(accessible, aString);
|
2011-10-17 07:59:28 -07:00
|
|
|
goThroughDOMSubtree = false;
|
2009-02-18 23:06:14 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (goThroughDOMSubtree)
|
|
|
|
rv = AppendFromDOMNode(aContent, aString);
|
|
|
|
|
|
|
|
gInitiatorAcc = nsnull;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEquivUtils::AppendTextEquivFromTextContent(nsIContent *aContent,
|
|
|
|
nsAString *aString)
|
|
|
|
{
|
|
|
|
if (aContent->IsNodeOfType(nsINode::eTEXT)) {
|
2011-09-28 23:19:26 -07:00
|
|
|
bool isHTMLBlock = false;
|
2010-06-11 01:23:18 -07:00
|
|
|
|
2009-02-18 23:06:14 -08:00
|
|
|
nsIContent *parentContent = aContent->GetParent();
|
|
|
|
if (parentContent) {
|
2009-12-24 13:20:05 -08:00
|
|
|
nsIFrame *frame = parentContent->GetPrimaryFrame();
|
2009-02-18 23:06:14 -08:00
|
|
|
if (frame) {
|
|
|
|
// If this text is inside a block level frame (as opposed to span
|
|
|
|
// level), we need to add spaces around that block's text, so we don't
|
|
|
|
// get words jammed together in final name.
|
|
|
|
const nsStyleDisplay* display = frame->GetStyleDisplay();
|
|
|
|
if (display->IsBlockOutside() ||
|
|
|
|
display->mDisplay == NS_STYLE_DISPLAY_TABLE_CELL) {
|
2011-10-17 07:59:28 -07:00
|
|
|
isHTMLBlock = true;
|
2009-02-18 23:06:14 -08:00
|
|
|
if (!aString->IsEmpty()) {
|
|
|
|
aString->Append(PRUnichar(' '));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aContent->TextLength() > 0) {
|
2009-12-24 13:20:05 -08:00
|
|
|
nsIFrame *frame = aContent->GetPrimaryFrame();
|
2009-02-18 23:06:14 -08:00
|
|
|
if (frame) {
|
|
|
|
nsresult rv = frame->GetRenderedText(aString);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
} else {
|
|
|
|
// If aContent is an object that is display: none, we have no a frame.
|
|
|
|
aContent->AppendTextTo(*aString);
|
|
|
|
}
|
|
|
|
if (isHTMLBlock && !aString->IsEmpty()) {
|
|
|
|
aString->Append(PRUnichar(' '));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2009-08-24 13:02:07 -07:00
|
|
|
if (aContent->IsHTML() &&
|
2011-06-03 14:35:17 -07:00
|
|
|
aContent->NodeInfo()->Equals(nsGkAtoms::br)) {
|
2009-02-18 23:06:14 -08:00
|
|
|
aString->AppendLiteral("\r\n");
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK_NO_NAME_CLAUSE_HANDLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsTextEquivUtils. Private.
|
|
|
|
|
2010-06-11 01:23:18 -07:00
|
|
|
nsRefPtr<nsAccessible> nsTextEquivUtils::gInitiatorAcc;
|
2009-02-18 23:06:14 -08:00
|
|
|
|
|
|
|
nsresult
|
2010-06-11 01:23:18 -07:00
|
|
|
nsTextEquivUtils::AppendFromAccessibleChildren(nsAccessible *aAccessible,
|
2009-02-18 23:06:14 -08:00
|
|
|
nsAString *aString)
|
|
|
|
{
|
2009-02-27 02:54:39 -08:00
|
|
|
nsresult rv = NS_OK_NO_NAME_CLAUSE_HANDLED;
|
2009-02-18 23:06:14 -08:00
|
|
|
|
2010-06-11 01:23:18 -07:00
|
|
|
PRInt32 childCount = aAccessible->GetChildCount();
|
2010-05-18 07:03:56 -07:00
|
|
|
for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
|
2010-06-11 01:23:18 -07:00
|
|
|
nsAccessible *child = aAccessible->GetChildAt(childIdx);
|
2010-05-18 07:03:56 -07:00
|
|
|
rv = AppendFromAccessible(child, aString);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2009-02-18 23:06:14 -08:00
|
|
|
}
|
|
|
|
|
2009-02-27 02:54:39 -08:00
|
|
|
return rv;
|
2009-02-18 23:06:14 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2010-06-11 01:23:18 -07:00
|
|
|
nsTextEquivUtils::AppendFromAccessible(nsAccessible *aAccessible,
|
2009-02-18 23:06:14 -08:00
|
|
|
nsAString *aString)
|
|
|
|
{
|
2010-06-11 01:23:18 -07:00
|
|
|
//XXX: is it necessary to care the accessible is not a document?
|
|
|
|
if (aAccessible->IsContent()) {
|
|
|
|
nsresult rv = AppendTextEquivFromTextContent(aAccessible->GetContent(),
|
|
|
|
aString);
|
2009-02-18 23:06:14 -08:00
|
|
|
if (rv != NS_OK_NO_NAME_CLAUSE_HANDLED)
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsAutoString text;
|
|
|
|
nsresult rv = aAccessible->GetName(text);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool isEmptyTextEquiv = true;
|
2009-02-27 02:54:39 -08:00
|
|
|
|
|
|
|
// If the name is from tooltip then append it to result string in the end
|
|
|
|
// (see h. step of name computation guide).
|
|
|
|
if (rv != NS_OK_NAME_FROM_TOOLTIP)
|
|
|
|
isEmptyTextEquiv = !AppendString(aString, text);
|
|
|
|
|
|
|
|
// Implementation of f. step.
|
|
|
|
rv = AppendFromValue(aAccessible, aString);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
if (rv != NS_OK_NO_NAME_CLAUSE_HANDLED)
|
2011-10-17 07:59:28 -07:00
|
|
|
isEmptyTextEquiv = false;
|
2009-02-27 02:54:39 -08:00
|
|
|
|
|
|
|
// Implementation of g) step of text equivalent computation guide. Go down
|
|
|
|
// into subtree if accessible allows "text equivalent from subtree rule" or
|
|
|
|
// it's not root and not control.
|
|
|
|
if (isEmptyTextEquiv) {
|
2010-09-06 19:41:53 -07:00
|
|
|
PRUint32 nameRule = gRoleToNameRulesMap[aAccessible->Role()];
|
2009-02-27 02:54:39 -08:00
|
|
|
if (nameRule & eFromSubtreeIfRec) {
|
|
|
|
rv = AppendFromAccessibleChildren(aAccessible, aString);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
if (rv != NS_OK_NO_NAME_CLAUSE_HANDLED)
|
2011-10-17 07:59:28 -07:00
|
|
|
isEmptyTextEquiv = false;
|
2009-02-27 02:54:39 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Implementation of h. step
|
|
|
|
if (isEmptyTextEquiv && !text.IsEmpty()) {
|
|
|
|
AppendString(aString, text);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2010-06-11 01:23:18 -07:00
|
|
|
nsTextEquivUtils::AppendFromValue(nsAccessible *aAccessible,
|
2009-02-27 02:54:39 -08:00
|
|
|
nsAString *aString)
|
|
|
|
{
|
2010-09-06 19:41:53 -07:00
|
|
|
PRUint32 nameRule = gRoleToNameRulesMap[aAccessible->Role()];
|
2009-02-27 02:54:39 -08:00
|
|
|
if (nameRule != eFromValue)
|
|
|
|
return NS_OK_NO_NAME_CLAUSE_HANDLED;
|
2009-02-18 23:06:14 -08:00
|
|
|
|
2009-02-27 02:54:39 -08:00
|
|
|
// Implementation of step f. of text equivalent computation. If the given
|
|
|
|
// accessible is not root accessible (the accessible the text equivalent is
|
|
|
|
// computed for in the end) then append accessible value. Otherwise append
|
|
|
|
// value if and only if the given accessible is in the middle of its parent.
|
2009-02-18 23:06:14 -08:00
|
|
|
|
2009-02-27 02:54:39 -08:00
|
|
|
nsAutoString text;
|
|
|
|
if (aAccessible != gInitiatorAcc) {
|
|
|
|
nsresult rv = aAccessible->GetValue(text);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
return AppendString(aString, text) ?
|
|
|
|
NS_OK : NS_OK_NO_NAME_CLAUSE_HANDLED;
|
|
|
|
}
|
|
|
|
|
2010-06-11 01:23:18 -07:00
|
|
|
//XXX: is it necessary to care the accessible is not a document?
|
2011-05-19 22:17:47 -07:00
|
|
|
if (aAccessible->IsDocumentNode())
|
2010-06-11 01:23:18 -07:00
|
|
|
return NS_ERROR_UNEXPECTED;
|
2009-07-29 02:03:20 -07:00
|
|
|
|
2010-06-11 01:23:18 -07:00
|
|
|
nsIContent *content = aAccessible->GetContent();
|
2009-07-29 02:03:20 -07:00
|
|
|
|
2011-12-06 23:20:17 -08:00
|
|
|
for (nsIContent* childContent = content->GetPreviousSibling(); childContent;
|
|
|
|
childContent = childContent->GetPreviousSibling()) {
|
2009-07-29 02:03:20 -07:00
|
|
|
// check for preceding text...
|
2011-12-06 23:20:17 -08:00
|
|
|
if (!childContent->TextIsOnlyWhitespace()) {
|
|
|
|
for (nsIContent* siblingContent = content->GetNextSibling(); siblingContent;
|
|
|
|
siblingContent = siblingContent->GetNextSibling()) {
|
2009-07-29 02:03:20 -07:00
|
|
|
// .. and subsequent text
|
2011-12-06 23:20:17 -08:00
|
|
|
if (!siblingContent->TextIsOnlyWhitespace()) {
|
2009-07-29 02:03:20 -07:00
|
|
|
nsresult rv = aAccessible->GetValue(text);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
return AppendString(aString, text) ?
|
|
|
|
NS_OK : NS_OK_NO_NAME_CLAUSE_HANDLED;
|
|
|
|
break;
|
|
|
|
}
|
2009-02-18 23:06:14 -08:00
|
|
|
}
|
2009-07-29 02:03:20 -07:00
|
|
|
break;
|
2009-02-18 23:06:14 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-27 02:54:39 -08:00
|
|
|
return NS_OK_NO_NAME_CLAUSE_HANDLED;
|
2009-02-18 23:06:14 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEquivUtils::AppendFromDOMChildren(nsIContent *aContent,
|
|
|
|
nsAString *aString)
|
|
|
|
{
|
2011-12-06 23:20:17 -08:00
|
|
|
for (nsIContent* childContent = aContent->GetFirstChild(); childContent;
|
|
|
|
childContent = childContent->GetNextSibling()) {
|
2009-02-18 23:06:14 -08:00
|
|
|
nsresult rv = AppendFromDOMNode(childContent, aString);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEquivUtils::AppendFromDOMNode(nsIContent *aContent, nsAString *aString)
|
|
|
|
{
|
|
|
|
nsresult rv = AppendTextEquivFromTextContent(aContent, aString);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
if (rv != NS_OK_NO_NAME_CLAUSE_HANDLED)
|
|
|
|
return NS_OK;
|
|
|
|
|
2009-08-24 13:02:07 -07:00
|
|
|
if (aContent->IsXUL()) {
|
2009-02-18 23:06:14 -08:00
|
|
|
nsAutoString textEquivalent;
|
|
|
|
nsCOMPtr<nsIDOMXULLabeledControlElement> labeledEl =
|
|
|
|
do_QueryInterface(aContent);
|
|
|
|
|
|
|
|
if (labeledEl) {
|
|
|
|
labeledEl->GetLabel(textEquivalent);
|
|
|
|
} else {
|
2011-06-03 14:35:17 -07:00
|
|
|
if (aContent->NodeInfo()->Equals(nsGkAtoms::label,
|
2009-02-18 23:06:14 -08:00
|
|
|
kNameSpaceID_XUL))
|
2011-06-03 14:35:17 -07:00
|
|
|
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value,
|
2009-02-18 23:06:14 -08:00
|
|
|
textEquivalent);
|
|
|
|
|
|
|
|
if (textEquivalent.IsEmpty())
|
|
|
|
aContent->GetAttr(kNameSpaceID_None,
|
2011-06-03 14:35:17 -07:00
|
|
|
nsGkAtoms::tooltiptext, textEquivalent);
|
2009-02-18 23:06:14 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
AppendString(aString, textEquivalent);
|
|
|
|
}
|
|
|
|
|
|
|
|
return AppendFromDOMChildren(aContent, aString);
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool
|
2009-02-18 23:06:14 -08:00
|
|
|
nsTextEquivUtils::AppendString(nsAString *aString,
|
|
|
|
const nsAString& aTextEquivalent)
|
|
|
|
{
|
|
|
|
// Insert spaces to insure that words from controls aren't jammed together.
|
|
|
|
if (aTextEquivalent.IsEmpty())
|
2011-10-17 07:59:28 -07:00
|
|
|
return false;
|
2009-02-18 23:06:14 -08:00
|
|
|
|
|
|
|
if (!aString->IsEmpty())
|
|
|
|
aString->Append(PRUnichar(' '));
|
|
|
|
|
|
|
|
aString->Append(aTextEquivalent);
|
2011-10-17 07:59:28 -07:00
|
|
|
return true;
|
2009-02-18 23:06:14 -08:00
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool
|
2009-06-12 18:06:02 -07:00
|
|
|
nsTextEquivUtils::IsWhitespaceString(const nsSubstring& aString)
|
|
|
|
{
|
|
|
|
nsSubstring::const_char_iterator iterBegin, iterEnd;
|
|
|
|
|
|
|
|
aString.BeginReading(iterBegin);
|
|
|
|
aString.EndReading(iterEnd);
|
|
|
|
|
|
|
|
while (iterBegin != iterEnd && IsWhitespace(*iterBegin))
|
|
|
|
++iterBegin;
|
|
|
|
|
|
|
|
return iterBegin == iterEnd;
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool
|
2009-06-12 18:06:02 -07:00
|
|
|
nsTextEquivUtils::IsWhitespace(PRUnichar aChar)
|
|
|
|
{
|
|
|
|
return aChar == ' ' || aChar == '\n' ||
|
|
|
|
aChar == '\r' || aChar == '\t' || aChar == 0xa0;
|
|
|
|
}
|
|
|
|
|
2009-02-18 23:06:14 -08:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Name rules to role map.
|
|
|
|
|
|
|
|
PRUint32 nsTextEquivUtils::gRoleToNameRulesMap[] =
|
|
|
|
{
|
2010-11-20 17:02:16 -08:00
|
|
|
eFromSubtreeIfRec, // ROLE_NOTHING
|
2009-02-18 23:06:14 -08:00
|
|
|
eNoRule, // ROLE_TITLEBAR
|
|
|
|
eNoRule, // ROLE_MENUBAR
|
|
|
|
eNoRule, // ROLE_SCROLLBAR
|
|
|
|
eNoRule, // ROLE_GRIP
|
|
|
|
eNoRule, // ROLE_SOUND
|
|
|
|
eNoRule, // ROLE_CURSOR
|
|
|
|
eNoRule, // ROLE_CARET
|
|
|
|
eNoRule, // ROLE_ALERT
|
|
|
|
eNoRule, // ROLE_WINDOW
|
|
|
|
eNoRule, // ROLE_INTERNAL_FRAME
|
|
|
|
eNoRule, // ROLE_MENUPOPUP
|
|
|
|
eFromSubtree, // ROLE_MENUITEM
|
|
|
|
eFromSubtree, // ROLE_TOOLTIP
|
|
|
|
eNoRule, // ROLE_APPLICATION
|
|
|
|
eNoRule, // ROLE_DOCUMENT
|
|
|
|
eNoRule, // ROLE_PANE
|
|
|
|
eNoRule, // ROLE_CHART
|
|
|
|
eNoRule, // ROLE_DIALOG
|
|
|
|
eNoRule, // ROLE_BORDER
|
|
|
|
eNoRule, // ROLE_GROUPING
|
|
|
|
eNoRule, // ROLE_SEPARATOR
|
|
|
|
eNoRule, // ROLE_TOOLBAR
|
|
|
|
eNoRule, // ROLE_STATUSBAR
|
|
|
|
eNoRule, // ROLE_TABLE
|
|
|
|
eFromSubtree, // ROLE_COLUMNHEADER
|
|
|
|
eFromSubtree, // ROLE_ROWHEADER
|
|
|
|
eFromSubtree, // ROLE_COLUMN
|
|
|
|
eFromSubtree, // ROLE_ROW
|
|
|
|
eFromSubtreeIfRec, // ROLE_CELL
|
|
|
|
eFromSubtree, // ROLE_LINK
|
|
|
|
eFromSubtree, // ROLE_HELPBALLOON
|
|
|
|
eNoRule, // ROLE_CHARACTER
|
|
|
|
eFromSubtreeIfRec, // ROLE_LIST
|
|
|
|
eFromSubtree, // ROLE_LISTITEM
|
|
|
|
eNoRule, // ROLE_OUTLINE
|
|
|
|
eFromSubtree, // ROLE_OUTLINEITEM
|
|
|
|
eFromSubtree, // ROLE_PAGETAB
|
|
|
|
eNoRule, // ROLE_PROPERTYPAGE
|
|
|
|
eNoRule, // ROLE_INDICATOR
|
|
|
|
eNoRule, // ROLE_GRAPHIC
|
|
|
|
eNoRule, // ROLE_STATICTEXT
|
|
|
|
eNoRule, // ROLE_TEXT_LEAF
|
|
|
|
eFromSubtree, // ROLE_PUSHBUTTON
|
|
|
|
eFromSubtree, // ROLE_CHECKBUTTON
|
|
|
|
eFromSubtree, // ROLE_RADIOBUTTON
|
|
|
|
eFromValue, // ROLE_COMBOBOX
|
|
|
|
eNoRule, // ROLE_DROPLIST
|
|
|
|
eFromValue, // ROLE_PROGRESSBAR
|
|
|
|
eNoRule, // ROLE_DIAL
|
|
|
|
eNoRule, // ROLE_HOTKEYFIELD
|
|
|
|
eNoRule, // ROLE_SLIDER
|
|
|
|
eNoRule, // ROLE_SPINBUTTON
|
|
|
|
eNoRule, // ROLE_DIAGRAM
|
|
|
|
eNoRule, // ROLE_ANIMATION
|
|
|
|
eNoRule, // ROLE_EQUATION
|
|
|
|
eFromSubtree, // ROLE_BUTTONDROPDOWN
|
|
|
|
eFromSubtree, // ROLE_BUTTONMENU
|
|
|
|
eFromSubtree, // ROLE_BUTTONDROPDOWNGRID
|
|
|
|
eNoRule, // ROLE_WHITESPACE
|
|
|
|
eNoRule, // ROLE_PAGETABLIST
|
|
|
|
eNoRule, // ROLE_CLOCK
|
|
|
|
eNoRule, // ROLE_SPLITBUTTON
|
|
|
|
eNoRule, // ROLE_IPADDRESS
|
|
|
|
eNoRule, // ROLE_ACCEL_LABEL
|
|
|
|
eNoRule, // ROLE_ARROW
|
|
|
|
eNoRule, // ROLE_CANVAS
|
|
|
|
eFromSubtree, // ROLE_CHECK_MENU_ITEM
|
|
|
|
eNoRule, // ROLE_COLOR_CHOOSER
|
|
|
|
eNoRule, // ROLE_DATE_EDITOR
|
|
|
|
eNoRule, // ROLE_DESKTOP_ICON
|
|
|
|
eNoRule, // ROLE_DESKTOP_FRAME
|
|
|
|
eNoRule, // ROLE_DIRECTORY_PANE
|
|
|
|
eNoRule, // ROLE_FILE_CHOOSER
|
|
|
|
eNoRule, // ROLE_FONT_CHOOSER
|
|
|
|
eNoRule, // ROLE_CHROME_WINDOW
|
|
|
|
eNoRule, // ROLE_GLASS_PANE
|
|
|
|
eFromSubtreeIfRec, // ROLE_HTML_CONTAINER
|
|
|
|
eNoRule, // ROLE_ICON
|
|
|
|
eFromSubtree, // ROLE_LABEL
|
|
|
|
eNoRule, // ROLE_LAYERED_PANE
|
|
|
|
eNoRule, // ROLE_OPTION_PANE
|
|
|
|
eNoRule, // ROLE_PASSWORD_TEXT
|
|
|
|
eNoRule, // ROLE_POPUP_MENU
|
|
|
|
eFromSubtree, // ROLE_RADIO_MENU_ITEM
|
|
|
|
eNoRule, // ROLE_ROOT_PANE
|
|
|
|
eNoRule, // ROLE_SCROLL_PANE
|
|
|
|
eNoRule, // ROLE_SPLIT_PANE
|
|
|
|
eFromSubtree, // ROLE_TABLE_COLUMN_HEADER
|
|
|
|
eFromSubtree, // ROLE_TABLE_ROW_HEADER
|
|
|
|
eFromSubtree, // ROLE_TEAR_OFF_MENU_ITEM
|
|
|
|
eNoRule, // ROLE_TERMINAL
|
|
|
|
eFromSubtreeIfRec, // ROLE_TEXT_CONTAINER
|
|
|
|
eFromSubtree, // ROLE_TOGGLE_BUTTON
|
|
|
|
eNoRule, // ROLE_TREE_TABLE
|
|
|
|
eNoRule, // ROLE_VIEWPORT
|
|
|
|
eNoRule, // ROLE_HEADER
|
|
|
|
eNoRule, // ROLE_FOOTER
|
|
|
|
eFromSubtreeIfRec, // ROLE_PARAGRAPH
|
|
|
|
eNoRule, // ROLE_RULER
|
|
|
|
eNoRule, // ROLE_AUTOCOMPLETE
|
|
|
|
eNoRule, // ROLE_EDITBAR
|
|
|
|
eFromValue, // ROLE_ENTRY
|
2011-06-23 21:01:45 -07:00
|
|
|
eFromSubtreeIfRec, // ROLE_CAPTION
|
2009-02-18 23:06:14 -08:00
|
|
|
eNoRule, // ROLE_DOCUMENT_FRAME
|
2009-11-06 22:37:51 -08:00
|
|
|
eFromSubtreeIfRec, // ROLE_HEADING
|
2009-02-18 23:06:14 -08:00
|
|
|
eNoRule, // ROLE_PAGE
|
|
|
|
eFromSubtreeIfRec, // ROLE_SECTION
|
|
|
|
eNoRule, // ROLE_REDUNDANT_OBJECT
|
|
|
|
eNoRule, // ROLE_FORM
|
|
|
|
eNoRule, // ROLE_IME
|
|
|
|
eNoRule, // ROLE_APP_ROOT
|
|
|
|
eFromSubtree, // ROLE_PARENT_MENUITEM
|
|
|
|
eNoRule, // ROLE_CALENDAR
|
|
|
|
eNoRule, // ROLE_COMBOBOX_LIST
|
|
|
|
eFromSubtree, // ROLE_COMBOBOX_OPTION
|
|
|
|
eNoRule, // ROLE_IMAGE_MAP
|
|
|
|
eFromSubtree, // ROLE_OPTION
|
|
|
|
eFromSubtree, // ROLE_RICH_OPTION
|
|
|
|
eNoRule, // ROLE_LISTBOX
|
|
|
|
eNoRule, // ROLE_FLAT_EQUATION
|
|
|
|
eFromSubtree // ROLE_GRID_CELL
|
|
|
|
};
|