Bug 559993. Scroll the whole selection into view, not just the focus point when finding on a page. r=roc a=blocking-final+

This commit is contained in:
Timothy Nikkel 2010-11-24 19:35:02 -06:00
parent d71d1bdc9f
commit 5c1b10cee6
6 changed files with 99 additions and 5 deletions

View File

@ -199,6 +199,7 @@ _BROWSER_FILES = \
browser_tab_dragdrop2_frame1.xul \ browser_tab_dragdrop2_frame1.xul \
browser_tabfocus.js \ browser_tabfocus.js \
browser_tabs_owner.js \ browser_tabs_owner.js \
browser_visibleFindSelection.js \
browser_visibleTabs.js \ browser_visibleTabs.js \
browser_visibleTabs_contextMenu.js \ browser_visibleTabs_contextMenu.js \
browser_visibleTabs_bookmarkAllPages.js \ browser_visibleTabs_bookmarkAllPages.js \

View File

@ -0,0 +1,39 @@
function test() {
waitForExplicitFinish();
let tab = gBrowser.addTab();
gBrowser.selectedTab = tab;
tab.linkedBrowser.addEventListener("load", function(aEvent) {
tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
ok(true, "Load listener called");
waitForFocus(onFocus, content);
}, true);
content.location = "data:text/html,<div style='position: absolute; left: 2200px; background: green; width: 200px; height: 200px;'>div</div><div style='position: absolute; left: 0px; background: red; width: 200px; height: 200px;'><span id='s'>div</span></div>";
}
function onFocus() {
EventUtils.synthesizeKey("f", { accelKey: true });
ok(gFindBarInitialized, "find bar is now initialized");
EventUtils.synthesizeKey("d", {});
EventUtils.synthesizeKey("i", {});
EventUtils.synthesizeKey("v", {});
// finds the div in the green box
EventUtils.synthesizeKey("g", { accelKey: true });
// finds the div in the red box
var rect = content.document.getElementById("s").getBoundingClientRect();
ok(rect.left >= 0, "scroll should include find result");
// clear the find bar
EventUtils.synthesizeKey("a", { accelKey: true });
EventUtils.synthesizeKey("VK_DELETE", { });
gFindBar.close();
gBrowser.removeCurrentTab();
finish();
}

View File

@ -67,7 +67,8 @@ interface nsISelectionController : nsISelectionDisplay
const short SELECTION_ANCHOR_REGION = 0; const short SELECTION_ANCHOR_REGION = 0;
const short SELECTION_FOCUS_REGION = 1; const short SELECTION_FOCUS_REGION = 1;
const short NUM_SELECTION_REGIONS = 2; const short SELECTION_WHOLE_SELECTION = 2;
const short NUM_SELECTION_REGIONS = 3;
const short SELECTION_OFF = 0; const short SELECTION_OFF = 0;
const short SELECTION_HIDDEN =1;//>HIDDEN displays selection const short SELECTION_HIDDEN =1;//>HIDDEN displays selection

View File

@ -451,7 +451,7 @@ void nsWebBrowserFind::SetSelectionAndScroll(nsIDOMWindow* aWindow,
// flushed and PresShell/PresContext/Frames may be dead. See bug 418470. // flushed and PresShell/PresContext/Frames may be dead. See bug 418470.
selCon->ScrollSelectionIntoView selCon->ScrollSelectionIntoView
(nsISelectionController::SELECTION_NORMAL, (nsISelectionController::SELECTION_NORMAL,
nsISelectionController::SELECTION_FOCUS_REGION, nsISelectionController::SELECTION_WHOLE_SELECTION,
nsISelectionController::SCROLL_SYNCHRONOUS); nsISelectionController::SCROLL_SYNCHRONOUS);
} }
} }

View File

