Bug 460932 - text-indent and text-align should really be object attributes, r=aaronlev, marcoz

This commit is contained in:
Alexander Surkov 2008-10-28 19:54:57 +08:00
parent bbeddbbb52
commit f1793770dc
9 changed files with 224 additions and 219 deletions

View File

@ -157,7 +157,6 @@ ACCESSIBILITY_ATOM(anonid, "anonid") // Used for ID's in XBL
ACCESSIBILITY_ATOM(contenteditable, "contenteditable")
ACCESSIBILITY_ATOM(control, "control")
ACCESSIBILITY_ATOM(disabled, "disabled")
ACCESSIBILITY_ATOM(display, "display")
ACCESSIBILITY_ATOM(_class, "class")
ACCESSIBILITY_ATOM(cycles, "cycles") // used for XUL cycler attribute
ACCESSIBILITY_ATOM(curpos, "curpos") // XUL
@ -187,6 +186,11 @@ ACCESSIBILITY_ATOM(tooltiptext, "tooltiptext")
ACCESSIBILITY_ATOM(type, "type")
ACCESSIBILITY_ATOM(value, "value")
// Alphabetical list of object attributes
ACCESSIBILITY_ATOM(display, "display")
ACCESSIBILITY_ATOM(textAlign, "text-align")
ACCESSIBILITY_ATOM(textIndent, "text-indent")
// Alphabetical list of text attributes (AT API)
ACCESSIBILITY_ATOM(backgroundColor, "background-color")
ACCESSIBILITY_ATOM(invalid, "invalid")

View File

@ -2182,13 +2182,28 @@ nsAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
}
// Expose 'display' attribute.
nsAutoString displayValue;
nsAutoString value;
nsresult rv = GetComputedStyleValue(EmptyString(),
NS_LITERAL_STRING("display"),
displayValue);
value);
if (NS_SUCCEEDED(rv))
nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::display,
displayValue);
value);
// Expose 'text-align' attribute.
rv = GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("text-align"),
value);
if (NS_SUCCEEDED(rv))
nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::textAlign,
value);
// Expose 'text-indent' attribute.
rv = GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("text-indent"),
value);
if (NS_SUCCEEDED(rv))
nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::textIndent,
value);
return NS_OK;
}

View File

@ -87,8 +87,6 @@ static nsCSSTextAttrMapItem gCSSTextAttrsMap[] = {
{ "font-weight", kAnyValue, kCopyName, kCopyValue },
{ "text-decoration", "line-through", "text-line-through-style", "solid" },
{ "text-decoration", "underline", "text-underline-style", "solid" },
{ "text-align", kAnyValue, kCopyName, kCopyValue },
{ "text-indent", kAnyValue, kCopyName, kCopyValue },
{ "vertical-align", kAnyValue, "text-position", kCopyValue }
};

View File

@ -48,6 +48,7 @@ include $(topsrcdir)/config/rules.mk
_TEST_FILES =\
moz.png \
longdesc_src.html \
attributes.js \
common.js \
nsIAccessible_actions.js \
nsIAccessible_name.css \

View File

