зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1109410 Resolve CSS transform in ContentEventHandler::ConvertToRootViewRelativeOffset() r=roc
This commit is contained in:
Родитель
f729d738ab
Коммит
f961371a5e
|
@ -203,13 +203,13 @@ ContentEventHandler::QueryContentRect(nsIContent* aContent,
|
|||
|
||||
// get rect for first frame
|
||||
nsRect resultRect(nsPoint(0, 0), frame->GetRect().Size());
|
||||
nsresult rv = ConvertToRootViewRelativeOffset(frame, resultRect);
|
||||
nsresult rv = ConvertToRootRelativeOffset(frame, resultRect);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// account for any additional frames
|
||||
while ((frame = frame->GetNextContinuation()) != nullptr) {
|
||||
nsRect frameRect(nsPoint(0, 0), frame->GetRect().Size());
|
||||
rv = ConvertToRootViewRelativeOffset(frame, frameRect);
|
||||
rv = ConvertToRootRelativeOffset(frame, frameRect);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
resultRect.UnionRect(resultRect, frameRect);
|
||||
}
|
||||
|
@ -1017,7 +1017,7 @@ ContentEventHandler::OnQueryTextRect(WidgetQueryContentEvent* aEvent)
|
|||
|
||||
// get the starting frame rect
|
||||
nsRect rect(nsPoint(0, 0), firstFrame->GetRect().Size());
|
||||
rv = ConvertToRootViewRelativeOffset(firstFrame, rect);
|
||||
rv = ConvertToRootRelativeOffset(firstFrame, rect);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsRect frameRect = rect;
|
||||
nsPoint ptOffset;
|
||||
|
@ -1059,7 +1059,7 @@ ContentEventHandler::OnQueryTextRect(WidgetQueryContentEvent* aEvent)
|
|||
}
|
||||
}
|
||||
frameRect.SetRect(nsPoint(0, 0), frame->GetRect().Size());
|
||||
rv = ConvertToRootViewRelativeOffset(frame, frameRect);
|
||||
rv = ConvertToRootRelativeOffset(frame, frameRect);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (frame != lastFrame) {
|
||||
// not last frame, so just add rect to previous result
|
||||
|
@ -1125,7 +1125,7 @@ ContentEventHandler::OnQueryCaretRect(WidgetQueryContentEvent* aEvent)
|
|||
lineBreakType);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (offset == aEvent->mInput.mOffset) {
|
||||
rv = ConvertToRootViewRelativeOffset(caretFrame, caretRect);
|
||||
rv = ConvertToRootRelativeOffset(caretFrame, caretRect);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nscoord appUnitsPerDevPixel =
|
||||
caretFrame->PresContext()->AppUnitsPerDevPixel();
|
||||
|
@ -1186,7 +1186,7 @@ ContentEventHandler::OnQueryCaretRect(WidgetQueryContentEvent* aEvent)
|
|||
rect.height = fontHeight;
|
||||
}
|
||||
|
||||
rv = ConvertToRootViewRelativeOffset(frame, rect);
|
||||
rv = ConvertToRootRelativeOffset(frame, rect);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aEvent->mReply.mRect = LayoutDevicePixel::FromUntyped(
|
||||
|
@ -1547,18 +1547,21 @@ ContentEventHandler::GetStartFrameAndOffset(const nsRange* aRange,
|
|||
}
|
||||
|
||||
nsresult
|
||||
ContentEventHandler::ConvertToRootViewRelativeOffset(nsIFrame* aFrame,
|
||||
nsRect& aRect)
|
||||
ContentEventHandler::ConvertToRootRelativeOffset(nsIFrame* aFrame,
|
||||
nsRect& aRect)
|
||||
{
|
||||
NS_ASSERTION(aFrame, "aFrame must not be null");
|
||||
|
||||
nsView* view = nullptr;
|
||||
nsPoint posInView;
|
||||
aFrame->GetOffsetFromView(posInView, &view);
|
||||
if (!view) {
|
||||
nsPresContext* rootPresContext = aFrame->PresContext()->GetRootPresContext();
|
||||
if (NS_WARN_IF(!rootPresContext)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
aRect += posInView + view->GetOffsetTo(nullptr);
|
||||
nsIFrame* rootFrame = rootPresContext->PresShell()->GetRootFrame();
|
||||
if (NS_WARN_IF(!rootFrame)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
aRect = nsLayoutUtils::TransformFrameRectToAncestor(aFrame, aRect, rootFrame);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -136,9 +136,10 @@ protected:
|
|||
nsresult GetStartFrameAndOffset(const nsRange* aRange,
|
||||
nsIFrame*& aFrame,
|
||||
int32_t& aOffsetInFrame);
|
||||
// Convert the frame relative offset to the root view relative offset.
|
||||
nsresult ConvertToRootViewRelativeOffset(nsIFrame* aFrame,
|
||||
nsRect& aRect);
|
||||
// Convert the frame relative offset to the root frame of the root presContext
|
||||
// relative offset.
|
||||
nsresult ConvertToRootRelativeOffset(nsIFrame* aFrame,
|
||||
nsRect& aRect);
|
||||
// Expand aXPOffset to the nearest offset in cluster boundary. aForward is
|
||||
// true, it is expanded to forward.
|
||||
nsresult ExpandToClusterBoundary(nsIContent* aContent, bool aForward,
|
||||
|
|
|
@ -582,7 +582,11 @@ public:
|
|||
// 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.
|
||||
// mRect is used by eQueryTextRect, eQueryCaretRect, eQueryCharacterAtPoint
|
||||
// and eQueryEditorRect. The coordinates is system coordinates relative to
|
||||
// the top level widget of mFocusedWidget. E.g., if a <xul:panel> which
|
||||
// is owned by a window has focused editor, the offset of mRect is relative
|
||||
// to the owner window, not the <xul:panel>.
|
||||
mozilla::LayoutDeviceIntRect mRect;
|
||||
// The return widget has the caret. This is set at all query events.
|
||||
nsIWidget* mFocusedWidget;
|
||||
|
|
|
@ -2309,6 +2309,86 @@ function runCharAtPointAtOutsideTest()
|
|||
}
|
||||
}
|
||||
|
||||
function runCSSTransformTest()
|
||||
{
|
||||
textarea.focus();
|
||||
textarea.value = "some text";
|
||||
textarea.selectionStart = textarea.selectionEnd = textarea.value.length;
|
||||
var editorRect = synthesizeQueryEditorRect();
|
||||
if (!checkQueryContentResult(editorRect,
|
||||
"runCSSTransformTest: editorRect")) {
|
||||
return;
|
||||
}
|
||||
var firstCharRect = synthesizeQueryTextRect(0, 1);
|
||||
if (!checkQueryContentResult(firstCharRect,
|
||||
"runCSSTransformTest: firstCharRect")) {
|
||||
return;
|
||||
}
|
||||
var lastCharRect = synthesizeQueryTextRect(textarea.value.length - 1, textarea.value.length);
|
||||
if (!checkQueryContentResult(lastCharRect,
|
||||
"runCSSTransformTest: lastCharRect")) {
|
||||
return;
|
||||
}
|
||||
var caretRect = synthesizeQueryCaretRect(textarea.selectionStart);
|
||||
if (!checkQueryContentResult(caretRect,
|
||||
"runCSSTransformTest: caretRect")) {
|
||||
return;
|
||||
}
|
||||
var caretRectBeforeFirstChar = synthesizeQueryCaretRect(0);
|
||||
if (!checkQueryContentResult(caretRectBeforeFirstChar,
|
||||
"runCSSTransformTest: caretRectBeforeFirstChar")) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
textarea.style.transform = "translate(10px, 15px)";
|
||||
function movedRect(aRect, aX, aY)
|
||||
{
|
||||
return { left: aRect.left + aX, top: aRect.top + aY, width: aRect.width, height: aRect.height }
|
||||
}
|
||||
|
||||
var editorRectTranslated = synthesizeQueryEditorRect();
|
||||
if (!checkQueryContentResult(editorRectTranslated,
|
||||
"runCSSTransformTest: editorRectTranslated") ||
|
||||
!checkRect(editorRectTranslated, movedRect(editorRect, 10, 15),
|
||||
"runCSSTransformTest: editorRectTranslated")) {
|
||||
return;
|
||||
}
|
||||
var firstCharRectTranslated = synthesizeQueryTextRect(0, 1);
|
||||
if (!checkQueryContentResult(firstCharRectTranslated,
|
||||
"runCSSTransformTest: firstCharRectTranslated") ||
|
||||
!checkRect(firstCharRectTranslated, movedRect(firstCharRect, 10, 15),
|
||||
"runCSSTransformTest: firstCharRectTranslated")) {
|
||||
return;
|
||||
}
|
||||
var lastCharRectTranslated = synthesizeQueryTextRect(textarea.value.length - 1, textarea.value.length);
|
||||
if (!checkQueryContentResult(lastCharRectTranslated,
|
||||
"runCSSTransformTest: lastCharRectTranslated") ||
|
||||
!checkRect(lastCharRectTranslated, movedRect(lastCharRect, 10, 15),
|
||||
"runCSSTransformTest: lastCharRectTranslated")) {
|
||||
return;
|
||||
}
|
||||
var caretRectTranslated = synthesizeQueryCaretRect(textarea.selectionStart);
|
||||
if (!checkQueryContentResult(caretRectTranslated,
|
||||
"runCSSTransformTest: caretRectTranslated") ||
|
||||
!checkRect(caretRectTranslated, movedRect(caretRect, 10, 15),
|
||||
"runCSSTransformTest: caretRectTranslated")) {
|
||||
return;
|
||||
}
|
||||
var caretRectBeforeFirstCharTranslated = synthesizeQueryCaretRect(0);
|
||||
if (!checkQueryContentResult(caretRectBeforeFirstCharTranslated,
|
||||
"runCSSTransformTest: caretRectBeforeFirstCharTranslated") ||
|
||||
!checkRect(caretRectBeforeFirstCharTranslated, movedRect(caretRectBeforeFirstChar, 10, 15),
|
||||
"runCSSTransformTest: caretRectBeforeFirstCharTranslated")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// XXX It's too difficult to check the result with scale and rotate...
|
||||
} finally {
|
||||
textarea.style.transform = "";
|
||||
}
|
||||
}
|
||||
|
||||
function runBug722639Test()
|
||||
{
|
||||
textarea.focus();
|
||||
|
@ -4522,6 +4602,7 @@ function runTest()
|
|||
runCompositionEventTest();
|
||||
runCharAtPointTest(textarea, "textarea in the document");
|
||||
runCharAtPointAtOutsideTest();
|
||||
runCSSTransformTest();
|
||||
runBug722639Test();
|
||||
runForceCommitTest();
|
||||
runNestedSettingValue();
|
||||
|
|
Загрузка…
Ссылка в новой задаче