mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-03 20:49:27 +00:00
Bug 606082 - update accessible tree when root element is changed, r=marcoz, davidb, bz, a=blocking
This commit is contained in:
parent
c22068623c
commit
a015a8fcc2
@ -156,7 +156,7 @@ public:
|
||||
*/
|
||||
virtual nsINode* GetNode() const { return mContent; }
|
||||
nsIContent* GetContent() const { return mContent; }
|
||||
nsIDocument* GetDocumentNode() const
|
||||
virtual nsIDocument* GetDocumentNode() const
|
||||
{ return mContent ? mContent->GetOwnerDoc() : nsnull; }
|
||||
|
||||
/**
|
||||
|
@ -477,32 +477,33 @@ nsAccessibilityService::ContentRangeInserted(nsIPresShell* aPresShell,
|
||||
nsIContent* aStartChild,
|
||||
nsIContent* aEndChild)
|
||||
{
|
||||
#ifdef DEBUG_A11Y
|
||||
#ifdef DEBUG_CONTENTMUTATION
|
||||
nsAutoString tag;
|
||||
aStartChild->Tag()->ToString(tag);
|
||||
nsIAtom* id = aStartChild->GetID();
|
||||
nsCAutoString strid;
|
||||
if (id)
|
||||
id->ToUTF8String(strid);
|
||||
|
||||
nsIAtom* atomid = aStartChild->GetID();
|
||||
nsCAutoString id;
|
||||
if (atomid)
|
||||
atomid->ToUTF8String(id);
|
||||
|
||||
nsAutoString ctag;
|
||||
aContainer->Tag()->ToString(ctag);
|
||||
nsIAtom* cid = aContainer->GetID();
|
||||
nsCAutoString strcid;
|
||||
if (cid)
|
||||
cid->ToUTF8String(strcid);
|
||||
nsCAutoString cid;
|
||||
nsIAtom* catomid = nsnull;
|
||||
if (aContainer) {
|
||||
aContainer->Tag()->ToString(ctag);
|
||||
catomid = aContainer->GetID();
|
||||
if (catomid)
|
||||
catomid->ToUTF8String(cid);
|
||||
}
|
||||
|
||||
printf("\ncontent inserted: %s@id='%s', container: %s@id='%s', end node: %p\n\n",
|
||||
NS_ConvertUTF16toUTF8(tag).get(), strid.get(),
|
||||
NS_ConvertUTF16toUTF8(ctag).get(), strcid.get(), aEndChild);
|
||||
NS_ConvertUTF16toUTF8(tag).get(), id.get(),
|
||||
NS_ConvertUTF16toUTF8(ctag).get(), cid.get(), aEndChild);
|
||||
#endif
|
||||
|
||||
// XXX: bug 606082. aContainer is null when root element is inserted into
|
||||
// document, we need to handle this and update the tree, also we need to
|
||||
// update a content node of the document accessible.
|
||||
if (aContainer) {
|
||||
nsDocAccessible* docAccessible = GetDocAccessible(aPresShell->GetDocument());
|
||||
if (docAccessible)
|
||||
docAccessible->UpdateTree(aContainer, aStartChild, aEndChild, PR_TRUE);
|
||||
}
|
||||
nsDocAccessible* docAccessible = GetDocAccessible(aPresShell->GetDocument());
|
||||
if (docAccessible)
|
||||
docAccessible->UpdateTree(aContainer, aStartChild, aEndChild, PR_TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
@ -510,21 +511,34 @@ nsAccessibilityService::ContentRemoved(nsIPresShell* aPresShell,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild)
|
||||
{
|
||||
#ifdef DEBUG_A11Y
|
||||
nsAutoString id;
|
||||
aChild->Tag()->ToString(id);
|
||||
printf("\ncontent removed: %s\n", NS_ConvertUTF16toUTF8(id).get());
|
||||
#ifdef DEBUG_CONTENTMUTATION
|
||||
nsAutoString tag;
|
||||
aChild->Tag()->ToString(tag);
|
||||
|
||||
nsIAtom* atomid = aChild->GetID();
|
||||
nsCAutoString id;
|
||||
if (atomid)
|
||||
atomid->ToUTF8String(id);
|
||||
|
||||
nsAutoString ctag;
|
||||
nsCAutoString cid;
|
||||
nsIAtom* catomid = nsnull;
|
||||
if (aContainer) {
|
||||
aContainer->Tag()->ToString(ctag);
|
||||
catomid = aContainer->GetID();
|
||||
if (catomid)
|
||||
catomid->ToUTF8String(cid);
|
||||
}
|
||||
|
||||
printf("\ncontent removed: %s@id='%s', container: %s@id='%s'\n\n",
|
||||
NS_ConvertUTF16toUTF8(tag).get(), id.get(),
|
||||
NS_ConvertUTF16toUTF8(ctag).get(), cid.get());
|
||||
#endif
|
||||
|
||||
// XXX: bug 606082. aContainer is null when root element is inserted into
|
||||
// document, we need to handle this and update the tree, perhaps destroy
|
||||
// the document accessible.
|
||||
if (aContainer) {
|
||||
nsDocAccessible* docAccessible = GetDocAccessible(aPresShell->GetDocument());
|
||||
if (docAccessible)
|
||||
docAccessible->UpdateTree(aContainer, aChild, aChild->GetNextSibling(),
|
||||
PR_FALSE);
|
||||
}
|
||||
nsDocAccessible* docAccessible = GetDocAccessible(aPresShell->GetDocument());
|
||||
if (docAccessible)
|
||||
docAccessible->UpdateTree(aContainer, aChild, aChild->GetNextSibling(),
|
||||
PR_FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -285,8 +285,12 @@ nsDocAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
return NS_OK_DEFUNCT_OBJECT;
|
||||
}
|
||||
|
||||
if (aExtraState)
|
||||
*aExtraState = 0;
|
||||
if (aExtraState) {
|
||||
// The root content of the document might be removed so that mContent is
|
||||
// out of date.
|
||||
*aExtraState = (mContent->GetCurrentDoc() == mDocument) ?
|
||||
0 : nsIAccessibleStates::EXT_STATE_STALE;
|
||||
}
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
nsCOMPtr<nsIXULDocument> xulDoc(do_QueryInterface(mDocument));
|
||||
@ -1346,22 +1350,49 @@ nsDocAccessible::UpdateTree(nsIContent* aContainerNode,
|
||||
// Since this information may be not correct then we need to fire some events
|
||||
// regardless the document loading state.
|
||||
|
||||
// Update the whole tree of this document accessible when the container is
|
||||
// null (document element is inserted or removed).
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
|
||||
nsIEventStateManager* esm = presShell->GetPresContext()->EventStateManager();
|
||||
PRBool fireAllEvents = PR_TRUE;//IsContentLoaded() || esm->IsHandlingUserInputExternal();
|
||||
|
||||
// We don't create new accessibles on content removal.
|
||||
nsAccessible* container = aIsInsert ?
|
||||
GetAccService()->GetAccessibleOrContainer(aContainerNode, mWeakShell) :
|
||||
GetAccService()->GetCachedAccessibleOrContainer(aContainerNode);
|
||||
|
||||
// XXX: bug 608887 reconsider accessible tree update logic because
|
||||
// 1) elements appended outside the HTML body don't get accessibles;
|
||||
// 2) the document having elements that should be accessible may function
|
||||
// without body.
|
||||
nsAccessible* container = nsnull;
|
||||
if (aIsInsert) {
|
||||
container = aContainerNode ?
|
||||
GetAccService()->GetAccessibleOrContainer(aContainerNode, mWeakShell) :
|
||||
this;
|
||||
|
||||
// The document children were changed; the root content might be affected.
|
||||
if (container == this) {
|
||||
nsIContent* rootContent = nsCoreUtils::GetRoleContent(mDocument);
|
||||
|
||||
// No root content (for example HTML document element was inserted but no
|
||||
// body). Nothing to update.
|
||||
if (!rootContent)
|
||||
return;
|
||||
|
||||
// New root content has been inserted, update it and update the tree.
|
||||
if (rootContent != mContent)
|
||||
mContent = rootContent;
|
||||
}
|
||||
|
||||
// XXX: Invalidate parent-child relations for container accessible and its
|
||||
// children because there's no good way to find insertion point of new child
|
||||
// accessibles into accessible tree. We need to invalidate children even
|
||||
// there's no inserted accessibles in the end because accessible children
|
||||
// are created while parent recaches child accessibles.
|
||||
container->InvalidateChildren();
|
||||
|
||||
} else {
|
||||
// Don't create new accessibles on content removal.
|
||||
container = aContainerNode ?
|
||||
GetAccService()->GetCachedAccessibleOrContainer(aContainerNode) :
|
||||
this;
|
||||
}
|
||||
|
||||
EIsFromUserInput fromUserInput = esm->IsHandlingUserInputExternal() ?
|
||||
|
@ -108,6 +108,7 @@ public:
|
||||
virtual nsIFrame* GetFrame();
|
||||
virtual PRBool IsDefunct();
|
||||
virtual nsINode* GetNode() const { return mDocument; }
|
||||
virtual nsIDocument* GetDocumentNode() const { return mDocument; }
|
||||
|
||||
// nsAccessible
|
||||
virtual PRUint32 NativeRole();
|
||||
|
@ -38,6 +38,7 @@ const EXT_STATE_EXPANDABLE = nsIAccessibleStates.EXT_STATE_EXPANDABLE;
|
||||
const EXT_STATE_HORIZONTAL = nsIAccessibleStates.EXT_STATE_HORIZONTAL;
|
||||
const EXT_STATE_MULTI_LINE = nsIAccessibleStates.EXT_STATE_MULTI_LINE;
|
||||
const EXT_STATE_SINGLE_LINE = nsIAccessibleStates.EXT_STATE_SINGLE_LINE;
|
||||
const EXT_STATE_STALE = nsIAccessibleStates.EXT_STATE_STALE;
|
||||
const EXT_STATE_SUPPORTS_AUTOCOMPLETION =
|
||||
nsIAccessibleStates.EXT_STATE_SUPPORTS_AUTOCOMPLETION;
|
||||
const EXT_STATE_VERTICAL = nsIAccessibleStates.EXT_STATE_VERTICAL;
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
<script type="application/javascript">
|
||||
function doTest()
|
||||
{
|
||||
{
|
||||
var docAcc = getAccessible(document, [nsIAccessibleDocument]);
|
||||
if (docAcc) {
|
||||
testStates(docAcc, STATE_READONLY);
|
||||
@ -28,6 +28,7 @@
|
||||
|
||||
testStates(docAcc, 0, EXT_STATE_EDITABLE);
|
||||
testStates("article", 0, EXT_STATE_EDITABLE);
|
||||
testStates("article", 0, EXT_STATE_EDITABLE);
|
||||
testStates("editable_article", 0, EXT_STATE_EDITABLE);
|
||||
|
||||
document.designMode = "off";
|
||||
|
@ -46,6 +46,7 @@ include $(DEPTH)/config/autoconf.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES =\
|
||||
test_doc.html \
|
||||
test_list_editabledoc.html \
|
||||
test_list.html \
|
||||
test_recreation.html \
|
||||
|
370
accessible/tests/mochitest/treeupdate/test_doc.html
Normal file
370
accessible/tests/mochitest/treeupdate/test_doc.html
Normal file
@ -0,0 +1,370 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Test document root content mutations</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="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../states.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Helpers
|
||||
|
||||
function getDocNode(aID)
|
||||
{
|
||||
return getNode(aID).contentDocument;
|
||||
}
|
||||
function getDocChildNode(aID)
|
||||
{
|
||||
return getDocNode(aID).body.firstChild;
|
||||
}
|
||||
|
||||
function rootContentReplaced(aID, aTextName)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_SHOW, getDocChildNode, aID),
|
||||
new invokerChecker(EVENT_REORDER, getDocNode, aID)
|
||||
];
|
||||
|
||||
this.finalCheck = function rootContentReplaced_finalCheck()
|
||||
{
|
||||
var tree = {
|
||||
role: ROLE_DOCUMENT,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_TEXT_LEAF,
|
||||
name: aTextName
|
||||
}
|
||||
]
|
||||
};
|
||||
testAccessibleTree(getDocNode(aID), tree);
|
||||
}
|
||||
}
|
||||
|
||||
function rootContentRemoved(aID)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, null),
|
||||
new invokerChecker(EVENT_REORDER, getDocNode, aID)
|
||||
];
|
||||
|
||||
this.preinvoke = function rootContentRemoved_preinvoke()
|
||||
{
|
||||
// Set up target for hide event before we invoke.
|
||||
var text = getAccessible(getAccessible(getDocNode(aID)).firstChild,
|
||||
[nsIAccessNode]).DOMNode;
|
||||
this.eventSeq[0].target = text;
|
||||
}
|
||||
|
||||
this.finalCheck = function rootContentRemoved_finalCheck()
|
||||
{
|
||||
var tree = {
|
||||
role: ROLE_DOCUMENT,
|
||||
states: {
|
||||
// Out of date root content involves stale state presence.
|
||||
states: 0,
|
||||
extraStates: EXT_STATE_STALE
|
||||
},
|
||||
children: [ ]
|
||||
};
|
||||
testAccessibleTree(getDocNode(aID), tree);
|
||||
}
|
||||
}
|
||||
|
||||
function rootContentInserted(aID, aTextName)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_SHOW, getDocChildNode, aID),
|
||||
new invokerChecker(EVENT_REORDER, getDocNode, aID)
|
||||
];
|
||||
|
||||
this.finalCheck = function rootContentInserted_finalCheck()
|
||||
{
|
||||
var tree = {
|
||||
role: ROLE_DOCUMENT,
|
||||
states: {
|
||||
states: 0,
|
||||
extraStates: 0,
|
||||
absentStates: 0,
|
||||
absentExtraStates: EXT_STATE_STALE
|
||||
},
|
||||
children: [
|
||||
{
|
||||
role: ROLE_TEXT_LEAF,
|
||||
name: aTextName
|
||||
}
|
||||
]
|
||||
};
|
||||
testAccessibleTree(getDocNode(aID), tree);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invokers
|
||||
|
||||
function writeIFrameDoc(aID)
|
||||
{
|
||||
this.__proto__ = new rootContentReplaced(aID, "hello");
|
||||
|
||||
this.invoke = function writeIFrameDoc_invoke()
|
||||
{
|
||||
var docNode = getDocNode(aID);
|
||||
|
||||
// We can't use open/write/close outside of iframe document because of
|
||||
// security error.
|
||||
var script = docNode.createElement("script");
|
||||
script.textContent = "document.open(); document.write('hello'); document.close();";
|
||||
docNode.body.appendChild(script);
|
||||
}
|
||||
|
||||
this.getID = function writeIFrameDoc_getID()
|
||||
{
|
||||
return "write document";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace HTML element.
|
||||
*/
|
||||
function replaceIFrameHTMLElm(aID)
|
||||
{
|
||||
this.__proto__ = new rootContentReplaced(aID, "New Wave");
|
||||
|
||||
this.invoke = function replaceIFrameHTMLElm_invoke()
|
||||
{
|
||||
var docNode = getDocNode(aID);
|
||||
var newHTMLNode = docNode.createElement("html");
|
||||
var newBodyNode = docNode.createElement("body");
|
||||
var newTextNode = docNode.createTextNode("New Wave");
|
||||
newBodyNode.appendChild(newTextNode);
|
||||
newHTMLNode.appendChild(newBodyNode);
|
||||
docNode.replaceChild(newHTMLNode, docNode.documentElement);
|
||||
}
|
||||
|
||||
this.getID = function replaceIFrameBody_getID()
|
||||
{
|
||||
return "replace HTML element";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace HTML body.
|
||||
*/
|
||||
function replaceIFrameBody(aID)
|
||||
{
|
||||
this.__proto__ = new rootContentReplaced(aID, "New Hello");
|
||||
|
||||
this.invoke = function replaceIFrameBody_invoke()
|
||||
{
|
||||
var docNode = getDocNode(aID);
|
||||
var newBodyNode = docNode.createElement("body");
|
||||
var newTextNode = docNode.createTextNode("New Hello");
|
||||
newBodyNode.appendChild(newTextNode);
|
||||
docNode.documentElement.replaceChild(newBodyNode, docNode.body);
|
||||
}
|
||||
|
||||
this.finalCheck = function replaceIFrameBody_finalCheck()
|
||||
{
|
||||
var tree = {
|
||||
role: ROLE_DOCUMENT,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_TEXT_LEAF,
|
||||
name: "New Hello"
|
||||
}
|
||||
]
|
||||
};
|
||||
testAccessibleTree(getDocNode(aID), tree);
|
||||
}
|
||||
|
||||
this.getID = function replaceIFrameBody_getID()
|
||||
{
|
||||
return "replace body";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open/close document pair.
|
||||
*/
|
||||
function openIFrameDoc(aID)
|
||||
{
|
||||
this.__proto__ = new rootContentRemoved(aID);
|
||||
|
||||
this.invoke = function openIFrameDoc_invoke()
|
||||
{
|
||||
this.preinvoke();
|
||||
|
||||
// Open document.
|
||||
var docNode = getDocNode(aID);
|
||||
var script = docNode.createElement("script");
|
||||
script.textContent = "function closeMe() { document.write('Works?'); document.close(); } window.closeMe = closeMe; document.open();";
|
||||
docNode.body.appendChild(script);
|
||||
}
|
||||
|
||||
this.getID = function openIFrameDoc_getID()
|
||||
{
|
||||
return "open document";
|
||||
}
|
||||
}
|
||||
|
||||
function closeIFrameDoc(aID)
|
||||
{
|
||||
this.__proto__ = new rootContentInserted(aID, "Works?");
|
||||
|
||||
this.invoke = function closeIFrameDoc_invoke()
|
||||
{
|
||||
// Write and close document.
|
||||
getDocNode(aID).write('Works?'); getDocNode(aID).close();
|
||||
}
|
||||
|
||||
this.getID = function closeIFrameDoc_getID()
|
||||
{
|
||||
return "close document";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove/insert HTML element pair.
|
||||
*/
|
||||
function removeHTMLFromIFrameDoc(aID)
|
||||
{
|
||||
this.__proto__ = new rootContentRemoved(aID);
|
||||
|
||||
this.invoke = function removeHTMLFromIFrameDoc_invoke()
|
||||
{
|
||||
this.preinvoke();
|
||||
|
||||
// Remove HTML element.
|
||||
var docNode = getDocNode(aID);
|
||||
docNode.removeChild(docNode.firstChild);
|
||||
}
|
||||
|
||||
this.getID = function removeHTMLFromIFrameDoc_getID()
|
||||
{
|
||||
return "remove HTML element";
|
||||
}
|
||||
}
|
||||
|
||||
function insertHTMLToIFrameDoc(aID)
|
||||
{
|
||||
this.__proto__ = new rootContentInserted(aID, "Haha");
|
||||
|
||||
this.invoke = function insertHTMLToIFrameDoc_invoke()
|
||||
{
|
||||
// Insert HTML element.
|
||||
var docNode = getDocNode(aID);
|
||||
var html = docNode.createElement("html");
|
||||
var body = docNode.createElement("body");
|
||||
var text = docNode.createTextNode("Haha");
|
||||
body.appendChild(text);
|
||||
html.appendChild(body);
|
||||
docNode.appendChild(html);
|
||||
}
|
||||
|
||||
this.getID = function insertHTMLToIFrameDoc_getID()
|
||||
{
|
||||
return "insert HTML element document";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove/insert HTML body pair.
|
||||
*/
|
||||
function removeBodyFromIFrameDoc(aID)
|
||||
{
|
||||
this.__proto__ = new rootContentRemoved(aID);
|
||||
|
||||
this.invoke = function removeBodyFromIFrameDoc_invoke()
|
||||
{
|
||||
this.preinvoke();
|
||||
|
||||
// Remove body element.
|
||||
var docNode = getDocNode(aID);
|
||||
docNode.documentElement.removeChild(docNode.body);
|
||||
}
|
||||
|
||||
this.getID = function removeBodyFromIFrameDoc_getID()
|
||||
{
|
||||
return "remove body element";
|
||||
}
|
||||
}
|
||||
|
||||
function insertBodyToIFrameDoc(aID)
|
||||
{
|
||||
this.__proto__ = new rootContentInserted(aID, "Yo ho ho i butylka roma!");
|
||||
|
||||
this.invoke = function insertBodyToIFrameDoc_invoke()
|
||||
{
|
||||
// Insert body element.
|
||||
var docNode = getDocNode(aID);
|
||||
var body = docNode.createElement("body");
|
||||
var text = docNode.createTextNode("Yo ho ho i butylka roma!");
|
||||
body.appendChild(text);
|
||||
docNode.documentElement.appendChild(body);
|
||||
}
|
||||
|
||||
this.getID = function insertBodyToIFrameDoc_getID()
|
||||
{
|
||||
return "insert body element";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
//gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
|
||||
var gQueue = null;
|
||||
|
||||
function doTest()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new writeIFrameDoc("iframe"));
|
||||
gQueue.push(new replaceIFrameHTMLElm("iframe"));
|
||||
gQueue.push(new replaceIFrameBody("iframe"));
|
||||
gQueue.push(new openIFrameDoc("iframe"));
|
||||
gQueue.push(new closeIFrameDoc("iframe"));
|
||||
gQueue.push(new removeHTMLFromIFrameDoc("iframe"));
|
||||
gQueue.push(new insertHTMLToIFrameDoc("iframe"));
|
||||
gQueue.push(new removeBodyFromIFrameDoc("iframe"));
|
||||
gQueue.push(new insertBodyToIFrameDoc("iframe"));
|
||||
|
||||
gQueue.invoke(); // SimpleTest.finish() will be called in the end
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
title="Update accessible tree when root element is changed"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=606082">Mozilla Bug 606082</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<iframe id="iframe"></iframe>
|
||||
|
||||
<div id="eventdump"></div>
|
||||
</body>
|
||||
</html>
|
@ -6898,6 +6898,17 @@ nsCSSFrameConstructor::ContentRangeInserted(nsIContent* aContainer,
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
if (mPresShell->IsAccessibilityActive()) {
|
||||
nsCOMPtr<nsIAccessibilityService> accService =
|
||||
do_GetService("@mozilla.org/accessibilityService;1");
|
||||
if (accService) {
|
||||
accService->ContentRangeInserted(mPresShell, aContainer,
|
||||
aStartChild, aEndChild);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user