@ -0,0 +1,141 @@
////////////////////////////////////////////////////////////////////////////////
// Object attributes.
/**
* Test object attributes.
*
* @param aID [in] the ID of DOM element having accessible
* @param aAttrs [in] the map of expected object attributes
* (name/value pairs)
* @param aSkipUnexpectedAttrs [in] points this function doesn't fail if
* unexpected attribute is encountered
*/
function testAttrs(aID, aAttrs, aSkipUnexpectedAttrs)
{
var accessible = getAccessible(aID);
if (!accessible)
return;
var attrs = null;
try {
attrs = accessible.attributes;
} catch (e) { }
if (!attrs) {
ok(false, "Can't get object attributes for " + aID);
return;
}
var errorMsg = " for " + aID;
compareAttrs(errorMsg, attrs, aAttrs, aSkipUnexpectedAttrs);
}
////////////////////////////////////////////////////////////////////////////////
// Text attributes.
/**
* Test text attributes.
*
* @param aID [in] the ID of DOM element having text
* accessible
* @param aOffset [in] the offset inside text accessible to fetch
* text attributes
* @param aAttrs [in] the map of expected text attributes
* (name/value pairs)
* @param aStartOffset [in] expected start offset where text attributes
* are applied
* @param aEndOffset [in] expected end offset where text attribute
* are applied
* @param aSkipUnexpectedAttrs [in] points the function doesn't fail if
* unexpected attribute is encountered
*/
function testTextAttrs(aID, aOffset, aAttrs, aStartOffset, aEndOffset,
aSkipUnexpectedAttrs)
{
var accessible = getAccessible(aID, [nsIAccessibleText]);
if (!accessible)
return;
var startOffset = { value: -1 };
var endOffset = { value: -1 };
var attrs = null;
try {
attrs = accessible.getTextAttributes(false, aOffset,
startOffset, endOffset);
} catch (e) {
}
if (!attrs) {
ok(false, "Can't get text attributes for " + aID);
return;
}
var errorMsg = " for " + aID + " at offset " + aOffset;
is(startOffset.value, aStartOffset, "Wrong start offset" + errorMsg);
is(endOffset.value, aEndOffset, "Wrong end offset" + errorMsg);
compareAttrs(errorMsg, attrs, aAttrs, aSkipUnexpectedAttrs);
}
/**
* Test default text attributes.
*
* @param aID [in] the ID of DOM element having text
* accessible
* @param aDefAttrs [in] the map of expected text attributes
* (name/value pairs)
* @param aSkipUnexpectedAttrs [in] points the function doesn't fail if
* unexpected attribute is encountered
*/
function testDefaultTextAttrs(aID, aDefAttrs, aSkipUnexpectedAttrs)
{
var accessible = getAccessible(aID, [nsIAccessibleText]);
if (!accessible)
return;
var defAttrs = null;
try{
defAttrs = accessible.defaultTextAttributes;
} catch (e) {
}
if (!defAttrs) {
ok(false, "Can't get default text attributes for " + aID);
return;
}
var errorMsg = ". Getting default text attributes for " + aID;
compareAttrs(errorMsg, defAttrs, aDefAttrs, aSkipUnexpectedAttrs);
}
////////////////////////////////////////////////////////////////////////////////
// Private.
function compareAttrs(aErrorMsg, aAttrs, aExpectedAttrs, aSkipUnexpectedAttrs)
{
var enumerate = aAttrs.enumerate();
while (enumerate.hasMoreElements()) {
var prop = enumerate.getNext().QueryInterface(nsIPropertyElement);
if (!(prop.key in aExpectedAttrs)) {
if (!aSkipUnexpectedAttrs)
ok(false, "Unexpected attribute '" + prop.key + "' having '" +
prop.value + "'" + aErrorMsg);
} else {
is(prop.value, aExpectedAttrs[prop.key],
"Attribute '" + prop.key + " 'has wrong value" + aErrorMsg);
}
}
for (var name in aExpectedAttrs) {
var value = "";
try {
value = aAttrs.getStringProperty(name);
} catch(e) { }
if (!value)
ok(false,
"There is no expected attribute '" + name + "' " + aErrorMsg);
}
}

View File

@ -29,6 +29,7 @@ const nsIAccessibleValue = Components.interfaces.nsIAccessibleValue;
const nsIObserverService = Components.interfaces.nsIObserverService;
const nsIDOMNode = Components.interfaces.nsIDOMNode;
const nsIPropertyElement = Components.interfaces.nsIPropertyElement;
////////////////////////////////////////////////////////////////////////////////
// Roles

View File

