Bug 727942 - boundaries of imagemap may be incorrect when page is zoomed, r=marcoz

This commit is contained in:
Alexander Surkov 2012-03-24 02:05:09 +09:00
Родитель a0c1ba62ca
Коммит 9aa9e71a8a
5 изменённых файлов: 80 добавлений и 60 удалений

Просмотреть файл

@ -216,53 +216,6 @@ nsHTMLAreaAccessible::Description(nsString& aDescription)
area->GetShape(aDescription);
}
NS_IMETHODIMP
nsHTMLAreaAccessible::GetBounds(PRInt32 *aX, PRInt32 *aY,
PRInt32 *aWidth, PRInt32 *aHeight)
{
NS_ENSURE_ARG_POINTER(aX);
*aX = 0;
NS_ENSURE_ARG_POINTER(aY);
*aY = 0;
NS_ENSURE_ARG_POINTER(aWidth);
*aWidth = 0;
NS_ENSURE_ARG_POINTER(aHeight);
*aHeight = 0;
if (IsDefunct())
return NS_ERROR_FAILURE;
// Essentially this uses GetRect on mAreas of nsImageMap from nsImageFrame.
nsPresContext *presContext = GetPresContext();
NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
nsIFrame *frame = GetFrame();
NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
nsImageFrame *imageFrame = do_QueryFrame(frame);
nsImageMap* map = imageFrame->GetImageMap();
NS_ENSURE_TRUE(map, NS_ERROR_FAILURE);
nsRect rect;
nsresult rv = map->GetBoundsForAreaContent(mContent, rect);
NS_ENSURE_SUCCESS(rv, rv);
*aX = presContext->AppUnitsToDevPixels(rect.x);
*aY = presContext->AppUnitsToDevPixels(rect.y);
// XXX Areas are screwy; they return their rects as a pair of points, one pair
// stored into the width and height.
*aWidth = presContext->AppUnitsToDevPixels(rect.width - rect.x);
*aHeight = presContext->AppUnitsToDevPixels(rect.height - rect.y);
// Put coords in absolute screen coords
nsIntRect orgRectPixels = frame->GetScreenRectExternal();
*aX += orgRectPixels.x;
*aY += orgRectPixels.y;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsHTMLAreaAccessible: nsAccessNode public
@ -326,3 +279,25 @@ nsHTMLAreaAccessible::CacheChildren()
{
// No children for aria accessible.
}
void
nsHTMLAreaAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame)
{
nsIFrame* frame = GetFrame();
if (!frame)
return;
nsImageFrame* imageFrame = do_QueryFrame(frame);
nsImageMap* map = imageFrame->GetImageMap();
nsresult rv = map->GetBoundsForAreaContent(mContent, aBounds);
if (NS_FAILED(rv))
return;
// XXX Areas are screwy; they return their rects as a pair of points, one pair
// stored into the width and height.
aBounds.width -= aBounds.x;
aBounds.height -= aBounds.y;
*aBoundingFrame = frame;
}

Просмотреть файл

@ -96,10 +96,6 @@ public:
nsHTMLAreaAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
// nsIAccessible
NS_IMETHOD GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height);
// nsAccessNode
virtual bool IsPrimaryForNode() const;
@ -118,6 +114,7 @@ protected:
// nsAccessible
virtual void CacheChildren();
virtual void GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame);
};
#endif

Просмотреть файл

@ -7,6 +7,8 @@
<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>
@ -21,24 +23,42 @@
function doTest()
{
var tabDocument = currentTabDocument();
var p1 = tabDocument.body.firstElementChild;
var p2 = tabDocument.body.lastElementChild;
var p1 = tabDocument.getElementById("p1");
var p2 = tabDocument.getElementById("p2");
var imgMap = tabDocument.getElementById("imgmap");
ensureImageMapTree(imgMap);
var imgMapAcc = getAccessible(imgMap);
var area = imgMapAcc.firstChild;
testBounds(p1);
testBounds(p2);
testBounds(area);
zoomDocument(tabDocument, 2.0);
testBounds(p1);
testBounds(p2);
testBounds(area);
closeBrowserWindow();
SimpleTest.finish();
}
var url = "data:text/html,<html><body>";
url += "<p id='p1'>para 1</p><p id='p2'>para 2</p>";
url += "<map name='atoz_map' id='map'>";
url += " <area id='area1' href='http%3A%2F%2Fmozilla.org'";
url += " coords=17,0,30,14' alt='mozilla.org' shape='rect'>";
url += "</map>";
url += "<img id='imgmap' width='447' height='15'";
url += " usemap='%23atoz_map'";
url += " src='chrome%3A%2F%2Fmochitests%2Fcontent%2Fa11y%2Faccessible%2Fletters.gif'>";
url += "</body></html>";
SimpleTest.waitForExplicitFinish();
openBrowserWindow(doTest,
"data:text/html,<html><body><p>para 1</p><p>para 2</p></body></html>",
url,
{ left: 0, top: 0, width: 600, height: 600 });
</script>
</head>

Просмотреть файл

@ -494,7 +494,9 @@ 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" });
var image = getNode(aID);
synthesizeMouse(image, 10, 10, { type: "mousemove" },
image.ownerDocument.defaultView);
// 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

Просмотреть файл

@ -107,16 +107,42 @@ function getBounds(aID)
*/
function getBoundsForDOMElm(aID)
{
var x = 0, y = 0, width = 0, height = 0;
var elm = getNode(aID);
if (elm.localName == "area") {
var mapName = elm.parentNode.getAttribute("name");
var selector = "[usemap='#" + mapName + "']";
var img = elm.ownerDocument.querySelector(selector);
var areaCoords = elm.coords.split(",");
var areaX = parseInt(areaCoords[0]);
var areaY = parseInt(areaCoords[1]);
var areaWidth = parseInt(areaCoords[2]) - areaX;
var areaHeight = parseInt(areaCoords[3]) - areaY;
var rect = img.getBoundingClientRect();
x = rect.left + areaX;
y = rect.top + areaY;
width = areaWidth;
height = areaHeight;
}
else {
var rect = elm.getBoundingClientRect();
x = rect.left;
y = rect.top;
width = rect.width;
height = rect.height;
}
var elmWindow = elm.ownerDocument.defaultView;
var winUtil = elmWindow.
QueryInterface(Components.interfaces.nsIInterfaceRequestor).
getInterface(Components.interfaces.nsIDOMWindowUtils);
var ratio = winUtil.screenPixelsPerCSSPixel;
var rect = elm.getBoundingClientRect();
return [ (rect.left + elmWindow.mozInnerScreenX) * ratio,
(rect.top + elmWindow.mozInnerScreenY) * ratio,
rect.width * ratio,
rect.height * ratio ];
return [ (x + elmWindow.mozInnerScreenX) * ratio,
(y + elmWindow.mozInnerScreenY) * ratio,
width * ratio,
height * ratio ];
}