Bug 783531 - Implement a 'select word at point' text selection routine in nsIDOMWindowUtils. r=roc

This commit is contained in:
Jim Mathies 2012-09-10 16:02:23 -05:00
parent 22c79f9cc8
commit bf296876b6
9 changed files with 497 additions and 42 deletions

View File

@ -19,6 +19,7 @@
#include "nsDOMTouchEvent.h" #include "nsDOMTouchEvent.h"
#include "nsIDOMTouchEvent.h" #include "nsIDOMTouchEvent.h"
#include "nsObjectLoadingContent.h" #include "nsObjectLoadingContent.h"
#include "nsFrame.h"
#include "nsIScrollableFrame.h" #include "nsIScrollableFrame.h"
@ -2809,3 +2810,76 @@ nsDOMWindowUtils::ExitFullscreen()
nsIDocument::ExitFullScreen(/* async = */ false); nsIDocument::ExitFullScreen(/* async = */ false);
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsDOMWindowUtils::SelectAtPoint(float aX, float aY, PRUint32 aSelectBehavior,
bool *_retval)
{
*_retval = false;
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsSelectionAmount amount;
switch (aSelectBehavior) {
case nsIDOMWindowUtils::SELECT_CHARACTER:
amount = eSelectCharacter;
break;
case nsIDOMWindowUtils::SELECT_CLUSTER:
amount = eSelectCluster;
break;
case nsIDOMWindowUtils::SELECT_WORD:
amount = eSelectWord;
break;
case nsIDOMWindowUtils::SELECT_LINE:
amount = eSelectLine;
break;
case nsIDOMWindowUtils::SELECT_BEGINLINE:
amount = eSelectBeginLine;
break;
case nsIDOMWindowUtils::SELECT_ENDLINE:
amount = eSelectEndLine;
break;
case nsIDOMWindowUtils::SELECT_PARAGRAPH:
amount = eSelectParagraph;
break;
case nsIDOMWindowUtils::SELECT_WORDNOSPACE:
amount = eSelectWordNoSpace;
break;
}
nsIPresShell* presShell = GetPresShell();
if (!presShell) {
return NS_ERROR_UNEXPECTED;
}
// The root frame for this content window
nsIFrame* rootFrame = presShell->FrameManager()->GetRootFrame();
if (!rootFrame) {
return NS_ERROR_UNEXPECTED;
}
// Get the target frame at the client coordinates passed to us
nsCOMPtr<nsIWidget> widget = GetWidget();
nsIntPoint pt(aX, aY);
nsPoint ptInRoot =
nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, rootFrame);
nsIFrame* targetFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, ptInRoot);
// This can happen if the page hasn't loaded yet or if the point
// is outside the frame.
if (!targetFrame) {
return NS_ERROR_INVALID_ARG;
}
// Convert point to coordinates relative to the target frame, which is
// what targetFrame's SelectByTypeAtPoint expects.
nsPoint relPoint =
nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, targetFrame);
nsresult rv =
static_cast<nsFrame*>(targetFrame)->
SelectByTypeAtPoint(GetPresContext(), relPoint, amount, amount,
nsFrame::SELECT_ACCUMULATE);
*_retval = !NS_FAILED(rv);
return NS_OK;
}

View File

