зеркало из https://github.com/mozilla/gecko-dev.git
Bug 492394 part.1 NS_QUERY_CHARACTER_AT_POINT should also return tentative caret offset for the point r=smaug, sr=smaug
This commit is contained in:
Родитель
14e96990fc
Коммит
8c1890067d
|
@ -38,6 +38,21 @@ nsQueryContentEventResult::GetOffset(uint32_t *aOffset)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsQueryContentEventResult::GetTentativeCaretOffset(uint32_t* aOffset)
|
||||
{
|
||||
bool notFound;
|
||||
nsresult rv = GetTentativeCaretOffsetNotFound(¬Found);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
if (NS_WARN_IF(notFound)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
*aOffset = mTentativeCaretOffset;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static bool IsRectEnabled(uint32_t aEventID)
|
||||
{
|
||||
return aEventID == NS_QUERY_CARET_RECT ||
|
||||
|
@ -126,6 +141,19 @@ nsQueryContentEventResult::GetNotFound(bool *aNotFound)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsQueryContentEventResult::GetTentativeCaretOffsetNotFound(bool* aNotFound)
|
||||
{
|
||||
if (NS_WARN_IF(!mSucceeded)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
if (NS_WARN_IF(mEventID != NS_QUERY_CHARACTER_AT_POINT)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
*aNotFound = (mTentativeCaretOffset == WidgetQueryContentEvent::NOT_FOUND);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsQueryContentEventResult::SetEventResult(nsIWidget* aWidget,
|
||||
const WidgetQueryContentEvent &aEvent)
|
||||
|
@ -135,6 +163,7 @@ nsQueryContentEventResult::SetEventResult(nsIWidget* aWidget,
|
|||
mReversed = aEvent.mReply.mReversed;
|
||||
mRect = aEvent.mReply.mRect;
|
||||
mOffset = aEvent.mReply.mOffset;
|
||||
mTentativeCaretOffset = aEvent.mReply.mTentativeCaretOffset;
|
||||
mString = aEvent.mReply.mString;
|
||||
|
||||
if (!IsRectEnabled(mEventID) || !aWidget || !mSucceeded) {
|
||||
|
|
|
@ -30,6 +30,7 @@ protected:
|
|||
uint32_t mEventID;
|
||||
|
||||
uint32_t mOffset;
|
||||
uint32_t mTentativeCaretOffset;
|
||||
nsString mString;
|
||||
mozilla::LayoutDeviceIntRect mRect;
|
||||
|
||||
|
|
|
@ -1135,6 +1135,9 @@ ContentEventHandler::OnQueryCharacterAtPoint(WidgetQueryContentEvent* aEvent)
|
|||
return rv;
|
||||
}
|
||||
|
||||
aEvent->mReply.mOffset = aEvent->mReply.mTentativeCaretOffset =
|
||||
WidgetQueryContentEvent::NOT_FOUND;
|
||||
|
||||
nsIFrame* rootFrame = mPresShell->GetRootFrame();
|
||||
NS_ENSURE_TRUE(rootFrame, NS_ERROR_FAILURE);
|
||||
nsIWidget* rootWidget = rootFrame->GetNearestWidget();
|
||||
|
@ -1164,12 +1167,10 @@ ContentEventHandler::OnQueryCharacterAtPoint(WidgetQueryContentEvent* aEvent)
|
|||
nsLayoutUtils::GetEventCoordinatesRelativeTo(&eventOnRoot, rootFrame);
|
||||
|
||||
nsIFrame* targetFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, ptInRoot);
|
||||
if (!targetFrame || targetFrame->GetType() != nsGkAtoms::textFrame ||
|
||||
!targetFrame->GetContent() ||
|
||||
if (!targetFrame || !targetFrame->GetContent() ||
|
||||
!nsContentUtils::ContentIsDescendantOf(targetFrame->GetContent(),
|
||||
mRootContent)) {
|
||||
// there is no character at the point.
|
||||
aEvent->mReply.mOffset = WidgetQueryContentEvent::NOT_FOUND;
|
||||
// There is no character at the point.
|
||||
aEvent->mSucceeded = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1178,6 +1179,35 @@ ContentEventHandler::OnQueryCharacterAtPoint(WidgetQueryContentEvent* aEvent)
|
|||
int32_t targetAPD = targetFrame->PresContext()->AppUnitsPerDevPixel();
|
||||
ptInTarget = ptInTarget.ScaleToOtherAppUnits(rootAPD, targetAPD);
|
||||
|
||||
nsIFrame::ContentOffsets tentativeCaretOffsets =
|
||||
targetFrame->GetContentOffsetsFromPoint(ptInTarget);
|
||||
if (!tentativeCaretOffsets.content ||
|
||||
!nsContentUtils::ContentIsDescendantOf(tentativeCaretOffsets.content,
|
||||
mRootContent)) {
|
||||
// There is no character nor tentative caret point at the point.
|
||||
aEvent->mSucceeded = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
rv = GetFlatTextOffsetOfRange(mRootContent, tentativeCaretOffsets.content,
|
||||
tentativeCaretOffsets.offset,
|
||||
&aEvent->mReply.mTentativeCaretOffset,
|
||||
GetLineBreakType(aEvent));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (targetFrame->GetType() != nsGkAtoms::textFrame) {
|
||||
// There is no character at the point but there is tentative caret point.
|
||||
aEvent->mSucceeded = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(
|
||||
aEvent->mReply.mTentativeCaretOffset != WidgetQueryContentEvent::NOT_FOUND,
|
||||
"The point is inside a character bounding box. Why tentative caret point "
|
||||
"hasn't been found?");
|
||||
|
||||
nsTextFrame* textframe = static_cast<nsTextFrame*>(targetFrame);
|
||||
nsIFrame::ContentOffsets contentOffsets =
|
||||
textframe->GetCharacterOffsetAtFramePoint(ptInTarget);
|
||||
|
|
|
@ -11,10 +11,11 @@
|
|||
* See nsIDOMWindowUtils.idl, which properites can be used was documented.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(4b4ba266-b51e-4f0f-8d0e-9f13cb2a0056)]
|
||||
[scriptable, uuid(e2c39e0e-345f-451a-a7b2-e0230d555847)]
|
||||
interface nsIQueryContentEventResult : nsISupports
|
||||
{
|
||||
readonly attribute unsigned long offset;
|
||||
readonly attribute unsigned long tentativeCaretOffset;
|
||||
readonly attribute boolean reversed;
|
||||
|
||||
readonly attribute long left;
|
||||
|
@ -25,4 +26,5 @@ interface nsIQueryContentEventResult : nsISupports
|
|||
|
||||
readonly attribute boolean succeeded;
|
||||
readonly attribute boolean notFound;
|
||||
readonly attribute boolean tentativeCaretOffsetNotFound;
|
||||
};
|
||||
|
|
|
@ -258,8 +258,9 @@
|
|||
#define NS_QUERY_CONTENT_STATE (NS_QUERY_CONTENT_EVENT_START + 6)
|
||||
// Query for the selection in the form of a nsITransferable.
|
||||
#define NS_QUERY_SELECTION_AS_TRANSFERABLE (NS_QUERY_CONTENT_EVENT_START + 7)
|
||||
// Query for character at a point. This returns the character offset and its
|
||||
// rect. The point is specified by Event::refPoint.
|
||||
// Query for character at a point. This returns the character offset, its
|
||||
// rect and also tentative caret point if the point is clicked. The point is
|
||||
// specified by Event::refPoint.
|
||||
#define NS_QUERY_CHARACTER_AT_POINT (NS_QUERY_CONTENT_EVENT_START + 8)
|
||||
// Query if the DOM element under Event::refPoint belongs to our widget
|
||||
// or not.
|
||||
|
|
|
@ -554,6 +554,9 @@ public:
|
|||
{
|
||||
void* mContentsRoot;
|
||||
uint32_t mOffset;
|
||||
// mTentativeCaretOffset is used by only NS_QUERY_CHARACTER_AT_POINT.
|
||||
// This is the offset where caret would be if user clicked at the refPoint.
|
||||
uint32_t mTentativeCaretOffset;
|
||||
nsString mString;
|
||||
// Finally, the coordinates is system coordinates.
|
||||
mozilla::LayoutDeviceIntRect mRect;
|
||||
|
|
|
@ -587,6 +587,7 @@ struct ParamTraits<mozilla::WidgetQueryContentEvent>
|
|||
WriteParam(aMsg, aParam.mInput.mOffset);
|
||||
WriteParam(aMsg, aParam.mInput.mLength);
|
||||
WriteParam(aMsg, aParam.mReply.mOffset);
|
||||
WriteParam(aMsg, aParam.mReply.mTentativeCaretOffset);
|
||||
WriteParam(aMsg, aParam.mReply.mString);
|
||||
WriteParam(aMsg, aParam.mReply.mRect);
|
||||
WriteParam(aMsg, aParam.mReply.mReversed);
|
||||
|
@ -606,6 +607,7 @@ struct ParamTraits<mozilla::WidgetQueryContentEvent>
|
|||
ReadParam(aMsg, aIter, &aResult->mInput.mOffset) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mInput.mLength) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mReply.mOffset) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mReply.mTentativeCaretOffset) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mReply.mString) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mReply.mRect) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mReply.mReversed) &&
|
||||
|
|
|
@ -19,13 +19,13 @@
|
|||
onpopuphidden="onPanelHidden(event);">
|
||||
<vbox id="vbox">
|
||||
<textbox id="textbox" onfocus="onFocusPanelTextbox(event);"
|
||||
multiline="true" cols="20" rows="4"/>
|
||||
multiline="true" cols="20" rows="4" style="font-size: 36px;"/>
|
||||
</vbox>
|
||||
</panel>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display">
|
||||
<div id="div" style="margin: 0; padding: 0; font-size: 24px;">Here is a text frame.</div>
|
||||
<div id="div" style="margin: 0; padding: 0; font-size: 36px;">Here is a text frame.</div>
|
||||
<textarea style="margin: 0;" id="textarea" cols="20" rows="4"></textarea><br/>
|
||||
<iframe id="iframe" width="300" height="150"
|
||||
src="data:text/html,<textarea id='textarea' cols='20' rows='4'></textarea>"></iframe><br/>
|
||||
|
@ -2169,9 +2169,11 @@ function runCharAtPointTest(aFocusedEditor, aTargetName)
|
|||
aFocusedEditor.focus();
|
||||
|
||||
const kNone = -1;
|
||||
const kTestingOffset = [ 0, 10, 20, 21 + kLFLen, 34 + kLFLen];
|
||||
const kLeftSideOffset = [ kNone, 9, 19, kNone, 33 + kLFLen];
|
||||
const kRightSideOffset = [ 1, 11, kNone, 22 + kLFLen, kNone];
|
||||
const kTestingOffset = [ 0, 10, 20, 21 + kLFLen, 34 + kLFLen];
|
||||
const kLeftSideOffset = [ kNone, 9, 19, kNone, 33 + kLFLen];
|
||||
const kRightSideOffset = [ 1, 11, kNone, 22 + kLFLen, kNone];
|
||||
const kLeftTentativeCaretOffset = [ 0, 10, 20, 21 + kLFLen, 34 + kLFLen];
|
||||
const kRightTentativeCaretOffset = [ 1, 11, 21, 22 + kLFLen, 35 + kLFLen];
|
||||
|
||||
var editorRect = synthesizeQueryEditorRect();
|
||||
if (!checkQueryContentResult(editorRect,
|
||||
|
@ -2203,6 +2205,12 @@ function runCharAtPointTest(aFocusedEditor, aTargetName)
|
|||
checkRect(charAtPt1, textRect, "runCharAtPointTest (" + aTargetName +
|
||||
"): charAtPt1 left is wrong: i=" + i);
|
||||
}
|
||||
ok(!charAtPt1.tentativeCaretOffsetNotFound,
|
||||
"runCharAtPointTest (" + aTargetName + "): tentative caret offset for charAtPt1 isn't found: i=" + i);
|
||||
if (!charAtPt1.tentativeCaretOffsetNotFound) {
|
||||
is(charAtPt1.tentativeCaretOffset, kLeftTentativeCaretOffset[i],
|
||||
"runCharAtPointTest (" + aTargetName + "): tentative caret offset for charAtPt1 is wrong: i=" + i);
|
||||
}
|
||||
}
|
||||
|
||||
// Test #2, getting same character rect by the point near the bottom-right.
|
||||
|
@ -2218,6 +2226,12 @@ function runCharAtPointTest(aFocusedEditor, aTargetName)
|
|||
checkRect(charAtPt2, textRect, "runCharAtPointTest (" + aTargetName +
|
||||
"): charAtPt1 left is wrong: i=" + i);
|
||||
}
|
||||
ok(!charAtPt2.tentativeCaretOffsetNotFound,
|
||||
"runCharAtPointTest (" + aTargetName + "): tentative caret offset for charAtPt2 isn't found: i=" + i);
|
||||
if (!charAtPt2.tentativeCaretOffsetNotFound) {
|
||||
is(charAtPt2.tentativeCaretOffset, kRightTentativeCaretOffset[i],
|
||||
"runCharAtPointTest (" + aTargetName + "): tentative caret offset for charAtPt2 is wrong: i=" + i);
|
||||
}
|
||||
}
|
||||
|
||||
// Test #3, getting left character offset.
|
||||
|
@ -2233,6 +2247,18 @@ function runCharAtPointTest(aFocusedEditor, aTargetName)
|
|||
is(charAtPt3.offset, kLeftSideOffset[i],
|
||||
"runCharAtPointTest (" + aTargetName + "): charAtPt3 offset is wrong: i=" + i);
|
||||
}
|
||||
if (kLeftSideOffset[i] == kNone) {
|
||||
// There may be no enough padding-left (depends on platform)
|
||||
todo(false,
|
||||
"runCharAtPointTest (" + aTargetName + "): tentative caret offset for charAtPt3 isn't tested: i=" + i);
|
||||
} else {
|
||||
ok(!charAtPt3.tentativeCaretOffsetNotFound,
|
||||
"runCharAtPointTest (" + aTargetName + "): tentative caret offset for charAtPt3 isn't found: i=" + i);
|
||||
if (!charAtPt3.tentativeCaretOffsetNotFound) {
|
||||
is(charAtPt3.tentativeCaretOffset, kLeftTentativeCaretOffset[i],
|
||||
"runCharAtPointTest (" + aTargetName + "): tentative caret offset for charAtPt3 is wrong: i=" + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test #4, getting right character offset.
|
||||
|
@ -2248,6 +2274,12 @@ function runCharAtPointTest(aFocusedEditor, aTargetName)
|
|||
is(charAtPt4.offset, kRightSideOffset[i],
|
||||
"runCharAtPointTest (" + aTargetName + "): charAtPt4 offset is wrong: i=" + i);
|
||||
}
|
||||
ok(!charAtPt4.tentativeCaretOffsetNotFound,
|
||||
"runCharAtPointTest (" + aTargetName + "): tentative caret offset for charAtPt4 isn't found: i=" + i);
|
||||
if (!charAtPt4.tentativeCaretOffsetNotFound) {
|
||||
is(charAtPt4.tentativeCaretOffset, kRightTentativeCaretOffset[i],
|
||||
"runCharAtPointTest (" + aTargetName + "): tentative caret offset for charAtPt4 is wrong: i=" + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2268,6 +2300,8 @@ function runCharAtPointAtOutsideTest()
|
|||
"runCharAtPointAtOutsideTest: charAtPt")) {
|
||||
ok(charAtPt.notFound,
|
||||
"runCharAtPointAtOutsideTest: charAtPt is found on outside of editor");
|
||||
ok(charAtPt.tentativeCaretOffsetNotFound,
|
||||
"runCharAtPointAtOutsideTest: tentative caret offset for charAtPt is found on outside of editor");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче