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 "mozilla/dom/Touch.h"
9 #include "mozilla/dom/EventTarget.h"
10 #include "mozilla/dom/TouchEvent.h"
11 #include "nsContentUtils.h"
12 #include "nsIContent.h"
14 namespace mozilla::dom
{
17 already_AddRefed
<Touch
> Touch::Constructor(const GlobalObject
& aGlobal
,
18 const TouchInit
& aParam
) {
19 // Annoyingly many parameters, make sure the ordering is the same as in the
21 RefPtr
<Touch
> touch
= new Touch(
22 aParam
.mTarget
, aParam
.mIdentifier
, aParam
.mPageX
, aParam
.mPageY
,
23 aParam
.mScreenX
, aParam
.mScreenY
, aParam
.mClientX
, aParam
.mClientY
,
24 aParam
.mRadiusX
, aParam
.mRadiusY
, aParam
.mRotationAngle
, aParam
.mForce
);
25 return touch
.forget();
28 Touch::Touch(EventTarget
* aTarget
, int32_t aIdentifier
, int32_t aPageX
,
29 int32_t aPageY
, int32_t aScreenX
, int32_t aScreenY
,
30 int32_t aClientX
, int32_t aClientY
, int32_t aRadiusX
,
31 int32_t aRadiusY
, float aRotationAngle
, float aForce
)
32 : mIsTouchEventSuppressed(false) {
34 mOriginalTarget
= aTarget
;
35 mIdentifier
= aIdentifier
;
36 mPagePoint
= CSSIntPoint(aPageX
, aPageY
);
37 mScreenPoint
= CSSIntPoint(aScreenX
, aScreenY
);
38 mClientPoint
= CSSIntPoint(aClientX
, aClientY
);
39 mRefPoint
= LayoutDeviceIntPoint(0, 0);
40 mPointsInitialized
= true;
43 mRotationAngle
= aRotationAngle
;
48 nsJSContext::LikelyShortLivingObjectCreated();
51 Touch::Touch(int32_t aIdentifier
, LayoutDeviceIntPoint aPoint
,
52 LayoutDeviceIntPoint aRadius
, float aRotationAngle
, float aForce
)
53 : mIsTouchEventSuppressed(false) {
54 mIdentifier
= aIdentifier
;
55 mPagePoint
= CSSIntPoint(0, 0);
56 mScreenPoint
= CSSIntPoint(0, 0);
57 mClientPoint
= CSSIntPoint(0, 0);
59 mPointsInitialized
= false;
61 mRotationAngle
= aRotationAngle
;
66 nsJSContext::LikelyShortLivingObjectCreated();
69 Touch::Touch(int32_t aIdentifier
, LayoutDeviceIntPoint aPoint
,
70 LayoutDeviceIntPoint aRadius
, float aRotationAngle
, float aForce
,
71 int32_t aTiltX
, int32_t aTiltY
, int32_t aTwist
)
72 : Touch(aIdentifier
, aPoint
, aRadius
, aRotationAngle
, aForce
) {
78 Touch::Touch(const Touch
& aOther
)
79 : mOriginalTarget(aOther
.mOriginalTarget
),
80 mTarget(aOther
.mTarget
),
81 mRefPoint(aOther
.mRefPoint
),
82 mChanged(aOther
.mChanged
),
83 mIsTouchEventSuppressed(aOther
.mIsTouchEventSuppressed
),
84 mMessage(aOther
.mMessage
),
85 mIdentifier(aOther
.mIdentifier
),
86 mPagePoint(aOther
.mPagePoint
),
87 mClientPoint(aOther
.mClientPoint
),
88 mScreenPoint(aOther
.mScreenPoint
),
89 mRadius(aOther
.mRadius
),
90 mRotationAngle(aOther
.mRotationAngle
),
91 mForce(aOther
.mForce
),
92 mPointsInitialized(aOther
.mPointsInitialized
) {
93 nsJSContext::LikelyShortLivingObjectCreated();
96 Touch::~Touch() = default;
99 bool Touch::PrefEnabled(JSContext
* aCx
, JSObject
* aGlobal
) {
100 return TouchEvent::PrefEnabled(aCx
, aGlobal
);
103 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Touch
, mTarget
, mOriginalTarget
)
105 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Touch
)
106 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
107 NS_INTERFACE_MAP_ENTRY(nsISupports
)
110 NS_IMPL_CYCLE_COLLECTING_ADDREF(Touch
)
111 NS_IMPL_CYCLE_COLLECTING_RELEASE(Touch
)
113 static EventTarget
* FindFirstNonChromeOnlyAccessContent(EventTarget
* aTarget
) {
114 nsIContent
* content
= nsIContent::FromEventTargetOrNull(aTarget
);
115 if (content
&& content
->ChromeOnlyAccess() &&
116 !nsContentUtils::LegacyIsCallerNativeCode() &&
117 !nsContentUtils::CanAccessNativeAnon()) {
118 return content
->FindFirstNonChromeOnlyAccessContent();
124 EventTarget
* Touch::GetTarget() const {
125 return FindFirstNonChromeOnlyAccessContent(mTarget
);
128 EventTarget
* Touch::GetOriginalTarget() const {
129 return FindFirstNonChromeOnlyAccessContent(mOriginalTarget
);
132 int32_t Touch::ScreenX(CallerType aCallerType
) const {
133 if (nsContentUtils::ShouldResistFingerprinting(aCallerType
, GetParentObject(),
134 RFPTarget::TouchEvents
)) {
138 return mScreenPoint
.x
;
141 int32_t Touch::ScreenY(CallerType aCallerType
) const {
142 if (nsContentUtils::ShouldResistFingerprinting(aCallerType
, GetParentObject(),
143 RFPTarget::TouchEvents
)) {
147 return mScreenPoint
.y
;
150 int32_t Touch::RadiusX(CallerType aCallerType
) const {
151 if (nsContentUtils::ShouldResistFingerprinting(aCallerType
, GetParentObject(),
152 RFPTarget::TouchEvents
)) {
159 int32_t Touch::RadiusY(CallerType aCallerType
) const {
160 if (nsContentUtils::ShouldResistFingerprinting(aCallerType
, GetParentObject(),
161 RFPTarget::TouchEvents
)) {
168 float Touch::RotationAngle(CallerType aCallerType
) const {
169 if (nsContentUtils::ShouldResistFingerprinting(aCallerType
, GetParentObject(),
170 RFPTarget::TouchEvents
)) {
174 return mRotationAngle
;
177 float Touch::Force(CallerType aCallerType
) const {
178 if (nsContentUtils::ShouldResistFingerprinting(aCallerType
, GetParentObject(),
179 RFPTarget::TouchEvents
)) {
186 void Touch::InitializePoints(nsPresContext
* aPresContext
, WidgetEvent
* aEvent
) {
187 if (mPointsInitialized
) {
191 Event::GetClientCoords(aPresContext
, aEvent
, mRefPoint
, mClientPoint
);
193 Event::GetPageCoords(aPresContext
, aEvent
, mRefPoint
, mClientPoint
);
195 Event::GetScreenCoords(aPresContext
, aEvent
, mRefPoint
).extract();
196 mPointsInitialized
= true;
199 void Touch::SetTouchTarget(EventTarget
* aTarget
) {
200 mOriginalTarget
= aTarget
;
204 bool Touch::Equals(Touch
* aTouch
) const {
205 return mRefPoint
== aTouch
->mRefPoint
&& mForce
== aTouch
->mForce
&&
206 mRotationAngle
== aTouch
->mRotationAngle
&&
207 mRadius
.x
== aTouch
->mRadius
.x
&& mRadius
.y
== aTouch
->mRadius
.y
;
210 void Touch::SetSameAs(const Touch
* aTouch
) {
211 mRefPoint
= aTouch
->mRefPoint
;
212 mForce
= aTouch
->mForce
;
213 mRotationAngle
= aTouch
->mRotationAngle
;
214 mRadius
.x
= aTouch
->mRadius
.x
;
215 mRadius
.y
= aTouch
->mRadius
.y
;
218 JSObject
* Touch::WrapObject(JSContext
* aCx
, JS::Handle
<JSObject
*> aGivenProto
) {
219 return Touch_Binding::Wrap(aCx
, this, aGivenProto
);
222 // Parent ourselves to the global of the target. This achieves the desirable
223 // effects of parenting to the target, but avoids making the touch inaccessible
224 // when the target happens to be NAC and therefore reflected into the XBL scope.
225 nsIGlobalObject
* Touch::GetParentObject() const {
226 if (!mOriginalTarget
) {
229 return mOriginalTarget
->GetOwnerGlobal();
232 } // namespace mozilla::dom