Bug 727942 - scrollToPoint is broken when page is zoomed, r=tbsaunde, f=roc

This commit is contained in:
Alexander Surkov 2012-10-20 00:10:28 +09:00
parent f3cb73b9c7
commit 4e69a50fef
8 changed files with 214 additions and 24 deletions

View File

@ -381,8 +381,9 @@ nsAccUtils::GetScreenCoordsForParent(nsAccessNode *aAccessNode)
if (!parentFrame)
return nsIntPoint(0, 0);
nsIntRect parentRect = parentFrame->GetScreenRectExternal();
return nsIntPoint(parentRect.x, parentRect.y);
nsRect rect = parentFrame->GetScreenRectInAppUnits();
return nsPoint(rect.x, rect.y).
ToNearestPixels(parentFrame->PresContext()->AppUnitsPerDevPixel());
}
uint8_t

View File

@ -9,6 +9,8 @@
#include "nsAccessNode.h"
#include "nsIBaseWindow.h"
#include "nsIDocShellTreeOwner.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsIDOMHTMLDocument.h"
@ -303,19 +305,14 @@ nsCoreUtils::ScrollFrameToPoint(nsIFrame *aScrollableFrame,
nsIFrame *aFrame,
const nsIntPoint& aPoint)
{
nsIScrollableFrame *scrollableFrame = do_QueryFrame(aScrollableFrame);
nsIScrollableFrame* scrollableFrame = do_QueryFrame(aScrollableFrame);
if (!scrollableFrame)
return;
nsPresContext *presContext = aFrame->PresContext();
nsIntRect frameRect = aFrame->GetScreenRectExternal();
int32_t devDeltaX = aPoint.x - frameRect.x;
int32_t devDeltaY = aPoint.y - frameRect.y;
nsPoint deltaPoint;
deltaPoint.x = presContext->DevPixelsToAppUnits(devDeltaX);
deltaPoint.y = presContext->DevPixelsToAppUnits(devDeltaY);
nsPoint point =
aPoint.ToAppUnits(aFrame->PresContext()->AppUnitsPerDevPixel());
nsRect frameRect = aFrame->GetScreenRectInAppUnits();
nsPoint deltaPoint(point.x - frameRect.x, point.y - frameRect.y);
nsPoint scrollPoint = scrollableFrame->GetScrollPosition();
scrollPoint -= deltaPoint;
@ -386,19 +383,15 @@ nsCoreUtils::GetScreenCoordsForWindow(nsINode *aNode)
if (!treeItem)
return coords;
nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
nsCOMPtr<nsIDOMDocument> domDoc = do_GetInterface(rootTreeItem);
if (!domDoc)
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
treeItem->GetTreeOwner(getter_AddRefs(treeOwner));
if (!treeOwner)
return coords;
nsCOMPtr<nsIDOMWindow> window;
domDoc->GetDefaultView(getter_AddRefs(window));
if (!window)
return coords;
nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(treeOwner);
if (baseWindow)
baseWindow->GetPosition(&coords.x, &coords.y); // in device pixels
window->GetScreenX(&coords.x);
window->GetScreenY(&coords.y);
return coords;
}

View File

@ -168,7 +168,8 @@ public:
nsIPresShell::ScrollAxis *aHorizontal);
/**
* Returns coordinates relative screen for the top level window.
* Returns coordinates in device pixels relative screen for the top level
* window.
*
* @param aNode the DOM node hosted in the window.
*/

View File

@ -24,6 +24,7 @@ DIRS = \
pivot \
relations \
role \
scroll \
selectable \
states \
table \

View File