@ -198,9 +198,16 @@ public:
// utility methods for scrolling the selection into view // utility methods for scrolling the selection into view
nsresult GetPresContext(nsPresContext **aPresContext); nsresult GetPresContext(nsPresContext **aPresContext);
nsresult GetPresShell(nsIPresShell **aPresShell); nsresult GetPresShell(nsIPresShell **aPresShell);
// Returns the position of the region, and frame that that position is relative // Returns a rect containing the selection region, and frame that that
// to. The 'position' is a zero-width rectangle. // position is relative to. For SELECTION_ANCHOR_REGION or
// SELECTION_FOCUS_REGION the rect is a zero-width rectangle. For
// SELECTION_WHOLE_SELECTION the rect contains both the anchor and focus
// region rects.
nsIFrame* GetSelectionAnchorGeometry(SelectionRegion aRegion, nsRect *aRect); nsIFrame* GetSelectionAnchorGeometry(SelectionRegion aRegion, nsRect *aRect);
// Returns the position of the region (SELECTION_ANCHOR_REGION or
// SELECTION_FOCUS_REGION only), and frame that that position is relative to.
// The 'position' is a zero-width rectangle.
nsIFrame* GetSelectionEndPointGeometry(SelectionRegion aRegion, nsRect *aRect);
nsresult PostScrollSelectionIntoViewEvent(SelectionRegion aRegion, PRBool aFirstAncestorOnly); nsresult PostScrollSelectionIntoViewEvent(SelectionRegion aRegion, PRBool aFirstAncestorOnly);
enum { enum {
@ -5509,6 +5516,52 @@ nsTypedSelection::GetSelectionAnchorGeometry(SelectionRegion aRegion,
aRect->SetRect(0, 0, 0, 0); aRect->SetRect(0, 0, 0, 0);
switch (aRegion) {
case nsISelectionController::SELECTION_ANCHOR_REGION:
case nsISelectionController::SELECTION_FOCUS_REGION:
return GetSelectionEndPointGeometry(aRegion, aRect);
break;
case nsISelectionController::SELECTION_WHOLE_SELECTION:
break;
default:
return nsnull;
}
NS_ASSERTION(aRegion == nsISelectionController::SELECTION_WHOLE_SELECTION,
"should only be SELECTION_WHOLE_SELECTION here");
nsRect anchorRect;
nsIFrame* anchorFrame = GetSelectionEndPointGeometry(
nsISelectionController::SELECTION_ANCHOR_REGION, &anchorRect);
if (!anchorFrame)
return nsnull;
nsRect focusRect;
nsIFrame* focusFrame = GetSelectionEndPointGeometry(
nsISelectionController::SELECTION_FOCUS_REGION, &focusRect);
if (!focusFrame)
return nsnull;
NS_ASSERTION(anchorFrame->PresContext() == focusFrame->PresContext(),
"points of selection in different documents?");
// make focusRect relative to anchorFrame
focusRect += focusFrame->GetOffsetTo(anchorFrame);
aRect->UnionRectIncludeEmpty(anchorRect, focusRect);
return anchorFrame;
}
nsIFrame *
nsTypedSelection::GetSelectionEndPointGeometry(SelectionRegion aRegion,
nsRect *aRect)
{
if (!mFrameSelection)
return nsnull; // nothing to do
NS_ENSURE_TRUE(aRect, nsnull);
aRect->SetRect(0, 0, 0, 0);
nsINode *node = nsnull; nsINode *node = nsnull;
PRInt32 nodeOffset = 0; PRInt32 nodeOffset = 0;
nsIFrame *frame = nsnull; nsIFrame *frame = nsnull;

View File

@ -562,7 +562,7 @@ nsTypeAheadFind::FindItNow(nsIPresShell *aPresShell, PRBool aIsLinksOnly,
SetSelectionModeAndRepaint(nsISelectionController::SELECTION_ATTENTION); SetSelectionModeAndRepaint(nsISelectionController::SELECTION_ATTENTION);
selectionController->ScrollSelectionIntoView( selectionController->ScrollSelectionIntoView(
nsISelectionController::SELECTION_NORMAL, nsISelectionController::SELECTION_NORMAL,
nsISelectionController::SELECTION_FOCUS_REGION, nsISelectionController::SELECTION_WHOLE_SELECTION,
nsISelectionController::SCROLL_SYNCHRONOUS); nsISelectionController::SCROLL_SYNCHRONOUS);
} }