@ -1,57 +1,46 @@
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=439566
https://bugzilla.mozilla.org/show_bug.cgi?id=460932
-->
<head>
<title>CSS-like attributes tests</title>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<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>
<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>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/attributes.js"></script>
<script type="application/javascript">
const nsIAccessibleRetrieval = Components.interfaces.nsIAccessibleRetrieval;
var gAccRetrieval = null;
function testAttr(aID, aName, aValue)
function testCSSAttrs(aID)
{
var acc = null;
try {
acc = gAccRetrieval.getAccessibleFor(document.getElementById(aID));
} catch(e) { }
var node = document.getElementById(aID);
var computedStyle = document.defaultView.getComputedStyle(node, "");
if (!acc) {
ok(false, "Can't get accessible object for " + aID);
return;
}
var attrs = null;
try {
attrs = acc.attributes;
} catch(e) { }
if (!attrs) {
ok(false, "Can't get accessible attributes for " + aID);
return;
}
is(attrs.getStringProperty(aName), aValue,
"Accessible with ID " + aID + " has wrong attribute value");
var attrs = {
"display": computedStyle.display,
"text-align": computedStyle.textAlign,
"text-indent": computedStyle.textIndent
};
testAttrs(aID, attrs, true);
}
function doTest()
{
gAccRetrieval = Components.classes["@mozilla.org/accessibleRetrieval;1"].
getService(nsIAccessibleRetrieval);
testAttr("span", "display", "inline");
testAttr("div", "display", "block");
testAttr("p", "display", "block");
testAttr("input", "display", "inline");
testAttr("table", "display", "table");
testAttr("tr", "display", "table-row");
testAttr("td", "display", "table-cell");
testCSSAttrs("span");
testCSSAttrs("div");
testCSSAttrs("p");
testCSSAttrs("input");
testCSSAttrs("table");
testCSSAttrs("tr");
testCSSAttrs("td");
SimpleTest.finish();
}
@ -67,6 +56,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=439566
title="Include the css display property as an IAccessible2 object attribute">
Mozilla Bug 439566
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=460932"
title="text-indent and text-align should really be object attribute">
Mozilla Bug 460932
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">

View File

