tor-browser

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

PointerEvent.cpp (19179B)


      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 * Portions Copyright 2013 Microsoft Open Technologies, Inc. */
      8 
      9 #include "PointerEvent.h"
     10 
     11 #include "jsfriendapi.h"
     12 #include "mozilla/MouseEvents.h"
     13 #include "mozilla/StaticPrefs_dom.h"
     14 #include "mozilla/dom/MouseEventBinding.h"
     15 #include "mozilla/dom/PointerEventBinding.h"
     16 #include "mozilla/dom/PointerEventHandler.h"
     17 #include "nsContentUtils.h"
     18 #include "prtime.h"
     19 
     20 namespace mozilla::dom {
     21 
     22 PointerEvent::PointerEvent(EventTarget* aOwner, nsPresContext* aPresContext,
     23                           WidgetPointerEvent* aEvent)
     24    : MouseEvent(aOwner, aPresContext,
     25                 aEvent ? aEvent
     26                        : new WidgetPointerEvent(false, eVoidEvent, nullptr)) {
     27  NS_ASSERTION(mEvent->mClass == ePointerEventClass,
     28               "event type mismatch ePointerEventClass");
     29 
     30  WidgetMouseEvent* mouseEvent = mEvent->AsMouseEvent();
     31  if (aEvent) {
     32    mEventIsInternal = false;
     33    mTiltX.emplace(aEvent->tiltX);
     34    mTiltY.emplace(aEvent->tiltY);
     35    // mAltitudeAngle and mAzimuthAngle should be computed when they are
     36    // requested by JS.
     37  } else {
     38    mEventIsInternal = true;
     39    mEvent->mRefPoint = LayoutDeviceIntPoint(0, 0);
     40    mouseEvent->mInputSource = MouseEvent_Binding::MOZ_SOURCE_UNKNOWN;
     41  }
     42  // 5.2 Pointer Event types, for all pointer events, |detail| attribute SHOULD
     43  // be 0.  However, UI Events defines that it should be click count if the
     44  // event type is "click".
     45  mDetail =
     46      IsPointerEventMessageOriginallyMouseEventMessage(mouseEvent->mMessage)
     47          ? mouseEvent->mClickCount
     48          : 0;
     49 }
     50 
     51 JSObject* PointerEvent::WrapObjectInternal(JSContext* aCx,
     52                                           JS::Handle<JSObject*> aGivenProto) {
     53  return PointerEvent_Binding::Wrap(aCx, this, aGivenProto);
     54 }
     55 
     56 static uint16_t ConvertStringToPointerType(const nsAString& aPointerTypeArg,
     57                                           bool aForTrustedEvent) {
     58  if (aPointerTypeArg.EqualsLiteral("mouse")) {
     59    return MouseEvent_Binding::MOZ_SOURCE_MOUSE;
     60  }
     61  if (aPointerTypeArg.EqualsLiteral("pen")) {
     62    return MouseEvent_Binding::MOZ_SOURCE_PEN;
     63  }
     64  if (aPointerTypeArg.EqualsLiteral("touch")) {
     65    return MouseEvent_Binding::MOZ_SOURCE_TOUCH;
     66  }
     67 
     68  // Some chrome script need to copy the input source of a source event to
     69  // dispatching new event.  Therefore, we need to allow chrome script to
     70  // set it to any input sources which we are supporting.  However, these
     71  // types are not standardized by the specs.  Therefore, we should do this
     72  // only when the event is a trusted one.
     73  if (aForTrustedEvent) {
     74    if (aPointerTypeArg.EqualsLiteral("eraser")) {
     75      return MouseEvent_Binding::MOZ_SOURCE_ERASER;
     76    }
     77    if (aPointerTypeArg.EqualsLiteral("cursor")) {
     78      return MouseEvent_Binding::MOZ_SOURCE_CURSOR;
     79    }
     80    if (aPointerTypeArg.EqualsLiteral("keyboard")) {
     81      return MouseEvent_Binding::MOZ_SOURCE_KEYBOARD;
     82    }
     83  }
     84 
     85  return MouseEvent_Binding::MOZ_SOURCE_UNKNOWN;
     86 }
     87 
     88 void ConvertPointerTypeToString(uint16_t aPointerTypeSrc,
     89                                nsAString& aPointerTypeDest) {
     90  switch (aPointerTypeSrc) {
     91    case MouseEvent_Binding::MOZ_SOURCE_MOUSE:
     92      aPointerTypeDest.AssignLiteral("mouse");
     93      break;
     94    case MouseEvent_Binding::MOZ_SOURCE_PEN:
     95      aPointerTypeDest.AssignLiteral("pen");
     96      break;
     97    case MouseEvent_Binding::MOZ_SOURCE_TOUCH:
     98      aPointerTypeDest.AssignLiteral("touch");
     99      break;
    100    // In ConvertStringToPointerType(), we allow chrome script to set the
    101    // input source from Gecko specific pointerType value.  However, we won't
    102    // expose them to the web because they are not standardized.
    103    case MouseEvent_Binding::MOZ_SOURCE_ERASER:
    104    case MouseEvent_Binding::MOZ_SOURCE_CURSOR:
    105    case MouseEvent_Binding::MOZ_SOURCE_KEYBOARD:
    106      aPointerTypeDest.Truncate();
    107      break;
    108    default:
    109      aPointerTypeDest.Truncate();
    110      break;
    111  }
    112 }
    113 
    114 // static
    115 already_AddRefed<PointerEvent> PointerEvent::Constructor(
    116    EventTarget* aOwner, const nsAString& aType,
    117    const PointerEventInit& aParam) {
    118  RefPtr<PointerEvent> e = new PointerEvent(aOwner, nullptr, nullptr);
    119  bool trusted = e->Init(aOwner);
    120 
    121  e->InitMouseEventInternal(
    122      aType, aParam.mBubbles, aParam.mCancelable, aParam.mView, aParam.mDetail,
    123      aParam.mScreenX, aParam.mScreenY, aParam.mClientX, aParam.mClientY, false,
    124      false, false, false, aParam.mButton, aParam.mRelatedTarget);
    125  e->InitializeExtraMouseEventDictionaryMembers(aParam);
    126  e->mPointerType = Some(aParam.mPointerType);
    127 
    128  WidgetPointerEvent* widgetEvent = e->mEvent->AsPointerEvent();
    129  widgetEvent->pointerId = aParam.mPointerId;
    130  widgetEvent->mWidth = aParam.mWidth;
    131  widgetEvent->mHeight = aParam.mHeight;
    132  widgetEvent->mPressure = aParam.mPressure;
    133  widgetEvent->tangentialPressure = aParam.mTangentialPressure;
    134  widgetEvent->twist = aParam.mTwist;
    135  widgetEvent->mInputSource =
    136      ConvertStringToPointerType(aParam.mPointerType, trusted);
    137  widgetEvent->mIsPrimary = aParam.mIsPrimary;
    138  widgetEvent->mButtons = aParam.mButtons;
    139 
    140  if (aParam.mTiltX.WasPassed()) {
    141    e->mTiltX.emplace(aParam.mTiltX.Value());
    142  }
    143  if (aParam.mTiltY.WasPassed()) {
    144    e->mTiltY.emplace(aParam.mTiltY.Value());
    145  }
    146  if (aParam.mAltitudeAngle.WasPassed()) {
    147    e->mAltitudeAngle.emplace(aParam.mAltitudeAngle.Value());
    148  }
    149  if (aParam.mAzimuthAngle.WasPassed()) {
    150    e->mAzimuthAngle.emplace(aParam.mAzimuthAngle.Value());
    151  }
    152 
    153  e->mPersistentDeviceId.emplace(aParam.mPersistentDeviceId);
    154 
    155  if (!aParam.mCoalescedEvents.IsEmpty()) {
    156    e->mCoalescedEvents.AppendElements(aParam.mCoalescedEvents);
    157  }
    158  if (!aParam.mPredictedEvents.IsEmpty()) {
    159    e->mPredictedEvents.AppendElements(aParam.mPredictedEvents);
    160  }
    161 
    162  // If only tiltX and/or tiltY is set, altitudeAngle and azimuthAngle should
    163  // be computed from them when they are requested by JS.
    164  if ((e->mTiltX || e->mTiltY) && (!e->mAltitudeAngle && !e->mAzimuthAngle)) {
    165    if (!e->mTiltX) {
    166      e->mTiltX.emplace(0);
    167    }
    168    if (!e->mTiltY) {
    169      e->mTiltY.emplace(0);
    170    }
    171  }
    172  // If only altitudeAngle and/or azimuthAngle is set, tiltX and tiltY should be
    173  // computed from them when they are requested by JS.
    174  else if ((e->mAltitudeAngle || e->mAzimuthAngle) &&
    175           (!e->mTiltX && !e->mTiltY)) {
    176    if (!e->mAltitudeAngle) {
    177      e->mAltitudeAngle.emplace(WidgetPointerHelper::GetDefaultAltitudeAngle());
    178    }
    179    if (!e->mAzimuthAngle) {
    180      e->mAzimuthAngle.emplace(WidgetPointerHelper::GetDefaultAzimuthAngle());
    181    }
    182  }
    183  // Otherwise, initialize the uninitialized values with their default values
    184  else {
    185    if (!e->mTiltX) {
    186      e->mTiltX.emplace(0);
    187    }
    188    if (!e->mTiltY) {
    189      e->mTiltY.emplace(0);
    190    }
    191    if (!e->mAltitudeAngle) {
    192      e->mAltitudeAngle.emplace(WidgetPointerHelper::GetDefaultAltitudeAngle());
    193    }
    194    if (!e->mAzimuthAngle) {
    195      e->mAzimuthAngle.emplace(WidgetPointerHelper::GetDefaultAzimuthAngle());
    196    }
    197  }
    198 
    199  e->SetTrusted(trusted);
    200  e->SetComposed(aParam.mComposed);
    201  return e.forget();
    202 }
    203 
    204 // static
    205 already_AddRefed<PointerEvent> PointerEvent::Constructor(
    206    const GlobalObject& aGlobal, const nsAString& aType,
    207    const PointerEventInit& aParam) {
    208  nsCOMPtr<EventTarget> owner = do_QueryInterface(aGlobal.GetAsSupports());
    209  return Constructor(owner, aType, aParam);
    210 }
    211 
    212 NS_IMPL_CYCLE_COLLECTION_CLASS(PointerEvent)
    213 
    214 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PointerEvent, MouseEvent)
    215  NS_IMPL_CYCLE_COLLECTION_UNLINK(mCoalescedEvents)
    216  NS_IMPL_CYCLE_COLLECTION_UNLINK(mPredictedEvents)
    217 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
    218 
    219 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PointerEvent, MouseEvent)
    220  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCoalescedEvents)
    221  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPredictedEvents)
    222 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
    223 
    224 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PointerEvent)
    225 NS_INTERFACE_MAP_END_INHERITING(MouseEvent)
    226 
    227 NS_IMPL_ADDREF_INHERITED(PointerEvent, MouseEvent)
    228 NS_IMPL_RELEASE_INHERITED(PointerEvent, MouseEvent)
    229 
    230 uint16_t PointerEvent::ResistantInputSource(CallerType aCallerType) const {
    231  const uint16_t inputSource = mEvent->AsPointerEvent()->mInputSource;
    232  if (!ShouldResistFingerprinting(aCallerType)) {
    233    return inputSource;
    234  }
    235 
    236  MOZ_ASSERT(IsTrusted());
    237 
    238  // Bug 1953665: Pen events are inconsistent between platforms.
    239  // They might emit touch events on Windows and Android, but only mouse events
    240  // in other platforms. In particular, touch is always disabled on macOS.
    241 #if defined(XP_WIN)
    242  if (inputSource == MouseEvent_Binding::MOZ_SOURCE_TOUCH ||
    243      inputSource == MouseEvent_Binding::MOZ_SOURCE_MOUSE) {
    244    return inputSource;
    245  }
    246  // Similar to nsWindow::DispatchTouchEventFromWMPointer.
    247  switch (mEvent->mMessage) {
    248    case ePointerMove:
    249      return mEvent->AsPointerEvent()->mPressure == 0
    250                 ? MouseEvent_Binding::MOZ_SOURCE_MOUSE  // hover
    251                 : MouseEvent_Binding::MOZ_SOURCE_TOUCH;
    252    case ePointerUp:
    253    case ePointerDown:
    254    case ePointerCancel:
    255      return MouseEvent_Binding::MOZ_SOURCE_TOUCH;
    256    default:
    257      return MouseEvent_Binding::MOZ_SOURCE_MOUSE;
    258  }
    259 #elif defined(MOZ_WIDGET_ANDROID)
    260  return inputSource == MouseEvent_Binding::MOZ_SOURCE_MOUSE
    261             ? MouseEvent_Binding::MOZ_SOURCE_MOUSE
    262             : MouseEvent_Binding::MOZ_SOURCE_TOUCH;
    263 #elif defined(MOZ_WIDGET_GTK)
    264  return inputSource == MouseEvent_Binding::MOZ_SOURCE_TOUCH
    265             ? MouseEvent_Binding::MOZ_SOURCE_TOUCH
    266             : MouseEvent_Binding::MOZ_SOURCE_MOUSE;
    267 #elif defined(MOZ_WIDGET_COCOA)
    268  return MouseEvent_Binding::MOZ_SOURCE_MOUSE;
    269 #else
    270  return inputSource;
    271 #endif
    272 }
    273 
    274 void PointerEvent::GetPointerType(nsAString& aPointerType,
    275                                  CallerType aCallerType) const {
    276  if (mPointerType.isSome()) {
    277    aPointerType = mPointerType.value();
    278    return;
    279  }
    280  ConvertPointerTypeToString(ResistantInputSource(aCallerType), aPointerType);
    281 }
    282 
    283 int32_t PointerEvent::PointerId(CallerType aCallerType) const {
    284 #ifdef MOZ_WIDGET_COCOA
    285  if (ShouldResistFingerprinting(aCallerType)) {
    286    return PointerEventHandler::GetSpoofedPointerIdForRFP();
    287  }
    288 #endif
    289  return mEvent->AsPointerEvent()->pointerId;
    290 }
    291 
    292 double PointerEvent::Width(CallerType aCallerType) const {
    293  return ShouldResistFingerprinting(aCallerType)
    294             ? 1.0
    295             : mEvent->AsPointerEvent()->mWidth;
    296 }
    297 
    298 double PointerEvent::Height(CallerType aCallerType) const {
    299  return ShouldResistFingerprinting(aCallerType)
    300             ? 1.0
    301             : mEvent->AsPointerEvent()->mHeight;
    302 }
    303 
    304 float PointerEvent::Pressure(CallerType aCallerType) const {
    305  if (mEvent->mMessage == ePointerUp ||
    306      !ShouldResistFingerprinting(aCallerType)) {
    307    return mEvent->AsPointerEvent()->mPressure;
    308  }
    309 
    310  // According to [1], we should use 0.5 when it is in active buttons state and
    311  // 0 otherwise for devices that don't support pressure. And a pointerup event
    312  // always reports 0, so we don't need to spoof that.
    313  //
    314  // [1] https://www.w3.org/TR/pointerevents/#dom-pointerevent-pressure
    315  float spoofedPressure = 0.0;
    316  if (mEvent->AsPointerEvent()->mButtons) {
    317    spoofedPressure = 0.5;
    318  }
    319 
    320  return spoofedPressure;
    321 }
    322 
    323 float PointerEvent::TangentialPressure(CallerType aCallerType) const {
    324  return ShouldResistFingerprinting(aCallerType)
    325             ? 0
    326             : mEvent->AsPointerEvent()->tangentialPressure;
    327 }
    328 
    329 int32_t PointerEvent::TiltX(CallerType aCallerType) {
    330  if (ShouldResistFingerprinting(aCallerType)) {
    331    return 0;
    332  }
    333  if (mTiltX.isSome()) {
    334    return *mTiltX;
    335  }
    336  mTiltX.emplace(
    337      WidgetPointerHelper::ComputeTiltX(*mAltitudeAngle, *mAzimuthAngle));
    338  return *mTiltX;
    339 }
    340 
    341 int32_t PointerEvent::TiltY(CallerType aCallerType) {
    342  if (ShouldResistFingerprinting(aCallerType)) {
    343    return 0;
    344  }
    345  if (mTiltY.isSome()) {
    346    return *mTiltY;
    347  }
    348  mTiltY.emplace(
    349      WidgetPointerHelper::ComputeTiltY(*mAltitudeAngle, *mAzimuthAngle));
    350  return *mTiltY;
    351 }
    352 
    353 int32_t PointerEvent::Twist(CallerType aCallerType) const {
    354  return ShouldResistFingerprinting(aCallerType)
    355             ? 0
    356             : mEvent->AsPointerEvent()->twist;
    357 }
    358 
    359 double PointerEvent::AltitudeAngle(CallerType aCallerType) {
    360  if (ShouldResistFingerprinting(aCallerType)) {
    361    return WidgetPointerHelper::GetDefaultAltitudeAngle();
    362  }
    363  if (mAltitudeAngle.isSome()) {
    364    return *mAltitudeAngle;
    365  }
    366  mAltitudeAngle.emplace(
    367      WidgetPointerHelper::ComputeAltitudeAngle(*mTiltX, *mTiltY));
    368  return *mAltitudeAngle;
    369 }
    370 
    371 double PointerEvent::AzimuthAngle(CallerType aCallerType) {
    372  if (ShouldResistFingerprinting(aCallerType)) {
    373    return WidgetPointerHelper::GetDefaultAzimuthAngle();
    374  }
    375  if (mAzimuthAngle.isSome()) {
    376    return *mAzimuthAngle;
    377  }
    378  mAzimuthAngle.emplace(
    379      WidgetPointerHelper::ComputeAzimuthAngle(*mTiltX, *mTiltY));
    380  return *mAzimuthAngle;
    381 }
    382 
    383 bool PointerEvent::IsPrimary() const {
    384  return mEvent->AsPointerEvent()->mIsPrimary;
    385 }
    386 
    387 int32_t PointerEvent::PersistentDeviceId(CallerType aCallerType) {
    388  const auto MaybeNonZero = [&]() {
    389    return mEvent->IsTrusted() && IsPointerEventMessage(mEvent->mMessage) &&
    390           !IsPointerEventMessageOriginallyMouseEventMessage(mEvent->mMessage);
    391  };
    392 
    393  if (ShouldResistFingerprinting(aCallerType)) {
    394    return MaybeNonZero() && ResistantInputSource(aCallerType) ==
    395                                 MouseEvent_Binding::MOZ_SOURCE_MOUSE
    396               ? 1
    397               : 0;
    398  }
    399 
    400  if (mPersistentDeviceId.isNothing()) {
    401    if (MaybeNonZero() && mEvent->AsPointerEvent()->mInputSource ==
    402                              MouseEvent_Binding::MOZ_SOURCE_MOUSE) {
    403      // Follow the behavior which Chrome has for mouse.
    404      mPersistentDeviceId.emplace(1);
    405    } else {
    406      // For now the default value is reported for non-mouse based events.
    407      mPersistentDeviceId.emplace(0);
    408    }
    409  }
    410 
    411  return mPersistentDeviceId.value();
    412 }
    413 
    414 bool PointerEvent::EnableGetCoalescedEvents(JSContext* aCx, JSObject* aGlobal) {
    415  return !StaticPrefs::
    416             dom_w3c_pointer_events_getcoalescedevents_only_in_securecontext() ||
    417         nsContentUtils::IsSecureContextOrWebExtension(aCx, aGlobal);
    418 }
    419 
    420 void PointerEvent::GetCoalescedEvents(
    421    nsTArray<RefPtr<PointerEvent>>& aPointerEvents) {
    422  WidgetPointerEvent* widgetEvent = mEvent->AsPointerEvent();
    423  MOZ_ASSERT(widgetEvent);
    424  EnsureFillingCoalescedEvents(*widgetEvent);
    425  if (mCoalescedEvents.IsEmpty() && widgetEvent &&
    426      widgetEvent->mCoalescedWidgetEvents &&
    427      !widgetEvent->mCoalescedWidgetEvents->mEvents.IsEmpty()) {
    428    nsCOMPtr<EventTarget> owner = do_QueryInterface(mOwner);
    429    for (WidgetPointerEvent& event :
    430         widgetEvent->mCoalescedWidgetEvents->mEvents) {
    431      RefPtr<PointerEvent> domEvent =
    432          NS_NewDOMPointerEvent(owner, nullptr, &event);
    433      domEvent->mCoalescedOrPredictedEvent = true;
    434 
    435      // The dom event is derived from an OS generated widget event. Setup
    436      // mWidget and mPresContext since they are necessary to calculate
    437      // offsetX / offsetY.
    438      domEvent->mEvent->AsGUIEvent()->mWidget = widgetEvent->mWidget;
    439      domEvent->mPresContext = mPresContext;
    440 
    441      // The coalesced widget mouse events shouldn't have been dispatched.
    442      MOZ_ASSERT(!domEvent->mEvent->mTarget);
    443      // The event target should be the same as the dispatched event's target.
    444      domEvent->mEvent->mTarget = mEvent->mTarget;
    445 
    446      // JS could hold reference to dom events. We have to ask dom event to
    447      // duplicate its private data to avoid the widget event is destroyed.
    448      domEvent->DuplicatePrivateData();
    449 
    450      mCoalescedEvents.AppendElement(domEvent);
    451    }
    452  }
    453  if (mEvent->IsTrusted() && mEvent->mTarget) {
    454    for (RefPtr<PointerEvent>& pointerEvent : mCoalescedEvents) {
    455      // Only set event target when it's null.
    456      if (!pointerEvent->mEvent->mTarget) {
    457        pointerEvent->mEvent->mTarget = mEvent->mTarget;
    458      }
    459    }
    460  }
    461  aPointerEvents.AppendElements(mCoalescedEvents);
    462 }
    463 
    464 void PointerEvent::EnsureFillingCoalescedEvents(
    465    WidgetPointerEvent& aWidgetEvent) {
    466  if (!aWidgetEvent.IsTrusted() ||
    467      (aWidgetEvent.mMessage != ePointerMove &&
    468       aWidgetEvent.mMessage != ePointerRawUpdate) ||
    469      !mCoalescedEvents.IsEmpty() ||
    470      (aWidgetEvent.mCoalescedWidgetEvents &&
    471       !aWidgetEvent.mCoalescedWidgetEvents->mEvents.IsEmpty()) ||
    472      mCoalescedOrPredictedEvent) {
    473    return;
    474  }
    475  if (!aWidgetEvent.mCoalescedWidgetEvents) {
    476    aWidgetEvent.mCoalescedWidgetEvents = new WidgetPointerEventHolder();
    477  }
    478  WidgetPointerEvent* const coalescedEvent =
    479      aWidgetEvent.mCoalescedWidgetEvents->mEvents.AppendElement(
    480          WidgetPointerEvent(true, aWidgetEvent.mMessage,
    481                             aWidgetEvent.mWidget));
    482  MOZ_ASSERT(coalescedEvent);
    483  PointerEventHandler::InitCoalescedEventFromPointerEvent(*coalescedEvent,
    484                                                          aWidgetEvent);
    485 }
    486 
    487 void PointerEvent::GetPredictedEvents(
    488    nsTArray<RefPtr<PointerEvent>>& aPointerEvents) {
    489  // XXX Add support for native predicted events, bug 1550461
    490  // And when doing so, update mCoalescedOrPredictedEvent here.
    491  if (mEvent->IsTrusted() && mEvent->mTarget) {
    492    for (RefPtr<PointerEvent>& pointerEvent : mPredictedEvents) {
    493      // Only set event target when it's null.
    494      if (!pointerEvent->mEvent->mTarget) {
    495        pointerEvent->mEvent->mTarget = mEvent->mTarget;
    496      }
    497    }
    498  }
    499  aPointerEvents.AppendElements(mPredictedEvents);
    500 }
    501 
    502 bool PointerEvent::ShouldResistFingerprinting(CallerType aCallerType) const {
    503  // There are a few simple situations we don't need to spoof this pointer
    504  // event.
    505  //   * We are being called by a System caller
    506  //   * The pref privcy.resistFingerprinting' is false, we fast return here
    507  //     since we don't need to do any QI of following codes.
    508  //   * This event is generated by scripts.
    509  //   * This event is a mouse pointer event.
    510  //  We don't need to check for the system group since pointer events won't be
    511  //  dispatched to the system group.
    512  RFPTarget target = RFPTarget::PointerEvents;
    513  if (aCallerType == CallerType::System ||
    514      !nsContentUtils::ShouldResistFingerprinting("Efficiency Check", target) ||
    515      !mEvent->IsTrusted() ||
    516      mEvent->AsPointerEvent()->mInputSource ==
    517          MouseEvent_Binding::MOZ_SOURCE_MOUSE) {
    518    return false;
    519  }
    520 
    521  // Pref is checked above, so use true as fallback.
    522  nsCOMPtr<Document> doc = GetDocument();
    523  return doc ? doc->ShouldResistFingerprinting(target) : true;
    524 }
    525 
    526 }  // namespace mozilla::dom
    527 
    528 using namespace mozilla;
    529 using namespace mozilla::dom;
    530 
    531 already_AddRefed<PointerEvent> NS_NewDOMPointerEvent(
    532    EventTarget* aOwner, nsPresContext* aPresContext,
    533    WidgetPointerEvent* aEvent) {
    534  RefPtr<PointerEvent> it = new PointerEvent(aOwner, aPresContext, aEvent);
    535  return it.forget();
    536 }