@ -73,6 +73,10 @@ const STATE_BUSY = nsIAccessibleStates.STATE_BUSY;
const SCROLL_TYPE_ANYWHERE = nsIAccessibleScrollType.SCROLL_TYPE_ANYWHERE;
const COORDTYPE_SCREEN_RELATIVE = nsIAccessibleCoordinateType.COORDTYPE_SCREEN_RELATIVE;
const COORDTYPE_WINDOW_RELATIVE = nsIAccessibleCoordinateType.COORDTYPE_WINDOW_RELATIVE;
const COORDTYPE_PARENT_RELATIVE = nsIAccessibleCoordinateType.COORDTYPE_PARENT_RELATIVE;
const kEmbedChar = String.fromCharCode(0xfffc);
const kDiscBulletText = String.fromCharCode(0x2022) + " ";

View File

@ -91,6 +91,19 @@ function getChildAtPoint(aIdentifier, aX, aY, aFindDeepestChild)
return null;
}
/**
* Test the accessible position.
*/
function testPos(aID, aPoint)
{
var [expectedX, expectedY] =
(aPoint != undefined) ? aPoint : getBoundsForDOMElm(aID);
var [x, y] = getBounds(aID);
is(x, expectedX, "Wrong x coordinate of " + prettyName(aID));
is(y, expectedY, "Wrong y coordinate of " + prettyName(aID));
}
/**
* Test the accessible boundaries.
*/
@ -107,7 +120,19 @@ function testBounds(aID, aRect)
}
/**
* Return the accessible coordinates and size relative to the screen.
* Return the accessible coordinates relative to the screen in device pixels.
*/
function getPos(aID)
{
var accessible = getAccessible(aID);
var x = {}, y = {};
accessible.getBounds(x, y, {}, {});
return [x.value, y.value];
}
/**
* Return the accessible coordinates and size relative to the screen in device
* pixels.
*/
function getBounds(aID)
{

View File

@ -0,0 +1,18 @@
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = accessible/scroll
include $(DEPTH)/config/autoconf.mk
MOCHITEST_A11Y_FILES =\
test_zoom.html \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,147 @@
<!DOCTYPE html>
<html>
<head>
<title>Test scrollToPoint when page is zoomed</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="../layout.js"></script>
<script type="application/javascript">
function testScrollToPoint()
{
// scrollToPoint relative screen
var anchor = getAccessible("bottom1");
var [x, y] = getPos(anchor);
var [docX, docY] = getPos(document);
anchor.scrollToPoint(COORDTYPE_SCREEN_RELATIVE, docX, docY);
testPos(anchor, [x, docY]);
// scrollToPoint relative window
anchor = getAccessible("bottom2");
var [x, y] = getPos(anchor);
var wnd = getRootAccessible().DOMDocument.defaultView;
var scrollToX = docX - wnd.screenX, scrollToY = docY - wnd.screenY;
anchor.scrollToPoint(COORDTYPE_WINDOW_RELATIVE, scrollToX, scrollToY);
testPos(anchor, [x, docY]);
// scrollToPoint relative parent
anchor = getAccessible("bottom3");
var [x, y] = getPos(anchor);
var [parentX, parentY] = getPos(anchor.parent);
var scrollToX = parentX - docX, scrollToY = parentY - docY;
anchor.scrollToPoint(COORDTYPE_PARENT_RELATIVE, scrollToX, scrollToY);
testPos(anchor, [x, docY]);
}
function doTest()
{
testScrollToPoint();
zoomDocument(document, 2.0);
testScrollToPoint(); // zoom and test again
zoomDocument(document, 1.0);
SimpleTest.finish();
}
addA11yLoadEvent(doTest);
SimpleTest.waitForExplicitFinish();
</script>
</head>
<body>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=727942"
title="scrollToPoint is broken when page is zoomed">
Mozilla Bug 727942
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<h1>Below there is a bunch of named anchors</h1>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
This is in the middle anchor #1<a id="bottom1"></a>
<br><br><br><br><br><br><br><br><br><br>
This is in the middle anchor #2<a id="bottom2"></a>
<br><br><br><br><br><br><br><br><br><br>
This is in the middle anchor #3<a id="bottom3"></a>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
</body>
</html>