1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "nsQueryContentEventResult.h"
11 #include "mozilla/TextEvents.h"
12 #include "nsIWidget.h"
15 using namespace mozilla
;
17 /******************************************************************************
18 * Is*PropertyAvailable() methods which check if the property is available
19 * (valid) with the event message.
20 ******************************************************************************/
22 static bool IsNotFoundPropertyAvailable(EventMessage aEventMessage
) {
23 return aEventMessage
== eQuerySelectedText
||
24 aEventMessage
== eQueryCharacterAtPoint
;
27 static bool IsOffsetPropertyAvailable(EventMessage aEventMessage
) {
28 return aEventMessage
== eQueryTextContent
||
29 aEventMessage
== eQueryTextRect
|| aEventMessage
== eQueryCaretRect
||
30 IsNotFoundPropertyAvailable(aEventMessage
);
33 static bool IsRectRelatedPropertyAvailable(EventMessage aEventMessage
) {
34 return aEventMessage
== eQueryCaretRect
|| aEventMessage
== eQueryTextRect
||
35 aEventMessage
== eQueryEditorRect
||
36 aEventMessage
== eQueryCharacterAtPoint
;
39 /******************************************************************************
40 * nsQueryContentEventResult
41 ******************************************************************************/
43 NS_INTERFACE_MAP_BEGIN(nsQueryContentEventResult
)
44 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsIQueryContentEventResult
)
45 NS_INTERFACE_MAP_ENTRY(nsIQueryContentEventResult
)
48 NS_IMPL_ADDREF(nsQueryContentEventResult
)
49 NS_IMPL_RELEASE(nsQueryContentEventResult
)
51 nsQueryContentEventResult::nsQueryContentEventResult(
52 mozilla::WidgetQueryContentEvent
&& aEvent
)
53 : mEventMessage(aEvent
.mMessage
),
54 mSucceeded(aEvent
.Succeeded()),
57 mOffsetAndData
= std::move(aEvent
.mReply
->mOffsetAndData
);
58 mTentativeCaretOffset
= std::move(aEvent
.mReply
->mTentativeCaretOffset
);
59 mRect
= std::move(aEvent
.mReply
->mRect
);
60 mRectArray
= std::move(aEvent
.mReply
->mRectArray
);
61 mReversed
= aEvent
.mReply
->mReversed
;
63 // Mark as result that is longer used.
64 aEvent
.mReply
.reset();
68 nsQueryContentEventResult::GetOffset(uint32_t* aOffset
) {
69 if (NS_WARN_IF(!mSucceeded
)) {
70 return NS_ERROR_NOT_AVAILABLE
;
73 if (NS_WARN_IF(!IsOffsetPropertyAvailable(mEventMessage
))) {
74 return NS_ERROR_NOT_AVAILABLE
;
77 // With some event message, both offset and notFound properties are available.
78 // In that case, offset value may mean "not found". If so, this method
79 // shouldn't return mOffset as the result because it's a special value for
81 if (IsNotFoundPropertyAvailable(mEventMessage
)) {
83 nsresult rv
= GetNotFound(¬Found
);
84 if (NS_WARN_IF(NS_FAILED(rv
))) {
85 return rv
; // Just an unexpected case...
87 // As said above, if mOffset means "not found", offset property shouldn't
88 // return its value without any errors.
89 if (NS_WARN_IF(notFound
)) {
90 return NS_ERROR_NOT_AVAILABLE
;
94 *aOffset
= mOffsetAndData
->StartOffset();
99 nsQueryContentEventResult::GetTentativeCaretOffset(uint32_t* aOffset
) {
101 nsresult rv
= GetTentativeCaretOffsetNotFound(¬Found
);
102 if (NS_WARN_IF(NS_FAILED(rv
))) {
105 if (NS_WARN_IF(notFound
)) {
106 return NS_ERROR_NOT_AVAILABLE
;
108 *aOffset
= mTentativeCaretOffset
.value();
113 nsQueryContentEventResult::GetReversed(bool* aReversed
) {
114 NS_ENSURE_TRUE(mSucceeded
, NS_ERROR_NOT_AVAILABLE
);
115 NS_ENSURE_TRUE(mEventMessage
== eQuerySelectedText
, NS_ERROR_NOT_AVAILABLE
);
116 *aReversed
= mReversed
;
121 nsQueryContentEventResult::GetLeft(int32_t* aLeft
) {
122 NS_ENSURE_TRUE(mSucceeded
, NS_ERROR_NOT_AVAILABLE
);
123 NS_ENSURE_TRUE(IsRectRelatedPropertyAvailable(mEventMessage
),
124 NS_ERROR_NOT_AVAILABLE
);
130 nsQueryContentEventResult::GetWidth(int32_t* aWidth
) {
131 NS_ENSURE_TRUE(mSucceeded
, NS_ERROR_NOT_AVAILABLE
);
132 NS_ENSURE_TRUE(IsRectRelatedPropertyAvailable(mEventMessage
),
133 NS_ERROR_NOT_AVAILABLE
);
134 *aWidth
= mRect
.Width();
139 nsQueryContentEventResult::GetTop(int32_t* aTop
) {
140 NS_ENSURE_TRUE(mSucceeded
, NS_ERROR_NOT_AVAILABLE
);
141 NS_ENSURE_TRUE(IsRectRelatedPropertyAvailable(mEventMessage
),
142 NS_ERROR_NOT_AVAILABLE
);
148 nsQueryContentEventResult::GetHeight(int32_t* aHeight
) {
149 NS_ENSURE_TRUE(mSucceeded
, NS_ERROR_NOT_AVAILABLE
);
150 NS_ENSURE_TRUE(IsRectRelatedPropertyAvailable(mEventMessage
),
151 NS_ERROR_NOT_AVAILABLE
);
152 *aHeight
= mRect
.Height();
157 nsQueryContentEventResult::GetText(nsAString
& aText
) {
158 NS_ENSURE_TRUE(mSucceeded
, NS_ERROR_NOT_AVAILABLE
);
159 NS_ENSURE_TRUE(mEventMessage
== eQuerySelectedText
||
160 mEventMessage
== eQueryTextContent
||
161 mEventMessage
== eQueryTextRect
,
162 NS_ERROR_NOT_AVAILABLE
);
163 NS_ENSURE_TRUE(mOffsetAndData
.isSome(), NS_ERROR_NOT_AVAILABLE
);
164 aText
= mOffsetAndData
->DataRef();
169 nsQueryContentEventResult::GetSucceeded(bool* aSucceeded
) {
170 NS_ENSURE_TRUE(mEventMessage
!= eVoidEvent
, NS_ERROR_NOT_INITIALIZED
);
171 *aSucceeded
= mSucceeded
;
176 nsQueryContentEventResult::GetNotFound(bool* aNotFound
) {
177 if (NS_WARN_IF(!mSucceeded
) ||
178 NS_WARN_IF(!IsNotFoundPropertyAvailable(mEventMessage
))) {
179 return NS_ERROR_NOT_AVAILABLE
;
181 *aNotFound
= mOffsetAndData
.isNothing();
186 nsQueryContentEventResult::GetTentativeCaretOffsetNotFound(bool* aNotFound
) {
187 if (NS_WARN_IF(!mSucceeded
)) {
188 return NS_ERROR_NOT_AVAILABLE
;
190 if (NS_WARN_IF(mEventMessage
!= eQueryCharacterAtPoint
)) {
191 return NS_ERROR_NOT_AVAILABLE
;
193 *aNotFound
= mTentativeCaretOffset
.isNothing();
198 nsQueryContentEventResult::GetCharacterRect(int32_t aOffset
, int32_t* aLeft
,
199 int32_t* aTop
, int32_t* aWidth
,
201 NS_ENSURE_TRUE(mSucceeded
, NS_ERROR_NOT_AVAILABLE
);
202 NS_ENSURE_TRUE(mEventMessage
== eQueryTextRectArray
, NS_ERROR_NOT_AVAILABLE
);
204 if (NS_WARN_IF(mRectArray
.Length() <= static_cast<size_t>(aOffset
))) {
205 return NS_ERROR_FAILURE
;
208 *aLeft
= mRectArray
[aOffset
].x
;
209 *aTop
= mRectArray
[aOffset
].y
;
210 *aWidth
= mRectArray
[aOffset
].Width();
211 *aHeight
= mRectArray
[aOffset
].Height();
216 void nsQueryContentEventResult::SetEventResult(nsIWidget
* aWidget
) {
217 if (!IsRectRelatedPropertyAvailable(mEventMessage
) || !aWidget
||
222 nsIWidget
* topWidget
= aWidget
->GetTopLevelWidget();
223 if (!topWidget
|| topWidget
== aWidget
) {
227 // Convert the top widget related coordinates to the given widget's.
228 LayoutDeviceIntPoint offset
=
229 aWidget
->WidgetToScreenOffset() - topWidget
->WidgetToScreenOffset();
230 mRect
.MoveBy(-offset
);
231 for (size_t i
= 0; i
< mRectArray
.Length(); i
++) {
232 mRectArray
[i
].MoveBy(-offset
);