@ -10,43 +10,29 @@
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="chrome://mochikit/content/a11y/accessible/common.js" />
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/attributes.js" />
<script type="application/javascript">
<![CDATA[
var gAccService = null;
function accAttributes(aId)
{
this.getAttribute = function getAttribute(aName)
{
try {
return this.mAttrs.getStringProperty(aName);
} catch (e) {
return "";
}
}
this.mAcc = gAccService.getAccessibleFor(document.getElementById(aId));
ok(this.mAcc, "Can't get accessible for " + aId);
if (this.mAcc)
this.mAttrs = this.mAcc.attributes;
}
function testGroupAttrs(aID, aPosInSet, aSetSize, aLevel)
{
var attrs = new accAttributes(aID);
is(attrs.getAttribute("posinset"), aPosInSet, "Wrong posinset on " + aID);
is(attrs.getAttribute("setsize"), aSetSize, "Wrong setsize on " + aID);
var attrs = {
"posinset": aPosInSet,
"setsize": aSetSize
};
if (aLevel)
is(attrs.getAttribute("level"), aLevel, "Wrong level on " + aID);
attrs["level"] = aLevel;
testAttrs(aID, attrs, true);
}
function doTest()
{
// Activate accessibility, otherwise events aren't fired.
gAccService = Components.classes["@mozilla.org/accessibleRetrieval;1"].
getService(Components.interfaces.nsIAccessibleRetrieval);
//////////////////////////////////////////////////////////////////////////
// xul:listbox (bug 417317)
testGroupAttrs("item1", "1", "2");

View File

@ -4,140 +4,23 @@
<title>Text attributes tests</title>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<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>
<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>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/attributes.js"></script>
<script type="application/javascript">
const nsIAccessibleRetrieval = Components.interfaces.nsIAccessibleRetrieval;
const nsIAccessibleText = Components.interfaces.nsIAccessibleText;
const nsIAccessibleEvent = Components.interfaces.nsIAccessibleEvent;
const nsIDOMNSEditableElement =
Components.interfaces.nsIDOMNSEditableElement;
const nsIObserverService = Components.interfaces.nsIObserverService;
var gAccRetrieval = null;
var gComputedStyle = null;
/**
* Test text attributes.
*
* @param aID the ID of DOM element having text accessible
* @param aOffset the offset inside text accessible to fetch
* text attributes
* @param aAttrs the map of text attributes (name/value pairs)
* @param aStartOffset the start offset where text attributes are
* applied
* @param aEndOffset the end offset where text attribute are applied
*/
function testTextAttrs(aID, aOffset,
aAttrs, aStartOffset, aEndOffset)
{
var accessible = getTextAccessible(aID);
if (!accessible)
return;
var startOffset = { value: -1 };
var endOffset = { value: -1 };
var attrs = null;
try {
attrs = accessible.getTextAttributes(false,
aOffset,
startOffset, endOffset);
} catch (e) {
}
if (!attrs) {
ok(false, "Can't get text attributes for " + aID);
return;
}
var errorMsg = " for " + aID + " at offset " + aOffset;
is(startOffset.value, aStartOffset,
"Wrong start offset" + errorMsg);
is(endOffset.value, aEndOffset,
"Wrong end offset" + errorMsg);
compareTextAttrs(errorMsg, attrs, aAttrs);
}
/**
* Test default text attributes.
*
* @param aID the ID of DOM element having text accessible
* @param aDefAttrs the list of default text attributes (name/value
* pairs)
*/
function testDefaultTextAttrs(aID, aDefAttrs)
{
var accessible = getTextAccessible(aID);
if (!accessible)
return;
var defAttrs = null;
try{
defAttrs = accessible.defaultTextAttributes;
} catch (e) {
}
if (!defAttrs) {
ok(false, "Can't get default attributes for " + aID);
return;
}
var errorMsg = ". Getting default attributes for " + aID;
compareTextAttrs(errorMsg, defAttrs, aDefAttrs);
}
function getTextAccessible(aID)
{
var node = document.getElementById(aID);
if (!node) {
ok(false, "Can't get the element with ID " + aID);
return;
}
var accessible = null;
try {
accessible = gAccRetrieval.getAccessibleFor(node);
accessible.QueryInterface(nsIAccessibleText);
} catch (e) {
}
if (!accessible)
ok(false, "Can't query nsIAccessibleText interface for " + aID);
return accessible;
}
function compareTextAttrs(aErrorMsg, aAttrs, aExpectedAttrs)
{
var enumerate = aAttrs.enumerate();
while (enumerate.hasMoreElements()) {
var prop = enumerate.getNext().
QueryInterface(Components.interfaces.nsIPropertyElement);
if (!(prop.key in aExpectedAttrs))
ok(false,
"Unexpected attribute '" + prop.key + "' having '" + prop.value + "'" + aErrorMsg);
else
is(prop.value, aExpectedAttrs[prop.key],
"Attribute '" + prop.key + " 'has wrong value" + aErrorMsg);
}
for (var name in aExpectedAttrs) {
var value = "";
try {
value = aAttrs.getStringProperty(name);
} catch(e) {
}
if (!value)
ok(false,
"There is no expected attribute '" + name + "' " + aErrorMsg);
}
}
var gObserverService = null;
var gA11yEventObserver = null;
@ -161,7 +44,7 @@
// Add accessibility event listeners
var gObserverService = Components.classes["@mozilla.org/observer-service;1"].
getService(nsIObserverService);
getService(nsIObserverService);
gObserverService.addObserver(gA11yEventObserver, "accessible-event",
false);
@ -180,11 +63,9 @@
gComputedStyle = document.defaultView.getComputedStyle(node, "");
var defAttrs = {
"font-style": gComputedStyle.fontStyle,
"text-align": gComputedStyle.textAlign,
"font-size": gComputedStyle.fontSize,
"background-color": gComputedStyle.backgroundColor,
"font-weight": gComputedStyle.fontWeight,
"text-indent": gComputedStyle.textIndent,
"color": gComputedStyle.color,
"font-family": gComputedStyle.fontFamily,
"text-position": gComputedStyle.verticalAlign
@ -214,9 +95,6 @@
function doTest()
{
gAccRetrieval = Components.classes["@mozilla.org/accessibleRetrieval;1"].
getService(nsIAccessibleRetrieval);
//////////////////////////////////////////////////////////////////////////
// area1
var ID = "area1";
@ -224,11 +102,9 @@
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
var defAttrs = {
"font-style": gComputedStyle.fontStyle,
"text-align": gComputedStyle.textAlign,
"font-size": gComputedStyle.fontSize,
"background-color": "rgb(0, 0, 0)", // XXX 455834
"font-weight": gComputedStyle.fontWeight,
"text-indent": gComputedStyle.textIndent,
"color": gComputedStyle.color,
"font-family": gComputedStyle.fontFamily,
"text-position": gComputedStyle.verticalAlign
@ -254,11 +130,9 @@
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
defAttrs = {
"font-style": gComputedStyle.fontStyle,
"text-align": gComputedStyle.textAlign,
"font-size": gComputedStyle.fontSize,
"background-color": "rgb(0, 0, 0)", // XXX bug 455834
"font-weight": gComputedStyle.fontWeight,
"text-indent": gComputedStyle.textIndent,
"color": gComputedStyle.color,
"font-family": gComputedStyle.fontFamily,
"text-position": gComputedStyle.verticalAlign
@ -295,11 +169,9 @@
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
defAttrs = {
"font-style": gComputedStyle.fontStyle,
"text-align": gComputedStyle.textAlign,
"font-size": gComputedStyle.fontSize,
"background-color": gComputedStyle.backgroundColor,
"font-weight": gComputedStyle.fontWeight,
"text-indent": gComputedStyle.textIndent,
"color": gComputedStyle.color,
"font-family": gComputedStyle.fontFamily,
"text-position": gComputedStyle.verticalAlign
@ -335,11 +207,9 @@
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
defAttrs = {
"font-style": gComputedStyle.fontStyle,
"text-align": gComputedStyle.textAlign,
"font-size": gComputedStyle.fontSize,
"background-color": "rgb(0, 0, 0)", // XXX bug 455834
"font-weight": gComputedStyle.fontWeight,
"text-indent": gComputedStyle.textIndent,
"color": gComputedStyle.color,
"font-family": gComputedStyle.fontFamily,
"text-position": gComputedStyle.verticalAlign
@ -369,11 +239,9 @@
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
defAttrs = {
"font-style": gComputedStyle.fontStyle,
"text-align": gComputedStyle.textAlign,
"font-size": gComputedStyle.fontSize,
"background-color": "rgb(0, 0, 0)", // XXX bug 455834
"font-weight": gComputedStyle.fontWeight,
"text-indent": gComputedStyle.textIndent,
"color": gComputedStyle.color,
"font-family": gComputedStyle.fontFamily,
"text-position": gComputedStyle.verticalAlign
@ -404,11 +272,9 @@
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
defAttrs = {
"font-style": gComputedStyle.fontStyle,
"text-align": gComputedStyle.textAlign,
"font-size": gComputedStyle.fontSize,
"background-color": "rgb(0, 0, 0)", // XXX bug 455834
"font-weight": gComputedStyle.fontWeight,
"text-indent": gComputedStyle.textIndent,
"color": gComputedStyle.color,
"font-family": gComputedStyle.fontFamily,
"text-position": gComputedStyle.verticalAlign
@ -457,11 +323,9 @@
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
defAttrs = {
"font-style": gComputedStyle.fontStyle,
"text-align": gComputedStyle.textAlign,
"font-size": gComputedStyle.fontSize,
"background-color": "rgb(0, 0, 0)", // XXX 455834
"font-weight": gComputedStyle.fontWeight,
"text-indent": gComputedStyle.textIndent,
"color": gComputedStyle.color,
"font-family": gComputedStyle.fontFamily,
"text-position": gComputedStyle.verticalAlign