mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 732389 - image map accessible tree is not updated when image map is changed, r=bz, tbsaunde
This commit is contained in:
parent
d9ecb49f84
commit
12cc97eaa6
@ -298,23 +298,24 @@ already_AddRefed<nsAccessible>
|
||||
nsAccessibilityService::CreateHTMLImageAccessible(nsIContent* aContent,
|
||||
nsIPresShell* aPresShell)
|
||||
{
|
||||
nsAutoString mapElmName;
|
||||
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::usemap, mapElmName);
|
||||
nsCOMPtr<nsIDOMHTMLMapElement> mapElm;
|
||||
if (nsIDocument* document = aContent->GetCurrentDoc()) {
|
||||
mapElm = do_QueryInterface(document->FindImageMap(mapElmName));
|
||||
}
|
||||
|
||||
nsAccessible* accessible = mapElm ?
|
||||
new nsHTMLImageMapAccessible(aContent,
|
||||
nsAccUtils::GetDocAccessibleFor(aPresShell),
|
||||
mapElm) :
|
||||
new nsHTMLImageAccessibleWrap(aContent,
|
||||
nsAccessible* accessible =
|
||||
new nsHTMLImageAccessibleWrap(aContent,
|
||||
nsAccUtils::GetDocAccessibleFor(aPresShell));
|
||||
NS_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
|
||||
already_AddRefed<nsAccessible>
|
||||
nsAccessibilityService::CreateHTMLImageMapAccessible(nsIContent* aContent,
|
||||
nsIPresShell* aPresShell)
|
||||
{
|
||||
nsAccessible* accessible =
|
||||
new nsHTMLImageMapAccessible(aContent,
|
||||
nsAccUtils::GetDocAccessibleFor(aPresShell));
|
||||
NS_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
|
||||
already_AddRefed<nsAccessible>
|
||||
nsAccessibilityService::CreateHTMLGroupboxAccessible(nsIContent* aContent,
|
||||
nsIPresShell* aPresShell)
|
||||
@ -611,6 +612,28 @@ nsAccessibilityService::UpdateListBullet(nsIPresShell* aPresShell,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsAccessibilityService::UpdateImageMap(nsImageFrame* aImageFrame)
|
||||
{
|
||||
nsIPresShell* presShell = aImageFrame->PresContext()->PresShell();
|
||||
nsDocAccessible* document = GetDocAccessible(presShell->GetDocument());
|
||||
if (document) {
|
||||
nsAccessible* accessible =
|
||||
document->GetAccessible(aImageFrame->GetContent());
|
||||
if (accessible) {
|
||||
nsHTMLImageMapAccessible* imageMap = accessible->AsImageMap();
|
||||
if (imageMap) {
|
||||
imageMap->UpdateChildAreas();
|
||||
return;
|
||||
}
|
||||
|
||||
// If image map was initialized after we created an accessible (that'll
|
||||
// be an image accessible) then recreate it.
|
||||
RecreateAccessible(presShell, aImageFrame->GetContent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsAccessibilityService::PresShellDestroyed(nsIPresShell *aPresShell)
|
||||
{
|
||||
|
@ -48,6 +48,8 @@
|
||||
|
||||
#include "nsIObserver.h"
|
||||
|
||||
class nsImageFrame;
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
@ -109,6 +111,8 @@ public:
|
||||
CreateHTMLHRAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
|
||||
virtual already_AddRefed<nsAccessible>
|
||||
CreateHTMLImageAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
|
||||
already_AddRefed<nsAccessible>
|
||||
CreateHTMLImageMapAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
|
||||
virtual already_AddRefed<nsAccessible>
|
||||
CreateHTMLLabelAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
|
||||
virtual already_AddRefed<nsAccessible>
|
||||
@ -155,6 +159,11 @@ public:
|
||||
nsIContent* aHTMLListItemContent,
|
||||
bool aHasBullet);
|
||||
|
||||
/**
|
||||
* Update the image map.
|
||||
*/
|
||||
void UpdateImageMap(nsImageFrame* aImageFrame);
|
||||
|
||||
virtual void NotifyOfAnchorJumpTo(nsIContent *aTarget);
|
||||
|
||||
virtual void PresShellDestroyed(nsIPresShell* aPresShell);
|
||||
|
@ -62,6 +62,7 @@ class KeyBinding;
|
||||
class nsAccessible;
|
||||
class nsHyperTextAccessible;
|
||||
class nsHTMLImageAccessible;
|
||||
class nsHTMLImageMapAccessible;
|
||||
class nsHTMLLIAccessible;
|
||||
struct nsRoleMapEntry;
|
||||
class Relation;
|
||||
@ -454,10 +455,13 @@ public:
|
||||
|
||||
inline bool IsHTMLListItem() const { return mFlags & eHTMLListItemAccessible; }
|
||||
nsHTMLLIAccessible* AsHTMLListItem();
|
||||
|
||||
|
||||
inline bool IsImageAccessible() const { return mFlags & eImageAccessible; }
|
||||
nsHTMLImageAccessible* AsImage();
|
||||
|
||||
bool IsImageMapAccessible() const { return mFlags & eImageMapAccessible; }
|
||||
nsHTMLImageMapAccessible* AsImageMap();
|
||||
|
||||
inline bool IsListControl() const { return mFlags & eListControlAccessible; }
|
||||
|
||||
inline bool IsMenuButton() const { return mFlags & eMenuButtonAccessible; }
|
||||
@ -689,11 +693,12 @@ protected:
|
||||
eHTMLFileInputAccessible = 1 << 8,
|
||||
eHTMLListItemAccessible = 1 << 9,
|
||||
eImageAccessible = 1 << 10,
|
||||
eListControlAccessible = 1 << 11,
|
||||
eMenuButtonAccessible = 1 << 12,
|
||||
eMenuPopupAccessible = 1 << 13,
|
||||
eRootAccessible = 1 << 14,
|
||||
eTextLeafAccessible = 1 << 15
|
||||
eImageMapAccessible = 1 << 11,
|
||||
eListControlAccessible = 1 << 12,
|
||||
eMenuButtonAccessible = 1 << 13,
|
||||
eMenuPopupAccessible = 1 << 14,
|
||||
eRootAccessible = 1 << 15,
|
||||
eTextLeafAccessible = 1 << 16
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -52,15 +52,16 @@
|
||||
#include "nsImageMap.h"
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLImageMapAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsHTMLImageMapAccessible::
|
||||
nsHTMLImageMapAccessible(nsIContent* aContent, nsDocAccessible* aDoc,
|
||||
nsIDOMHTMLMapElement* aMapElm) :
|
||||
nsHTMLImageAccessibleWrap(aContent, aDoc), mMapElement(aMapElm)
|
||||
nsHTMLImageMapAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
|
||||
nsHTMLImageAccessibleWrap(aContent, aDoc)
|
||||
{
|
||||
mFlags |= eImageMapAccessible;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -104,39 +105,75 @@ nsHTMLImageMapAccessible::AnchorURIAt(PRUint32 aAnchorIndex)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLImageMapAccessible: nsAccessible protected
|
||||
// nsHTMLImageMapAccessible: public
|
||||
|
||||
void
|
||||
nsHTMLImageMapAccessible::CacheChildren()
|
||||
void
|
||||
nsHTMLImageMapAccessible::UpdateChildAreas(bool aDoFireEvents)
|
||||
{
|
||||
if (!mMapElement)
|
||||
nsImageFrame* imageFrame = do_QueryFrame(mContent->GetPrimaryFrame());
|
||||
|
||||
// If image map is not initialized yet then we trigger one time more later.
|
||||
nsImageMap* imageMapObj = imageFrame->GetExistingImageMap();
|
||||
if (!imageMapObj)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLCollection> mapAreas;
|
||||
mMapElement->GetAreas(getter_AddRefs(mapAreas));
|
||||
if (!mapAreas)
|
||||
return;
|
||||
bool doReorderEvent = false;
|
||||
|
||||
nsDocAccessible* document = Document();
|
||||
// Remove areas that are not a valid part of the image map anymore.
|
||||
for (PRInt32 childIdx = mChildren.Length() - 1; childIdx >= 0; childIdx--) {
|
||||
nsAccessible* area = mChildren.ElementAt(childIdx);
|
||||
if (area->GetContent()->GetPrimaryFrame())
|
||||
continue;
|
||||
|
||||
PRUint32 areaCount = 0;
|
||||
mapAreas->GetLength(&areaCount);
|
||||
if (aDoFireEvents) {
|
||||
nsRefPtr<AccEvent> event = new AccHideEvent(area, area->GetContent());
|
||||
mDoc->FireDelayedAccessibleEvent(event);
|
||||
doReorderEvent = true;
|
||||
}
|
||||
|
||||
for (PRUint32 areaIdx = 0; areaIdx < areaCount; areaIdx++) {
|
||||
nsCOMPtr<nsIDOMNode> areaNode;
|
||||
mapAreas->Item(areaIdx, getter_AddRefs(areaNode));
|
||||
if (!areaNode)
|
||||
return;
|
||||
RemoveChild(area);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> areaContent(do_QueryInterface(areaNode));
|
||||
nsRefPtr<nsAccessible> area =
|
||||
new nsHTMLAreaAccessible(areaContent, mDoc);
|
||||
// Insert new areas into the tree.
|
||||
PRUint32 areaElmCount = imageMapObj->AreaCount();
|
||||
for (PRUint32 idx = 0; idx < areaElmCount; idx++) {
|
||||
nsIContent* areaContent = imageMapObj->GetAreaAt(idx);
|
||||
|
||||
if (!document->BindToDocument(area, nsAccUtils::GetRoleMapEntry(areaContent)) ||
|
||||
!AppendChild(area)) {
|
||||
return;
|
||||
nsAccessible* area = mChildren.SafeElementAt(idx);
|
||||
if (!area || area->GetContent() != areaContent) {
|
||||
nsRefPtr<nsAccessible> area = new nsHTMLAreaAccessible(areaContent, mDoc);
|
||||
if (!mDoc->BindToDocument(area, nsAccUtils::GetRoleMapEntry(areaContent)))
|
||||
break;
|
||||
|
||||
if (!InsertChildAt(idx, area)) {
|
||||
mDoc->UnbindFromDocument(area);
|
||||
break;
|
||||
}
|
||||
|
||||
if (aDoFireEvents) {
|
||||
nsRefPtr<AccEvent> event = new AccShowEvent(area, areaContent);
|
||||
mDoc->FireDelayedAccessibleEvent(event);
|
||||
doReorderEvent = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fire reorder event if needed.
|
||||
if (doReorderEvent) {
|
||||
nsRefPtr<AccEvent> reorderEvent =
|
||||
new AccEvent(nsIAccessibleEvent::EVENT_REORDER, mContent,
|
||||
eAutoDetect, AccEvent::eCoalesceFromSameSubtree);
|
||||
mDoc->FireDelayedAccessibleEvent(reorderEvent);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLImageMapAccessible: nsAccessible protected
|
||||
|
||||
void
|
||||
nsHTMLImageMapAccessible::CacheChildren()
|
||||
{
|
||||
UpdateChildAreas(false);
|
||||
}
|
||||
|
||||
|
||||
@ -226,6 +263,17 @@ nsHTMLAreaAccessible::GetBounds(PRInt32 *aX, PRInt32 *aY,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLAreaAccessible: nsAccessNode public
|
||||
|
||||
bool
|
||||
nsHTMLAreaAccessible::IsPrimaryForNode() const
|
||||
{
|
||||
// Make HTML area DOM element not accessible. HTML image map accessible
|
||||
// manages its tree itself.
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLAreaAccessible: nsAccessible public
|
||||
|
||||
|
@ -51,8 +51,8 @@
|
||||
class nsHTMLImageMapAccessible : public nsHTMLImageAccessibleWrap
|
||||
{
|
||||
public:
|
||||
nsHTMLImageMapAccessible(nsIContent* aContent, nsDocAccessible* aDoc,
|
||||
nsIDOMHTMLMapElement* aMapElm);
|
||||
nsHTMLImageMapAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
|
||||
virtual ~nsHTMLImageMapAccessible() { }
|
||||
|
||||
// nsISupports and cycle collector
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
@ -65,16 +65,27 @@ public:
|
||||
virtual nsAccessible* AnchorAt(PRUint32 aAnchorIndex);
|
||||
virtual already_AddRefed<nsIURI> AnchorURIAt(PRUint32 aAnchorIndex);
|
||||
|
||||
/**
|
||||
* Update area children of the image map.
|
||||
*/
|
||||
void UpdateChildAreas(bool aDoFireEvents = true);
|
||||
|
||||
protected:
|
||||
|
||||
// nsAccessible
|
||||
virtual void CacheChildren();
|
||||
|
||||
private:
|
||||
// Reference on linked map element if any.
|
||||
nsCOMPtr<nsIDOMHTMLMapElement> mMapElement;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessible downcasting method
|
||||
|
||||
inline nsHTMLImageMapAccessible*
|
||||
nsAccessible::AsImageMap()
|
||||
{
|
||||
return IsImageMapAccessible() ?
|
||||
static_cast<nsHTMLImageMapAccessible*>(this) : nsnull;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Accessible for image map areas - must be child of image.
|
||||
@ -89,6 +100,9 @@ public:
|
||||
|
||||
NS_IMETHOD GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height);
|
||||
|
||||
// nsAccessNode
|
||||
virtual bool IsPrimaryForNode() const;
|
||||
|
||||
// nsAccessible
|
||||
virtual void Description(nsString& aDescription);
|
||||
virtual nsresult GetNameInternal(nsAString& aName);
|
||||
|
@ -486,6 +486,21 @@ function testDefunctAccessible(aAcc, aNodeOrId)
|
||||
ok(success, "parent" + msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that image map accessible tree is created.
|
||||
*/
|
||||
function ensureImageMapTree(aID)
|
||||
{
|
||||
// XXX: We send a useless mouse move to the image to force it to setup its
|
||||
// image map, because flushing layout won't do it. Hopefully bug 135040
|
||||
// will make this not suck.
|
||||
synthesizeMouse(getNode(aID), 10, 10, { type: "mousemove" });
|
||||
|
||||
// XXX This may affect a11y more than other code because imagemaps may not
|
||||
// get drawn or have an mouse event over them. Bug 570322 tracks a11y
|
||||
// dealing with this.
|
||||
todo(false, "Need to remove this image map workaround.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert role to human readable string.
|
||||
|
@ -9,6 +9,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
@ -88,6 +90,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// image map and its link children
|
||||
ensureImageMapTree("imgmap");
|
||||
|
||||
var imageMapHyperlinkAcc = getAccessible("imgmap",
|
||||
[nsIAccessibleHyperLink]);
|
||||
testThis("imgmap", imageMapHyperlinkAcc, ROLE_IMAGE_MAP, 2, "b", true,
|
||||
@ -268,7 +272,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
||||
><img width="447" id="imgmap"
|
||||
height="15"
|
||||
usemap="#atoz_map"
|
||||
src="letters.gif"><br>Empty link:<br
|
||||
src="../letters.gif"><br>Empty link:<br
|
||||
><a id="emptyLink" href=""><img src=""></a
|
||||
><br>Link with embedded span<br
|
||||
><a id="LinkWithSpan" href="http://www.heise.de/"><span lang="de">Heise Online</span></a
|
||||
|
@ -9,6 +9,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=428248
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
@ -53,6 +55,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=428248
|
||||
testThis("InvalidAriaHyperlink", 63, 2, "Invalid link");
|
||||
|
||||
// image map, but not its link children. They are not part of hypertext.
|
||||
ensureImageMapTree("imgmap");
|
||||
testThis("imgmap", 76, 3, "b");
|
||||
|
||||
// empty hyperlink
|
||||
@ -131,7 +134,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=428248
|
||||
><img width="447" id="imgmap"
|
||||
height="15"
|
||||
usemap="#atoz_map"
|
||||
src="letters.gif"></img><br
|
||||
src="../letters.gif"></img><br
|
||||
>Empty link:<br
|
||||
><a id="emptyLink" href=""><img src=""></img></a><br
|
||||
>Link with embedded span<br
|
||||
|
@ -19,21 +19,22 @@
|
||||
<script type="application/javascript">
|
||||
function doTest()
|
||||
{
|
||||
//XXX We send a useless mouse move to the image to force it to setup its
|
||||
// image map, because flushing layout won't do it. Hopefully bug 135040
|
||||
// will make this not suck.
|
||||
synthesizeMouse($("imagemap"), 10, 10, { type: "mousemove" });
|
||||
//XXX This may affect a11y more than other code because imagemaps may not
|
||||
// get drawn or have an mouse event over them. Bug 570322 tracks a11y
|
||||
// dealing with this.
|
||||
todo(false, "Need to remove this image map workaround.");
|
||||
ensureImageMapTree("imagemap");
|
||||
|
||||
testStates("t1", 0, EXT_STATE_EDITABLE, STATE_LINKED);
|
||||
testStates("t2", 0, EXT_STATE_EDITABLE, STATE_LINKED);
|
||||
testStates("rb1", (STATE_CHECKABLE | STATE_CHECKED), 0, STATE_LINKED);
|
||||
testStates("rb2", STATE_CHECKABLE, 0, STATE_CHECKED, STATE_LINKED);
|
||||
testStates("cb1", (STATE_CHECKABLE | STATE_CHECKED), 0, STATE_LINKED);
|
||||
testStates("cbox", (STATE_HASPOPUP | STATE_COLLAPSED),
|
||||
var imageMap = getAccessible("imagemap");
|
||||
|
||||
var t1 = imageMap.getChildAt(0);
|
||||
testStates(t1, 0, EXT_STATE_EDITABLE, STATE_LINKED);
|
||||
var t2 = imageMap.getChildAt(1);
|
||||
testStates(t2, 0, EXT_STATE_EDITABLE, STATE_LINKED);
|
||||
var rb1 = imageMap.getChildAt(2);
|
||||
testStates(rb1, (STATE_CHECKABLE | STATE_CHECKED), 0, STATE_LINKED);
|
||||
var rb2 = imageMap.getChildAt(3);
|
||||
testStates(rb2, STATE_CHECKABLE, 0, STATE_CHECKED, STATE_LINKED);
|
||||
var cb1 = imageMap.getChildAt(4);
|
||||
testStates(cb1, (STATE_CHECKABLE | STATE_CHECKED), 0, STATE_LINKED);
|
||||
var cbox = imageMap.getChildAt(5);
|
||||
testStates(cbox, (STATE_HASPOPUP | STATE_COLLAPSED),
|
||||
EXT_STATE_EXPANDABLE, STATE_LINKED);
|
||||
|
||||
SimpleTest.finish();
|
||||
|
@ -19,14 +19,7 @@
|
||||
<script type="application/javascript">
|
||||
function doTest()
|
||||
{
|
||||
//XXX We send a useless mouse move to the image to force it to setup its
|
||||
// image map, because flushing layout won't do it. Hopefully bug 135040
|
||||
// will make this not suck.
|
||||
synthesizeMouse($("imagemap"), 10, 10, { type: "mousemove" });
|
||||
//XXX This may affect a11y more than other code because imagemaps may not
|
||||
// get drawn or have an mouse event over them. Bug 570322 tracks a11y
|
||||
// dealing with this.
|
||||
todo(false, "Need to remove this image map workaround.");
|
||||
ensureImageMapTree("imagemap");
|
||||
|
||||
var accTree = {
|
||||
role: ROLE_IMAGE_MAP,
|
||||
|
@ -54,6 +54,7 @@ _TEST_FILES =\
|
||||
test_doc.html \
|
||||
test_gencontent.html \
|
||||
test_hidden.html \
|
||||
test_imagemap.html \
|
||||
test_list_editabledoc.html \
|
||||
test_list.html \
|
||||
test_menu.xul \
|
||||
|
394
accessible/tests/mochitest/treeupdate/test_imagemap.html
Normal file
394
accessible/tests/mochitest/treeupdate/test_imagemap.html
Normal file
@ -0,0 +1,394 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>HTML img map accessible tree update tests</title>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function insertArea(aImageMapID, aMapID)
|
||||
{
|
||||
this.imageMap = getAccessible(aImageMapID);
|
||||
this.mapNode = getNode(aMapID);
|
||||
|
||||
function getInsertedArea(aThisObj)
|
||||
{
|
||||
return aThisObj.imageMap.firstChild;
|
||||
}
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_SHOW, getInsertedArea, this),
|
||||
new invokerChecker(EVENT_REORDER, this.imageMap)
|
||||
];
|
||||
|
||||
this.invoke = function insertArea_invoke()
|
||||
{
|
||||
var areaElm = document.createElement("area");
|
||||
areaElm.setAttribute("href",
|
||||
"http://www.bbc.co.uk/radio4/atoz/index.shtml#a");
|
||||
areaElm.setAttribute("coords", "0,0,13,14");
|
||||
areaElm.setAttribute("alt", "a");
|
||||
areaElm.setAttribute("shape", "rect");
|
||||
|
||||
this.mapNode.insertBefore(areaElm, this.mapNode.firstChild);
|
||||
}
|
||||
|
||||
this.finalCheck = function insertArea_finalCheck()
|
||||
{
|
||||
var accTree =
|
||||
{ IMAGE_MAP: [
|
||||
{
|
||||
role: ROLE_LINK,
|
||||
name: "a",
|
||||
children: [ ]
|
||||
},
|
||||
{
|
||||
role: ROLE_LINK,
|
||||
name: "b",
|
||||
children: [ ]
|
||||
},
|
||||
] };
|
||||
testAccessibleTree(this.imageMap, accTree);
|
||||
}
|
||||
|
||||
this.getID = function insertArea_getID()
|
||||
{
|
||||
return "insert area element";
|
||||
}
|
||||
}
|
||||
|
||||
function appendArea(aImageMapID, aMapID)
|
||||
{
|
||||
this.imageMap = getAccessible(aImageMapID);
|
||||
this.mapNode = getNode(aMapID);
|
||||
|
||||
function getAppendedArea(aThisObj)
|
||||
{
|
||||
return aThisObj.imageMap.lastChild;
|
||||
}
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_SHOW, getAppendedArea, this),
|
||||
new invokerChecker(EVENT_REORDER, this.imageMap)
|
||||
];
|
||||
|
||||
this.invoke = function appendArea_invoke()
|
||||
{
|
||||
var areaElm = document.createElement("area");
|
||||
areaElm.setAttribute("href",
|
||||
"http://www.bbc.co.uk/radio4/atoz/index.shtml#c");
|
||||
areaElm.setAttribute("coords", "34,0,47,14");
|
||||
areaElm.setAttribute("alt", "c");
|
||||
areaElm.setAttribute("shape", "rect");
|
||||
|
||||
this.mapNode.appendChild(areaElm);
|
||||
}
|
||||
|
||||
this.finalCheck = function appendArea_finalCheck()
|
||||
{
|
||||
var accTree =
|
||||
{ IMAGE_MAP: [
|
||||
{
|
||||
role: ROLE_LINK,
|
||||
name: "a",
|
||||
children: [ ]
|
||||
},
|
||||
{
|
||||
role: ROLE_LINK,
|
||||
name: "b",
|
||||
children: [ ]
|
||||
},
|
||||
{
|
||||
role: ROLE_LINK,
|
||||
name: "c",
|
||||
children: [ ]
|
||||
}
|
||||
] };
|
||||
testAccessibleTree(this.imageMap, accTree);
|
||||
}
|
||||
|
||||
this.getID = function appendArea_getID()
|
||||
{
|
||||
return "append area element";
|
||||
}
|
||||
}
|
||||
|
||||
function removeArea(aImageMapID, aMapID)
|
||||
{
|
||||
this.imageMap = getAccessible(aImageMapID);
|
||||
this.area = null;
|
||||
this.mapNode = getNode(aMapID);
|
||||
|
||||
function getRemovedArea(aThisObj)
|
||||
{
|
||||
return aThisObj.area;
|
||||
}
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, getRemovedArea, this),
|
||||
new invokerChecker(EVENT_REORDER, this.imageMap)
|
||||
];
|
||||
|
||||
this.invoke = function removeArea_invoke()
|
||||
{
|
||||
this.area = this.imageMap.firstChild;
|
||||
this.mapNode.removeChild(this.mapNode.firstElementChild);
|
||||
}
|
||||
|
||||
this.finalCheck = function removeArea_finalCheck()
|
||||
{
|
||||
var accTree =
|
||||
{ IMAGE_MAP: [
|
||||
{
|
||||
role: ROLE_LINK,
|
||||
name: "b",
|
||||
children: [ ]
|
||||
},
|
||||
{
|
||||
role: ROLE_LINK,
|
||||
name: "c",
|
||||
children: [ ]
|
||||
}
|
||||
] };
|
||||
testAccessibleTree(this.imageMap, accTree);
|
||||
}
|
||||
|
||||
this.getID = function removeArea_getID()
|
||||
{
|
||||
return "remove area element";
|
||||
}
|
||||
}
|
||||
|
||||
function removeNameOnMap(aImageMapContainerID, aImageMapID, aMapID)
|
||||
{
|
||||
this.container = getAccessible(aImageMapContainerID);
|
||||
this.containerNode = this.container.DOMNode;
|
||||
this.imageMap = getAccessible(aImageMapID);
|
||||
this.imgNode = this.imageMap.DOMNode;
|
||||
this.mapNode = getNode(aMapID);
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, this.imageMap),
|
||||
new invokerChecker(EVENT_SHOW, this.imgNode),
|
||||
new invokerChecker(EVENT_REORDER, this.container)
|
||||
];
|
||||
|
||||
this.invoke = function removeNameOnMap_invoke()
|
||||
{
|
||||
this.mapNode.removeAttribute("name");
|
||||
}
|
||||
|
||||
this.finalCheck = function removeNameOnMap_finalCheck()
|
||||
{
|
||||
var accTree =
|
||||
{ SECTION: [
|
||||
{ GRAPHIC: [ ] }
|
||||
] };
|
||||
testAccessibleTree(this.container, accTree);
|
||||
}
|
||||
|
||||
this.getID = function removeNameOnMap_getID()
|
||||
{
|
||||
return "remove @name on map element";
|
||||
}
|
||||
}
|
||||
|
||||
function restoreNameOnMap(aImageMapContainerID, aImageMapID, aMapID)
|
||||
{
|
||||
this.container = getAccessible(aImageMapContainerID);
|
||||
this.containerNode = this.container.DOMNode;
|
||||
this.imageMap = null;
|
||||
this.imgNode = getNode(aImageMapID);
|
||||
this.mapNode = getNode(aMapID);
|
||||
|
||||
function getImageMap(aThisObj)
|
||||
{
|
||||
return aThisObj.imageMap;
|
||||
}
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, getImageMap, this),
|
||||
new invokerChecker(EVENT_SHOW, this.imgNode),
|
||||
new invokerChecker(EVENT_REORDER, this.container)
|
||||
];
|
||||
|
||||
this.invoke = function restoreNameOnMap_invoke()
|
||||
{
|
||||
this.imageMap = getAccessible(aImageMapID);
|
||||
this.mapNode.setAttribute("name", "atoz_map");
|
||||
}
|
||||
|
||||
this.finalCheck = function removeNameOnMap_finalCheck()
|
||||
{
|
||||
var accTree =
|
||||
{ SECTION: [
|
||||
{ IMAGE_MAP: [
|
||||
{ LINK: [ ] },
|
||||
{ LINK: [ ] }
|
||||
] }
|
||||
] };
|
||||
testAccessibleTree(this.container, accTree);
|
||||
}
|
||||
|
||||
this.getID = function removeNameOnMap_getID()
|
||||
{
|
||||
return "restore @name on map element";
|
||||
}
|
||||
}
|
||||
|
||||
function removeMap(aImageMapContainerID, aImageMapID, aMapID)
|
||||
{
|
||||
this.container = getAccessible(aImageMapContainerID);
|
||||
this.containerNode = this.container.DOMNode;
|
||||
this.imageMap = null;
|
||||
this.imgNode = getNode(aImageMapID);
|
||||
this.mapNode = getNode(aMapID);
|
||||
|
||||
function getImageMap(aThisObj)
|
||||
{
|
||||
return aThisObj.imageMap;
|
||||
}
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, getImageMap, this),
|
||||
new invokerChecker(EVENT_SHOW, this.imgNode),
|
||||
new invokerChecker(EVENT_REORDER, this.container)
|
||||
];
|
||||
|
||||
this.invoke = function removeMap_invoke()
|
||||
{
|
||||
this.imageMap = getAccessible(aImageMapID);
|
||||
this.mapNode.parentNode.removeChild(this.mapNode);
|
||||
}
|
||||
|
||||
this.finalCheck = function removeMap_finalCheck()
|
||||
{
|
||||
var accTree =
|
||||
{ SECTION: [
|
||||
{ GRAPHIC: [ ] }
|
||||
] };
|
||||
testAccessibleTree(this.container, accTree);
|
||||
}
|
||||
|
||||
this.getID = function removeMap_getID()
|
||||
{
|
||||
return "remove map element";
|
||||
}
|
||||
}
|
||||
|
||||
function insertMap(aImageMapContainerID, aImageID)
|
||||
{
|
||||
this.container = getAccessible(aImageMapContainerID);
|
||||
this.containerNode = this.container.DOMNode;
|
||||
this.image = null;
|
||||
this.imgMapNode = getNode(aImageID);
|
||||
|
||||
function getImage(aThisObj)
|
||||
{
|
||||
return aThisObj.image;
|
||||
}
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, getImage, this),
|
||||
new invokerChecker(EVENT_SHOW, this.imgMapNode),
|
||||
new invokerChecker(EVENT_REORDER, this.container)
|
||||
];
|
||||
|
||||
this.invoke = function insertMap_invoke()
|
||||
{
|
||||
this.image = getAccessible(aImageID);
|
||||
|
||||
var map = document.createElement("map");
|
||||
map.setAttribute("name", "atoz_map");
|
||||
map.setAttribute("id", "map");
|
||||
|
||||
var area = document.createElement("area")
|
||||
area.setAttribute("href",
|
||||
"http://www.bbc.co.uk/radio4/atoz/index.shtml#b");
|
||||
area.setAttribute("coords", "17,0,30,14");
|
||||
area.setAttribute("alt", "b");
|
||||
area.setAttribute("shape", "rect");
|
||||
|
||||
map.appendChild(area);
|
||||
|
||||
this.containerNode.appendChild(map);
|
||||
|
||||
ensureImageMapTree(aImageID);
|
||||
}
|
||||
|
||||
this.finalCheck = function insertMap_finalCheck()
|
||||
{
|
||||
var accTree =
|
||||
{ SECTION: [
|
||||
{ IMAGE_MAP: [
|
||||
{ LINK: [ ] }
|
||||
] }
|
||||
] };
|
||||
testAccessibleTree(this.container, accTree);
|
||||
}
|
||||
|
||||
this.getID = function insertMap_getID()
|
||||
{
|
||||
return "insert map element";
|
||||
}
|
||||
}
|
||||
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
var gQueue = null;
|
||||
function doTest()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new insertArea("imgmap", "map"));
|
||||
gQueue.push(new appendArea("imgmap", "map"));
|
||||
gQueue.push(new removeArea("imgmap", "map"));
|
||||
gQueue.push(new removeNameOnMap("container", "imgmap", "map"));
|
||||
gQueue.push(new restoreNameOnMap("container", "imgmap", "map"));
|
||||
gQueue.push(new removeMap("container", "imgmap", "map"));
|
||||
gQueue.push(new insertMap("container", "imgmap"));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
title="Image map accessible tree is not updated when image map is changed"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=732389">
|
||||
Mozilla Bug 732389
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<map name="atoz_map" id="map">
|
||||
<area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#b"
|
||||
coords="17,0,30,14" alt="b" shape="rect">
|
||||
</map>
|
||||
|
||||
<div id="container">
|
||||
<img id="imgmap" width="447" height="15"
|
||||
usemap="#atoz_map"
|
||||
src="../letters.gif">
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -194,8 +194,14 @@ nsImageFrame::CreateAccessible()
|
||||
{
|
||||
nsAccessibilityService* accService = nsIPresShell::AccService();
|
||||
if (accService) {
|
||||
return accService->CreateHTMLImageAccessible(mContent,
|
||||
PresContext()->PresShell());
|
||||
// Don't use GetImageMap() to avoid reentrancy into accessibility.
|
||||
if (HasImageMap()) {
|
||||
return accService->CreateHTMLImageMapAccessible(mContent,
|
||||
PresContext()->PresShell());
|
||||
} else {
|
||||
return accService->CreateHTMLImageAccessible(mContent,
|
||||
PresContext()->PresShell());
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
@ -208,6 +214,13 @@ nsImageFrame::DisconnectMap()
|
||||
if (mImageMap) {
|
||||
mImageMap->Destroy();
|
||||
NS_RELEASE(mImageMap);
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
nsAccessibilityService* accService = GetAccService();
|
||||
if (accService) {
|
||||
accService->RecreateAccessible(PresContext()->PresShell(), mContent);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -1422,15 +1435,7 @@ nsImageMap*
|
||||
nsImageFrame::GetImageMap()
|
||||
{
|
||||
if (!mImageMap) {
|
||||
nsIDocument* doc = mContent->GetDocument();
|
||||
if (!doc) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsAutoString usemap;
|
||||
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::usemap, usemap);
|
||||
|
||||
nsCOMPtr<nsIContent> map = doc->FindImageMap(usemap);
|
||||
nsIContent* map = GetMapElement();
|
||||
if (map) {
|
||||
mImageMap = new nsImageMap();
|
||||
NS_ADDREF(mImageMap);
|
||||
|
@ -183,7 +183,25 @@ public:
|
||||
|
||||
nsRect GetInnerArea() const;
|
||||
|
||||
/**
|
||||
* Return a map element associated with this image.
|
||||
*/
|
||||
mozilla::dom::Element* GetMapElement() const
|
||||
{
|
||||
nsAutoString usemap;
|
||||
if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::usemap, usemap)) {
|
||||
return mContent->OwnerDoc()->FindImageMap(usemap);
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the image has associated image map.
|
||||
*/
|
||||
bool HasImageMap() const { return mImageMap || GetMapElement(); }
|
||||
|
||||
nsImageMap* GetImageMap();
|
||||
nsImageMap* GetExistingImageMap() const { return mImageMap; }
|
||||
|
||||
virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext,
|
||||
InlineMinWidthData *aData);
|
||||
|
@ -61,6 +61,10 @@
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
#include "nsAccessibilityService.h"
|
||||
#endif
|
||||
|
||||
namespace dom = mozilla::dom;
|
||||
|
||||
static NS_DEFINE_CID(kCStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
|
||||
@ -811,7 +815,16 @@ nsImageMap::UpdateAreas()
|
||||
bool foundAnchor = false;
|
||||
mContainsBlockContents = false;
|
||||
|
||||
return SearchForAreas(mMap, foundArea, foundAnchor);
|
||||
nsresult rv = SearchForAreas(mMap, foundArea, foundAnchor);
|
||||
#ifdef ACCESSIBILITY
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsAccessibilityService* accService = GetAccService();
|
||||
if (accService) {
|
||||
accService->UpdateImageMap(mImageFrame);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -886,6 +899,12 @@ nsImageMap::GetArea(nscoord aX, nscoord aY) const
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
nsImageMap::GetAreaAt(PRUint32 aIndex) const
|
||||
{
|
||||
return mAreas.ElementAt(aIndex)->mArea;
|
||||
}
|
||||
|
||||
void
|
||||
nsImageMap::Draw(nsIFrame* aFrame, nsRenderingContext& aRC)
|
||||
{
|
||||
|
@ -66,6 +66,16 @@ public:
|
||||
*/
|
||||
nsIContent* GetArea(nscoord aX, nscoord aY) const;
|
||||
|
||||
/**
|
||||
* Return area elements count associated with the image map.
|
||||
*/
|
||||
PRUint32 AreaCount() const { return mAreas.Length(); }
|
||||
|
||||
/**
|
||||
* Return area element at the given index.
|
||||
*/
|
||||
nsIContent* GetAreaAt(PRUint32 aIndex) const;
|
||||
|
||||
void Draw(nsIFrame* aFrame, nsRenderingContext& aRC);
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user