tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsQueryContentEventResult.cpp (7627B)


      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/. */
      6 
      7 #include "nsQueryContentEventResult.h"
      8 
      9 #include <utility>
     10 
     11 #include "mozilla/TextEvents.h"
     12 #include "nsIWidget.h"
     13 #include "nsPoint.h"
     14 
     15 using namespace mozilla;
     16 
     17 /******************************************************************************
     18 * Is*PropertyAvailable() methods which check if the property is available
     19 * (valid) with the event message.
     20 ******************************************************************************/
     21 
     22 static bool IsNotFoundPropertyAvailable(EventMessage aEventMessage) {
     23  return aEventMessage == eQuerySelectedText ||
     24         aEventMessage == eQueryCharacterAtPoint;
     25 }
     26 
     27 static bool IsOffsetPropertyAvailable(EventMessage aEventMessage) {
     28  return aEventMessage == eQueryTextContent ||
     29         aEventMessage == eQueryTextRect || aEventMessage == eQueryCaretRect ||
     30         IsNotFoundPropertyAvailable(aEventMessage);
     31 }
     32 
     33 static bool IsRectRelatedPropertyAvailable(EventMessage aEventMessage) {
     34  return aEventMessage == eQueryCaretRect || aEventMessage == eQueryTextRect ||
     35         aEventMessage == eQueryEditorRect ||
     36         aEventMessage == eQueryCharacterAtPoint;
     37 }
     38 
     39 /******************************************************************************
     40 * nsQueryContentEventResult
     41 ******************************************************************************/
     42 
     43 NS_INTERFACE_MAP_BEGIN(nsQueryContentEventResult)
     44  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIQueryContentEventResult)
     45  NS_INTERFACE_MAP_ENTRY(nsIQueryContentEventResult)
     46 NS_INTERFACE_MAP_END
     47 
     48 NS_IMPL_ADDREF(nsQueryContentEventResult)
     49 NS_IMPL_RELEASE(nsQueryContentEventResult)
     50 
     51 nsQueryContentEventResult::nsQueryContentEventResult(
     52    mozilla::WidgetQueryContentEvent&& aEvent)
     53    : mEventMessage(aEvent.mMessage),
     54      mSucceeded(aEvent.Succeeded()),
     55      mReversed(false) {
     56  if (mSucceeded) {
     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;
     62  }
     63  // Mark as result that is longer used.
     64  aEvent.mReply.reset();
     65 }
     66 
     67 NS_IMETHODIMP
     68 nsQueryContentEventResult::GetOffset(uint32_t* aOffset) {
     69  if (NS_WARN_IF(!mSucceeded)) {
     70    return NS_ERROR_NOT_AVAILABLE;
     71  }
     72 
     73  if (NS_WARN_IF(!IsOffsetPropertyAvailable(mEventMessage))) {
     74    return NS_ERROR_NOT_AVAILABLE;
     75  }
     76 
     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
     80  // "not found".
     81  if (IsNotFoundPropertyAvailable(mEventMessage)) {
     82    bool notFound;
     83    nsresult rv = GetNotFound(&notFound);
     84    if (NS_WARN_IF(NS_FAILED(rv))) {
     85      return rv;  // Just an unexpected case...
     86    }
     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;
     91    }
     92  }
     93 
     94  *aOffset = mOffsetAndData->StartOffset();
     95  return NS_OK;
     96 }
     97 
     98 NS_IMETHODIMP
     99 nsQueryContentEventResult::GetTentativeCaretOffset(uint32_t* aOffset) {
    100  bool notFound;
    101  nsresult rv = GetTentativeCaretOffsetNotFound(&notFound);
    102  if (NS_WARN_IF(NS_FAILED(rv))) {
    103    return rv;
    104  }
    105  if (NS_WARN_IF(notFound)) {
    106    return NS_ERROR_NOT_AVAILABLE;
    107  }
    108  *aOffset = mTentativeCaretOffset.value();
    109  return NS_OK;
    110 }
    111 
    112 NS_IMETHODIMP
    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;
    117  return NS_OK;
    118 }
    119 
    120 NS_IMETHODIMP
    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);
    125  *aLeft = mRect.x;
    126  return NS_OK;
    127 }
    128 
    129 NS_IMETHODIMP
    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();
    135  return NS_OK;
    136 }
    137 
    138 NS_IMETHODIMP
    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);
    143  *aTop = mRect.y;
    144  return NS_OK;
    145 }
    146 
    147 NS_IMETHODIMP
    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();
    153  return NS_OK;
    154 }
    155 
    156 NS_IMETHODIMP
    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();
    165  return NS_OK;
    166 }
    167 
    168 NS_IMETHODIMP
    169 nsQueryContentEventResult::GetSucceeded(bool* aSucceeded) {
    170  NS_ENSURE_TRUE(mEventMessage != eVoidEvent, NS_ERROR_NOT_INITIALIZED);
    171  *aSucceeded = mSucceeded;
    172  return NS_OK;
    173 }
    174 
    175 NS_IMETHODIMP
    176 nsQueryContentEventResult::GetNotFound(bool* aNotFound) {
    177  if (NS_WARN_IF(!mSucceeded) ||
    178      NS_WARN_IF(!IsNotFoundPropertyAvailable(mEventMessage))) {
    179    return NS_ERROR_NOT_AVAILABLE;
    180  }
    181  *aNotFound = mOffsetAndData.isNothing();
    182  return NS_OK;
    183 }
    184 
    185 NS_IMETHODIMP
    186 nsQueryContentEventResult::GetTentativeCaretOffsetNotFound(bool* aNotFound) {
    187  if (NS_WARN_IF(!mSucceeded)) {
    188    return NS_ERROR_NOT_AVAILABLE;
    189  }
    190  if (NS_WARN_IF(mEventMessage != eQueryCharacterAtPoint)) {
    191    return NS_ERROR_NOT_AVAILABLE;
    192  }
    193  *aNotFound = mTentativeCaretOffset.isNothing();
    194  return NS_OK;
    195 }
    196 
    197 NS_IMETHODIMP
    198 nsQueryContentEventResult::GetCharacterRect(int32_t aOffset, int32_t* aLeft,
    199                                            int32_t* aTop, int32_t* aWidth,
    200                                            int32_t* aHeight) {
    201  NS_ENSURE_TRUE(mSucceeded, NS_ERROR_NOT_AVAILABLE);
    202  NS_ENSURE_TRUE(mEventMessage == eQueryTextRectArray, NS_ERROR_NOT_AVAILABLE);
    203 
    204  if (NS_WARN_IF(mRectArray.Length() <= static_cast<size_t>(aOffset))) {
    205    return NS_ERROR_FAILURE;
    206  }
    207 
    208  *aLeft = mRectArray[aOffset].x;
    209  *aTop = mRectArray[aOffset].y;
    210  *aWidth = mRectArray[aOffset].Width();
    211  *aHeight = mRectArray[aOffset].Height();
    212 
    213  return NS_OK;
    214 }
    215 
    216 void nsQueryContentEventResult::SetEventResult(nsIWidget* aWidget) {
    217  if (!IsRectRelatedPropertyAvailable(mEventMessage) || !aWidget ||
    218      !mSucceeded) {
    219    return;
    220  }
    221 
    222  nsIWidget* topWidget = aWidget->GetTopLevelWidget();
    223  if (!topWidget || topWidget == aWidget) {
    224    return;
    225  }
    226 
    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);
    233  }
    234 }