@ -39,7 +39,7 @@ interface nsIFile;
interface nsIDOMTouch; interface nsIDOMTouch;
interface nsIDOMClientRect; interface nsIDOMClientRect;
[scriptable, uuid(f7222baa-7c4b-4079-a9e0-db13cf797f58)] [scriptable, uuid(8A7DA5AF-26FD-4449-8887-9BEADC938B0A)]
interface nsIDOMWindowUtils : nsISupports { interface nsIDOMWindowUtils : nsISupports {
/** /**
@ -921,6 +921,33 @@ interface nsIDOMWindowUtils : nsISupports {
in unsigned long aLength, in unsigned long aLength,
in boolean aReverse); in boolean aReverse);
/* Selection behaviors - mirror nsIFrame's nsSelectionAmount constants */
const unsigned long SELECT_CHARACTER = 0;
const unsigned long SELECT_CLUSTER = 1;
const unsigned long SELECT_WORD = 2;
const unsigned long SELECT_LINE = 3;
const unsigned long SELECT_BEGINLINE = 4;
const unsigned long SELECT_ENDLINE = 5;
const unsigned long SELECT_PARAGRAPH = 6;
const unsigned long SELECT_WORDNOSPACE = 7;
/**
* Select content at a client point based on a selection behavior if the
* underlying content is selectable. Selection will accumulate with any
* existing selection, callers should clear selection prior if needed.
* May fire selection changed events. Calls nsFrame's SelectByTypeAtPoint.
*
* @param aX, aY The selection point in client coordinates.
* @param aSelectType The selection behavior requested.
* @return True if a selection occured, false otherwise.
* @throw NS_ERROR_DOM_SECURITY_ERR, NS_ERROR_UNEXPECTED for utils
* issues, and NS_ERROR_INVALID_ARG for coordinates that are outside
* this window.
*/
boolean selectAtPoint(in float aX,
in float aY,
in unsigned long aSelectBehavior);
/** /**
* Perform the equivalent of: * Perform the equivalent of:
* window.getComputedStyle(aElement, aPseudoElement). * window.getComputedStyle(aElement, aPseudoElement).

View File

@ -46,6 +46,8 @@ MOCHITEST_CHROME_FILES = \
window_callback_wrapping.xul \ window_callback_wrapping.xul \
test_sandbox_postMessage.html \ test_sandbox_postMessage.html \
test_sandbox_bindings.xul \ test_sandbox_bindings.xul \
test_selectAtPoint.html \
selectAtPoint.html \
$(NULL) $(NULL)
ifeq (WINNT,$(OS_ARCH)) ifeq (WINNT,$(OS_ARCH))

View File

@ -0,0 +1,271 @@
<!DOCTYPE HTML>
<html>
<head>
<title>nsIDOMWindowUtils::selectAtPoint test</title>
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
<script type="application/javascript;version=1.8">
let SimpleTest = window.opener.SimpleTest;
let Ci = Components.interfaces;
function ok() { window.opener.ok.apply(window.opener, arguments); }
function done() { window.opener.done.apply(window.opener, arguments); }
function dumpLn() {
for (let idx = 0; idx < arguments.length; idx++)
dump(arguments[idx] + " ");
dump("\n");
}
function getCharacterDims() {
let span = document.getElementById("measure");
let rect = span.getBoundingClientRect();
return { width: rect.right - rect.left,
height: rect.bottom - rect.top };
}
function setStart(aDWU, aX, aY, aSelectType)
{
// Clear any existing selection
let selection = document.getSelection();
selection.removeAllRanges();
// Select text
let result = aDWU.selectAtPoint(aX, aY, aSelectType);
ok(result == true, "selectAtPoint secceeded?");
}
function setEnd(aDWU, aX, aY, aSelectType)
{
// Select text
let result = aDWU.selectAtPoint(aX, aY, aSelectType);
ok(result == true, "selectAtPoint secceeded?");
}
function setSingle(aDWU, aX, aY, aSelectType, aSelectTypeStr, aExpectedSelectionText) {
// Clear any existing selection
let selection = document.getSelection();
selection.removeAllRanges();
// Select text
let result = aDWU.selectAtPoint(aX, aY, aSelectType);
ok(result == true, "selectAtPoint secceeded?");
}
function checkSelection(aDoc, aSelectTypeStr, aExpectedSelectionText) {
// Retrieve text selected
let selection = aDoc.getSelection();
let text = selection.toString();
// Test
let result = (text == aExpectedSelectionText);
ok(result, aSelectTypeStr + " selection text matches?");
if (!result) {
dumpLn(aSelectTypeStr + " selection text:", "[" + text + "] expected:[" + aExpectedSelectionText + "]" );
}
}
function doTest() {
let dwu = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let os = Components.classes["@mozilla.org/xre/app-info;1"]
.getService(Ci.nsIXULRuntime).OS;
let isLinux = (os == "Linux");
let isMac = (os == "Darwin");
let isWindows = (os == "WINNT");
if (!isLinux && !isMac && !isWindows) {
done();
return;
}
window.scrollTo(0, 0);
// Trick to get character spacing - get the bounds around a
// single character trapped in a div.
let charDims = getCharacterDims();
// dumpLn("character dims:", charDims.width, charDims.height);
//
// Root frame selection
//
// First div in the main page
let div = document.getElementById("div1");
let rect = div.getBoundingClientRect();
// Centered on the first character in the sentence div
let targetPoint = { xPos: rect.left + (charDims.width / 2),
yPos: rect.top + (charDims.height / 2) };
setSingle(dwu, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_WORDNOSPACE);
checkSelection(document, "SELECT_WORDNOSPACE", "ttestselection1");
setSingle(dwu, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_WORD);
if (isLinux || isMac) {
checkSelection(document, "SELECT_WORD", "ttestselection1");
} else if (isWindows) {
checkSelection(document, "SELECT_WORD", "ttestselection1 ");
}
setSingle(dwu, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_PARAGRAPH);
checkSelection(document, "SELECT_PARAGRAPH", "ttestselection1 Lorem ipsum dolor sit amet, at duo debet graeci, vivendum vulputate per ut. Ne labore incorrupte vix. Cu copiosae postulant tincidunt ius, in illud appetere contentiones eos. Ei munere officiis assentior pro, nibh decore ius at.");
// Centered on the second character in the sentence div
let targetPoint = { xPos: rect.left + (charDims.width + (charDims.width / 2)),
yPos: rect.top + (charDims.height / 2) };
setSingle(dwu, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_CHARACTER);
checkSelection(document, "SELECT_CHARACTER", "te");
setSingle(dwu, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_CLUSTER);
checkSelection(document, "SELECT_CLUSTER", "te");
// Separate character blocks in a word 't(te)s(ts)election1'
let targetPoint = { xPos: rect.left + (charDims.width + (charDims.width / 2)),
yPos: rect.top + (charDims.height / 2) };
setStart(dwu, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_CHARACTER);
let targetPoint = { xPos: rect.left + ((charDims.width * 4) + (charDims.width / 2)),
yPos: rect.top + (charDims.height / 2) };
setEnd(dwu, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_CHARACTER);
if (isLinux || isMac) {
// XXX I think this is a bug, the right hand selection is 4.5 characters over with a
// monspaced font. what we want: t(te)s(ts)election1 what we get: t(te)st(se)lection1
checkSelection(document, "split selection", "tese");
} else if (isWindows) {
checkSelection(document, "split selection", "tets");
}
// Trying to select where there's no text, should fail but not throw
let result = dwu.selectAtPoint(rect.left - 20, rect.top - 20, Ci.nsIDOMWindowUtils.SELECT_CHARACTER, false);
ok(result == false, "couldn't select?");
// Second div in the main page
let div = document.getElementById("div2");
let rect = div.getBoundingClientRect();
// Centered on the first line, first character in the paragraph div
let targetPoint = { xPos: rect.left + (charDims.width / 2),
yPos: rect.top + (charDims.height / 2) };
setSingle(dwu, targetPoint.xPos + 50, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_PARAGRAPH);
checkSelection(document, "SELECT_PARAGRAPH", "Lorem ipsum dolor sit amet, at duo debet graeci, vivendum vulputate per ut. Ne labore incorrupte vix. Cu copiosae postulant tincidunt ius, in illud appetere contentiones eos.");
//
// Inner IFRAME selection tests
//
let frame = document.getElementById("frame1");
let dwuFrame = frame.contentDocument
.defaultView
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
frame.contentWindow.scrollTo(0, 0);
let rect = frame.getBoundingClientRect();
let targetPoint = { xPos: rect.left + (charDims.width / 2),
yPos: rect.top + (charDims.height / 2) };
setSingle(dwuFrame, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_WORDNOSPACE);
checkSelection(frame.contentWindow.document, "SELECT_WORDNOSPACE", "ttestselection2");
setSingle(dwuFrame, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_WORD);
if (isLinux || isMac) {
checkSelection(frame.contentWindow.document, "SELECT_WORD", "ttestselection2");
} else if (isWindows) {
checkSelection(frame.contentWindow.document, "SELECT_WORD", "ttestselection2 ");
}
setSingle(dwuFrame, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_PARAGRAPH);
checkSelection(frame.contentWindow.document, "SELECT_PARAGRAPH", "ttestselection2 Lorem ipsum dolor sit amet, at duo debet graeci, vivendum vulputate per ut.");
// Outside the frame should throw. This is a failure in coordinate setup of
// nsDOMWindowUtils::SelectAtPoint.
let thr = false;
try {
dwuFrame.selectAtPoint(rect.right + 50, rect.top, Ci.nsIDOMWindowUtils.SELECT_WORD, false);
} catch (ex) { thr = true; }
ok(thr == true, "selectAtPoint expected throw?");
done();
}
let frameLoad = false;
let pageLoad = false;
let painted = false;
function testReady() {
if (frameLoad && pageLoad && painted)
doTest();
}
function onFrameLoad() {
frameLoad = true;
testReady();
}
function onPageLoad() {
pageLoad = true;
testReady();
}
function onPaint() {
window.removeEventListener("MozAfterPaint", onPaint, false);
painted = true;
testReady();
}
window.addEventListener("MozAfterPaint", onPaint, false);
</script>
<style type="text/css">
body {
font-family: monospace;
margin-left: 40px;
margin-top: 40px;
padding: 0;
}
#div1 {
border: 1px solid red;
width: 400px;
height: 100px;
}
#frame1 {
display: block;
height: 100px;
width: 300px;
border: 1px solid blue;
padding: 0;
margin: 0;
}
#div2 {
border: 1px solid green;
}
#measure {
padding: 0px;
margin: 0px;
border: 1px solid red;
}
</style>
</head>
<body id="body" onload="onPageLoad();">
<div id="div1">ttestselection1 Lorem ipsum dolor sit amet, at duo debet graeci, vivendum vulputate per ut. Ne labore incorrupte vix. Cu copiosae postulant tincidunt ius, in illud appetere contentiones eos. Ei munere officiis assentior pro, nibh decore ius at.</div>
<br />
<iframe id="frame1" src="data:text/html,<html><body style='margin: 0; padding: 0; font-family: monospace;' onload='window.parent.onFrameLoad();'><div id='sel2'>ttestselection2 Lorem ipsum dolor sit amet, at duo debet graeci, vivendum vulputate per ut.</div><br/><br/></body></html>"></iframe>
<br/>
<div id="div2">Lorem ipsum dolor sit amet, at duo debet graeci, vivendum vulputate per ut. Ne labore incorrupte vix. Cu copiosae postulant tincidunt ius, in illud appetere contentiones eos.</div>
<br />
<span id="measure">t</span>
</body>
</html>

View File

@ -0,0 +1,21 @@
<!DOCTYPE HTML>
<html>
<head>
<title>nsIDOMWindowUtils::selectAtPoint test</title>
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
function done() {
testwindow.close();
SimpleTest.finish();
}
var testwindow = window.open("selectAtPoint.html", '_new', 'width=800,height=800');
</script>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</body>
</html>

View File

@ -1042,10 +1042,22 @@ nsLayoutUtils::GetEventCoordinatesRelativeTo(const nsEvent* aEvent,
return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
} }
return GetEventCoordinatesRelativeTo(widget, aPoint, aFrame);
}
nsPoint
nsLayoutUtils::GetEventCoordinatesRelativeTo(nsIWidget* aWidget,
const nsIntPoint aPoint,
nsIFrame* aFrame)
{
if (!aFrame || !aWidget) {
return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
}
nsIView* view = aFrame->GetView(); nsIView* view = aFrame->GetView();
if (view) { if (view) {
nsIWidget* frameWidget = view->GetWidget(); nsIWidget* frameWidget = view->GetWidget();
if (frameWidget && frameWidget == GUIEvent->widget) { if (frameWidget && frameWidget == aWidget) {
// Special case this cause it happens a lot. // Special case this cause it happens a lot.
// This also fixes bug 664707, events in the extra-special case of select // This also fixes bug 664707, events in the extra-special case of select
// dropdown popups that are transformed. // dropdown popups that are transformed.
@ -1076,7 +1088,7 @@ nsLayoutUtils::GetEventCoordinatesRelativeTo(const nsEvent* aEvent,
} }
nsPoint widgetToView = TranslateWidgetToView(rootFrame->PresContext(), nsPoint widgetToView = TranslateWidgetToView(rootFrame->PresContext(),
widget, aPoint, rootView); aWidget, aPoint, rootView);
if (widgetToView == nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE)) { if (widgetToView == nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE)) {
return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);

View File

@ -416,6 +416,20 @@ public:
const nsIntPoint aPoint, const nsIntPoint aPoint,
nsIFrame* aFrame); nsIFrame* aFrame);
/**
* Get the coordinates of a given point relative to a widget and a
* given frame.
* @param aWidget the event src widget
* @param aPoint the point to get the coordinates relative to
* @param aFrame the frame to make coordinates relative to
* @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if
* for some reason the coordinates for the mouse are not known (e.g.,
* the event is not a GUI event).
*/
static nsPoint GetEventCoordinatesRelativeTo(nsIWidget* aWidget,
const nsIntPoint aPoint,
nsIFrame* aFrame);
/** /**
* Get the popup frame of a given native mouse event. * Get the popup frame of a given native mouse event.
* @param aPresContext only check popups within aPresContext or a descendant * @param aPresContext only check popups within aPresContext or a descendant

View File

@ -2780,22 +2780,70 @@ nsFrame::HandlePress(nsPresContext* aPresContext,
return rv; return rv;
} }
/*
* SelectByTypeAtPoint
*
* Search for selectable content at point and attempt to select
* based on the start and end selection behaviours.
*
* @param aPresContext Presentation context
* @param aPoint Point at which selection will occur. Coordinates
* should be relaitve to this frame.
* @param aBeginAmountType, aEndAmountType Selection behavior, see
* nsIFrame for definitions.
* @param aSelectFlags Selection flags defined in nsFame.h.
* @return success or failure at finding suitable content to select.
*/
nsresult
nsFrame::SelectByTypeAtPoint(nsPresContext* aPresContext,
const nsPoint& aPoint,
nsSelectionAmount aBeginAmountType,
nsSelectionAmount aEndAmountType,
uint32_t aSelectFlags)
{
NS_ENSURE_ARG_POINTER(aPresContext);
// No point in selecting if selection is turned off
if (DisplaySelection(aPresContext) == nsISelectionController::SELECTION_OFF)
return NS_OK;
ContentOffsets offsets = GetContentOffsetsFromPoint(aPoint, SKIP_HIDDEN);
if (!offsets.content)
return NS_ERROR_FAILURE;
nsIFrame* theFrame;
int32_t offset;
const nsFrameSelection* frameSelection =
PresContext()->GetPresShell()->ConstFrameSelection();
theFrame = frameSelection->
GetFrameForNodeOffset(offsets.content, offsets.offset,
nsFrameSelection::HINT(offsets.associateWithNext),
&offset);
if (!theFrame)
return NS_ERROR_FAILURE;
nsFrame* frame = static_cast<nsFrame*>(theFrame);
return frame->PeekBackwardAndForward(aBeginAmountType, aEndAmountType,
offsets.offset, aPresContext,
aBeginAmountType != eSelectWord,
aSelectFlags);
}
/** /**
* Multiple Mouse Press -- line or paragraph selection -- for the frame. * Multiple Mouse Press -- line or paragraph selection -- for the frame.
* Wouldn't it be nice if this didn't have to be hardwired into Frame code? * Wouldn't it be nice if this didn't have to be hardwired into Frame code?
*/ */
NS_IMETHODIMP NS_IMETHODIMP
nsFrame::HandleMultiplePress(nsPresContext* aPresContext, nsFrame::HandleMultiplePress(nsPresContext* aPresContext,
nsGUIEvent* aEvent, nsGUIEvent* aEvent,
nsEventStatus* aEventStatus, nsEventStatus* aEventStatus,
bool aControlHeld) bool aControlHeld)
{ {
NS_ENSURE_ARG_POINTER(aEvent);
NS_ENSURE_ARG_POINTER(aEventStatus); NS_ENSURE_ARG_POINTER(aEventStatus);
if (nsEventStatus_eConsumeNoDefault == *aEventStatus) {
return NS_OK;
}
if (DisplaySelection(aPresContext) == nsISelectionController::SELECTION_OFF) { if (nsEventStatus_eConsumeNoDefault == *aEventStatus ||
DisplaySelection(aPresContext) == nsISelectionController::SELECTION_OFF) {
return NS_OK; return NS_OK;
} }
@ -2823,37 +2871,18 @@ nsFrame::HandleMultiplePress(nsPresContext* aPresContext,
return NS_OK; return NS_OK;
} }
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this); nsPoint relPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
ContentOffsets offsets = GetContentOffsetsFromPoint(pt, SKIP_HIDDEN); return SelectByTypeAtPoint(aPresContext, relPoint, beginAmount, endAmount,
if (!offsets.content) return NS_ERROR_FAILURE; (aControlHeld ? SELECT_ACCUMULATE : 0));
nsIFrame* theFrame;
int32_t offset;
// Maybe make this a static helper?
const nsFrameSelection* frameSelection =
PresContext()->GetPresShell()->ConstFrameSelection();
theFrame = frameSelection->
GetFrameForNodeOffset(offsets.content, offsets.offset,
nsFrameSelection::HINT(offsets.associateWithNext),
&offset);
if (!theFrame)
return NS_ERROR_FAILURE;
nsFrame* frame = static_cast<nsFrame*>(theFrame);
return frame->PeekBackwardAndForward(beginAmount, endAmount,
offsets.offset, aPresContext,
beginAmount != eSelectWord,
aControlHeld);
} }
NS_IMETHODIMP nsresult
nsFrame::PeekBackwardAndForward(nsSelectionAmount aAmountBack, nsFrame::PeekBackwardAndForward(nsSelectionAmount aAmountBack,
nsSelectionAmount aAmountForward, nsSelectionAmount aAmountForward,
int32_t aStartPos, int32_t aStartPos,
nsPresContext* aPresContext, nsPresContext* aPresContext,
bool aJumpLines, bool aJumpLines,
bool aMultipleSelection) uint32_t aSelectFlags)
{ {
nsIFrame* baseFrame = this; nsIFrame* baseFrame = this;
int32_t baseOffset = aStartPos; int32_t baseOffset = aStartPos;
@ -2907,7 +2936,7 @@ nsFrame::PeekBackwardAndForward(nsSelectionAmount aAmountBack,
rv = frameSelection->HandleClick(startpos.mResultContent, rv = frameSelection->HandleClick(startpos.mResultContent,
startpos.mContentOffset, startpos.mContentOffset, startpos.mContentOffset, startpos.mContentOffset,
false, aMultipleSelection, false, (aSelectFlags & SELECT_ACCUMULATE),
nsFrameSelection::HINTRIGHT); nsFrameSelection::HINTRIGHT);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return rv; return rv;

View File

@ -339,9 +339,7 @@ public:
virtual bool UpdateOverflow(); virtual bool UpdateOverflow();
// Selection Methods // Selection Methods
// XXX Doc me... (in nsIFrame.h puhleeze)
// XXX If these are selection specific, then the name should imply selection
// rather than generic event processing, e.g., SelectionHandlePress...
NS_IMETHOD HandlePress(nsPresContext* aPresContext, NS_IMETHOD HandlePress(nsPresContext* aPresContext,
nsGUIEvent * aEvent, nsGUIEvent * aEvent,
nsEventStatus* aEventStatus); nsEventStatus* aEventStatus);
@ -359,13 +357,20 @@ public:
nsGUIEvent * aEvent, nsGUIEvent * aEvent,
nsEventStatus* aEventStatus); nsEventStatus* aEventStatus);
NS_IMETHOD PeekBackwardAndForward(nsSelectionAmount aAmountBack, enum { SELECT_ACCUMULATE = 0x01 };
nsSelectionAmount aAmountForward,
int32_t aStartPos,
nsPresContext* aPresContext,
bool aJumpLines,
bool aMultipleSelection);
nsresult PeekBackwardAndForward(nsSelectionAmount aAmountBack,
nsSelectionAmount aAmountForward,
int32_t aStartPos,
nsPresContext* aPresContext,
bool aJumpLines,
uint32_t aSelectFlags);
nsresult SelectByTypeAtPoint(nsPresContext* aPresContext,
const nsPoint& aPoint,
nsSelectionAmount aBeginAmountType,
nsSelectionAmount aEndAmountType,
uint32_t aSelectFlags);
// Helper for GetContentAndOffsetsFromPoint; calculation of content offsets // Helper for GetContentAndOffsetsFromPoint; calculation of content offsets
// in this function assumes there is no child frame that can be targeted. // in this function assumes there is no child frame that can be targeted.