зеркало из https://github.com/mozilla/gecko-dev.git
Bug 452161 – pyatspi insertText doesn't work in empty textboxes, r=aaronlev, MarcoZ
This commit is contained in:
Родитель
151a371207
Коммит
f9c6f47571
|
@ -735,6 +735,30 @@ nsHyperTextAccessible::HypertextOffsetsToDOMRange(PRInt32 aStartHTOffset,
|
|||
NS_ENSURE_ARG_POINTER(aEndOffset);
|
||||
*aEndOffset = -1;
|
||||
|
||||
// If the given offsets are 0 and associated editor is empty then return
|
||||
// collapsed range with editor root element as range container.
|
||||
if (aStartHTOffset == 0 && aEndHTOffset == 0) {
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
GetAssociatedEditor(getter_AddRefs(editor));
|
||||
if (editor) {
|
||||
PRBool isEmpty = PR_FALSE;
|
||||
editor->GetDocumentIsEmpty(&isEmpty);
|
||||
if (isEmpty) {
|
||||
nsCOMPtr<nsIDOMElement> editorRootElm;
|
||||
editor->GetRootElement(getter_AddRefs(editorRootElm));
|
||||
|
||||
nsCOMPtr<nsIDOMNode> editorRoot(do_QueryInterface(editorRootElm));
|
||||
if (editorRoot) {
|
||||
*aStartOffset = *aEndOffset = 0;
|
||||
NS_ADDREF(*aStartNode = editorRoot);
|
||||
NS_ADDREF(*aEndNode = editorRoot);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAccessible> startAcc, endAcc;
|
||||
PRInt32 startOffset = aStartHTOffset, endOffset = aEndHTOffset;
|
||||
nsIFrame *startFrame = nsnull, *endFrame = nsnull;
|
||||
|
|
|
@ -48,9 +48,11 @@ include $(topsrcdir)/config/rules.mk
|
|||
_TEST_FILES =\
|
||||
moz.png \
|
||||
longdesc_src.html \
|
||||
common.js \
|
||||
nsIAccessible_actions.js \
|
||||
nsIAccessible_name.css \
|
||||
nsIAccessible_name.xbl \
|
||||
nsIAccessibleEditableText.js \
|
||||
test_aria_activedescendant.html \
|
||||
test_aria_role_article.html \
|
||||
test_bug368835.xul \
|
||||
|
@ -62,16 +64,17 @@ _TEST_FILES =\
|
|||
test_nsIAccessible_actions.xul \
|
||||
test_nsIAccessible_name.html \
|
||||
test_nsIAccessible_name.xul \
|
||||
test_nsIAccessibleDocument.html \
|
||||
test_nsIAccessibleEditableText.html \
|
||||
test_nsIAccessibleHyperLink.html \
|
||||
test_nsIAccessibleHyperLink.xul \
|
||||
test_nsIAccessibleHyperText.html \
|
||||
test_nsIAccessibleImage.html \
|
||||
test_nsIAccessibleTable_1.html \
|
||||
test_nsIAccessibleTable_2.html \
|
||||
test_nsIAccessibleTable_3.html \
|
||||
test_nsIAccessibleTable_4.html \
|
||||
test_nsIAccessibleTable_listboxes.xul \
|
||||
test_nsIAccessibleDocument.html \
|
||||
test_nsIAccessibleHyperLink.html \
|
||||
test_nsIAccessibleHyperLink.xul \
|
||||
test_nsIAccessibleHyperText.html \
|
||||
test_nsIAccessibleImage.html \
|
||||
test_nsOuterDocAccessible.html \
|
||||
test_textattrs.html \
|
||||
test_textboxes.html \
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Interfaces
|
||||
|
||||
const nsIAccessibleRetrieval = Components.interfaces.nsIAccessibleRetrieval;
|
||||
|
||||
const nsIAccessibleEvent = Components.interfaces.nsIAccessibleEvent;
|
||||
const nsIAccessibleStates = Components.interfaces.nsIAccessibleStates;
|
||||
const nsIAccessibleRole = Components.interfaces.nsIAccessibleRole;
|
||||
const nsIAccessibleTypes = Components.interfaces.nsIAccessibleTypes;
|
||||
|
||||
const nsIAccessibleRelation = Components.interfaces.nsIAccessibleRelation;
|
||||
|
||||
const nsIAccessNode = Components.interfaces.nsIAccessNode;
|
||||
const nsIAccessible = Components.interfaces.nsIAccessible;
|
||||
|
||||
const nsIAccessibleDocument = Components.interfaces.nsIAccessibleDocument;
|
||||
|
||||
const nsIAccessibleText = Components.interfaces.nsIAccessibleText;
|
||||
const nsIAccessibleEditableText = Components.interfaces.nsIAccessibleEditableText;
|
||||
|
||||
const nsIAccessibleHyperLink = Components.interfaces.nsIAccessibleHyperLink;
|
||||
const nsIAccessibleHyperText = Components.interfaces.nsIAccessibleHyperText;
|
||||
|
||||
const nsIAccessibleImage = Components.interfaces.nsIAccessibleImage;
|
||||
const nsIAccessibleSelectable = Components.interfaces.nsIAccessibleSelectable;
|
||||
const nsIAccessibleTable = Components.interfaces.nsIAccessibleTable;
|
||||
const nsIAccessibleValue = Components.interfaces.nsIAccessibleValue;
|
||||
|
||||
const nsIObserverService = Components.interfaces.nsIObserverService;
|
||||
|
||||
const nsIDOMNode = Components.interfaces.nsIDOMNode;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// General
|
||||
|
||||
/**
|
||||
* nsIAccessibleRetrieval, initialized when test is loaded.
|
||||
*/
|
||||
var gAccRetrieval = null;
|
||||
|
||||
/**
|
||||
* Return accessible for the given ID attribute or DOM element.
|
||||
*
|
||||
* @param aElmOrID [in] the ID attribute or DOM element to get an accessible
|
||||
* for
|
||||
* @param aInterfaces [in, optional] the accessible interface or the array of
|
||||
* accessible interfaces to query it/them from obtained
|
||||
* accessible
|
||||
* @param aElmObj [out, optional] object to store DOM element which
|
||||
* accessible is created for
|
||||
*/
|
||||
function getAccessible(aElmOrID, aInterfaces, aElmObj)
|
||||
{
|
||||
var elm = null;
|
||||
|
||||
if (aElmOrID instanceof nsIDOMNode) {
|
||||
elm = aElmOrID;
|
||||
} else {
|
||||
var elm = document.getElementById(aElmOrID);
|
||||
if (!elm) {
|
||||
ok(false, "Can't get DOM element for " + aID);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (aElmObj && (typeof aElmObj == "object"))
|
||||
aElmObj.value = elm;
|
||||
|
||||
var acc = null;
|
||||
try {
|
||||
acc = gAccRetrieval.getAccessibleFor(elm);
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
if (!acc) {
|
||||
ok(false, "Can't get accessible for " + aID);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!aInterfaces)
|
||||
return acc;
|
||||
|
||||
if (aInterfaces instanceof Array) {
|
||||
for (var index = 0; index < aInterfaces.length; index++) {
|
||||
try {
|
||||
acc.QueryInterface(aInterfaces[index]);
|
||||
} catch (e) {
|
||||
ok(false, "Can't query " + aInterfaces[index] + " for " + aID);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return acc;
|
||||
}
|
||||
|
||||
try {
|
||||
acc.QueryInterface(aInterfaces);
|
||||
} catch (e) {
|
||||
ok(false, "Can't query " + aInterfaces + " for " + aID);
|
||||
return null;
|
||||
}
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Private
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// General
|
||||
|
||||
function initialize()
|
||||
{
|
||||
gAccRetrieval = Components.classes["@mozilla.org/accessibleRetrieval;1"].
|
||||
getService(nsIAccessibleRetrieval);
|
||||
}
|
||||
|
||||
addLoadEvent(initialize);
|
|
@ -0,0 +1,105 @@
|
|||
function nsEditableText(aElmOrID)
|
||||
{
|
||||
this.setTextContents = function setTextContents(aStr)
|
||||
{
|
||||
try {
|
||||
this.mAcc.setTextContents(aStr);
|
||||
|
||||
is(this.getValue(), aStr,
|
||||
"setTextContents: Can't set " + aStr +
|
||||
" to element with ID '" + this.mID + "'");
|
||||
} catch (e) {
|
||||
ok(false,
|
||||
"setTextContents: Can't set " + aStr +
|
||||
"to element with ID '" + this.mID +
|
||||
"', value '" + this.getValue() + "', exception" + e);
|
||||
}
|
||||
}
|
||||
|
||||
this.insertText = function insertText(aStr, aPos, aResStr)
|
||||
{
|
||||
try {
|
||||
this.mAcc.insertText(aStr, aPos);
|
||||
|
||||
is(this.getValue(), aResStr,
|
||||
"insertText: Can't insert " + aStr + " at " + aPos +
|
||||
" to element with ID '" + this.mID + "'");
|
||||
} catch (e) {
|
||||
ok(false,
|
||||
"insertText: Can't insert " + aStr + " at " + aPos +
|
||||
" to element with ID '" + this.mID +
|
||||
"', value '" + this.getValue() + "', exception " + e);
|
||||
}
|
||||
}
|
||||
|
||||
this.copyNPasteText = function copyNPasteText(aStartPos, aEndPos,
|
||||
aPos, aResStr)
|
||||
{
|
||||
try {
|
||||
this.mAcc.copyText(aStartPos, aEndPos);
|
||||
this.mAcc.pasteText(aPos);
|
||||
|
||||
is(this.getValue(), aResStr,
|
||||
"copyText & pasteText: Can't copy text from " + aStartPos +
|
||||
" to " + aEndPos + " and paste to " + aPos +
|
||||
" for element with ID '" + this.mID + "'");
|
||||
} catch (e) {
|
||||
ok(false,
|
||||
"copyText & pasteText: Can't copy text from " + aStartPos +
|
||||
" to " + aEndPos + " and paste to " + aPos +
|
||||
" for element with ID '" + this.mID +
|
||||
"', value '" + this.getValue() + "', exception " + e);
|
||||
}
|
||||
}
|
||||
|
||||
this.cutNPasteText = function copyNPasteText(aStartPos, aEndPos,
|
||||
aPos, aResStr)
|
||||
{
|
||||
try {
|
||||
this.mAcc.cutText(aStartPos, aEndPos);
|
||||
this.mAcc.pasteText(aPos);
|
||||
|
||||
is(this.getValue(), aResStr,
|
||||
"cutText & pasteText: Can't cut text from " + aStartPos +
|
||||
" to " + aEndPos + " and paste to " + aPos +
|
||||
" for element with ID '" + this.mID + "'");
|
||||
} catch (e) {
|
||||
ok(false,
|
||||
"cutText & pasteText: Can't cut text from " + aStartPos +
|
||||
" to " + aEndPos + " and paste to " + aPos +
|
||||
" for element with ID '" + this.mID +
|
||||
"', value '" + this.getValue() + "', exception " + e);
|
||||
}
|
||||
}
|
||||
|
||||
this.deleteText = function deleteText(aStartPos, aEndPos, aResStr)
|
||||
{
|
||||
try {
|
||||
this.mAcc.deleteText(aStartPos, aEndPos);
|
||||
|
||||
is(this.getValue(), aResStr,
|
||||
"deleteText: Can't delete text from " + aStartPos +
|
||||
" to " + aEndPos + " for element with ID '" + this.mID + "'");
|
||||
} catch (e) {
|
||||
ok(false,
|
||||
"deleteText: Can't delete text from " + aStartPos +
|
||||
" to " + aEndPos + " for element with ID '" + this.mID +
|
||||
"', value " + this.getValue() + ", exception " + e);
|
||||
}
|
||||
}
|
||||
|
||||
this.getValue = function getValue()
|
||||
{
|
||||
if (this.mElm instanceof Components.interfaces.nsIDOMNSEditableElement)
|
||||
return this.mElm.value;
|
||||
if (this.mElm instanceof Components.interfaces.nsIDOMHTMLDocument)
|
||||
return this.mElm.body.textContent;
|
||||
return this.mElm.textContent;
|
||||
}
|
||||
|
||||
var elmObj = { value: null };
|
||||
this.mAcc = getAccessible(aElmOrID, nsIAccessibleEditableText, elmObj);
|
||||
|
||||
this.mElm = elmObj.value;
|
||||
this.mID = aElmOrID;
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=452161
|
||||
-->
|
||||
<head>
|
||||
<title>nsIAccessibleEditableText chrome 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/a11y/accessible/common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/nsIAccessibleEditableText.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
var gParagraphAcc;
|
||||
|
||||
function testEditable(aID)
|
||||
{
|
||||
var et = new nsEditableText(aID);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// insertText
|
||||
et.insertText("hello", 0, "hello");
|
||||
et.insertText("ma ", 0, "ma hello");
|
||||
et.insertText("ma", 2, "mama hello");
|
||||
et.insertText(" hello", 10, "mama hello hello");
|
||||
|
||||
// XXX: bug 452584
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// setTextContents
|
||||
// et.setTextContents("hello", "hello");
|
||||
// et.setTextContents("olleh", "olleh");
|
||||
// et.setTextContents("", "");
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// deleteText
|
||||
// et.deleteText(0, 5, "hello hello");
|
||||
// et.deleteText(5, 6, "hellohello");
|
||||
// et.deleteText(5, 10, "hello");
|
||||
// et.deleteText(0, 5, "");
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// copyNPasteText
|
||||
// et.copyNPasteText(0, 0, 0, "");
|
||||
// et.insertText("hello", 0, "hello");
|
||||
// et.copyNPasteText(0, 1, 0, "hhello");
|
||||
// et.copyNPasteText(5, 6, 6, "hhelloo");
|
||||
// et.copyNPasteText(3, 4, 1, "hehelloo");
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// // cutNPasteText
|
||||
// et.cutNPasteText(0, 1, 1, "ehhelloo");
|
||||
// et.cutNPasteText(1, 2, 0, "hehelloo");
|
||||
// et.cutNPasteText(7, 8, 8, "hehelloo");
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
testEditable("input");
|
||||
// testEditable("div"); XXX: bug 452599
|
||||
|
||||
var frame = document.getElementById("frame");
|
||||
frame.contentDocument.designMode = "on";
|
||||
testEditable(frame.contentDocument);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
title="nsIAccessibleEditableText chrome tests"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=452161">Mozilla Bug 452161</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<input id="input"/>
|
||||
|
||||
<div id="div" contentEditable="true"/>
|
||||
|
||||
<iframe id="frame"/>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче