Touch.cpp (7580B)
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 "mozilla/dom/Touch.h" 8 9 #include "mozilla/dom/EventTarget.h" 10 #include "mozilla/dom/TouchEvent.h" 11 #include "nsContentUtils.h" 12 #include "nsIContent.h" 13 14 namespace mozilla::dom { 15 16 // static 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 20 // Touch constructor. 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(); 26 } 27 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) { 33 mTarget = aTarget; 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; 41 mRadius.x = aRadiusX; 42 mRadius.y = aRadiusY; 43 mRotationAngle = aRotationAngle; 44 mForce = aForce; 45 46 mChanged = false; 47 mMessage = 0; 48 nsJSContext::LikelyShortLivingObjectCreated(); 49 } 50 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); 58 mRefPoint = aPoint; 59 mPointsInitialized = false; 60 mRadius = aRadius; 61 mRotationAngle = aRotationAngle; 62 mForce = aForce; 63 64 mChanged = false; 65 mMessage = 0; 66 nsJSContext::LikelyShortLivingObjectCreated(); 67 } 68 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) { 73 tiltX = aTiltX; 74 tiltY = aTiltY; 75 twist = aTwist; 76 } 77 78 Touch::Touch(const Touch& aOther) 79 : WidgetPointerHelper(aOther), 80 mOriginalTarget(aOther.mOriginalTarget), 81 mTarget(aOther.mTarget), 82 mRefPoint(aOther.mRefPoint), 83 mChanged(aOther.mChanged), 84 mIsTouchEventSuppressed(aOther.mIsTouchEventSuppressed), 85 mMessage(aOther.mMessage), 86 mIdentifier(aOther.mIdentifier), 87 mPagePoint(aOther.mPagePoint), 88 mClientPoint(aOther.mClientPoint), 89 mScreenPoint(aOther.mScreenPoint), 90 mRadius(aOther.mRadius), 91 mRotationAngle(aOther.mRotationAngle), 92 mForce(aOther.mForce), 93 mPointsInitialized(aOther.mPointsInitialized) { 94 nsJSContext::LikelyShortLivingObjectCreated(); 95 } 96 97 Touch::~Touch() = default; 98 99 // static 100 bool Touch::PrefEnabled(JSContext* aCx, JSObject* aGlobal) { 101 return TouchEvent::PrefEnabled(aCx, aGlobal); 102 } 103 104 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Touch, mTarget, mOriginalTarget) 105 106 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Touch) 107 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY 108 NS_INTERFACE_MAP_ENTRY(nsISupports) 109 NS_INTERFACE_MAP_END 110 111 NS_IMPL_CYCLE_COLLECTING_ADDREF(Touch) 112 NS_IMPL_CYCLE_COLLECTING_RELEASE(Touch) 113 114 static EventTarget* FindFirstNonChromeOnlyAccessContent(EventTarget* aTarget) { 115 nsIContent* content = nsIContent::FromEventTargetOrNull(aTarget); 116 if (content && content->ChromeOnlyAccess() && 117 !nsContentUtils::LegacyIsCallerNativeCode() && 118 !nsContentUtils::CanAccessNativeAnon()) { 119 return content->FindFirstNonChromeOnlyAccessContent(); 120 } 121 122 return aTarget; 123 } 124 125 EventTarget* Touch::GetTarget() const { 126 return FindFirstNonChromeOnlyAccessContent(mTarget); 127 } 128 129 EventTarget* Touch::GetOriginalTarget() const { 130 return FindFirstNonChromeOnlyAccessContent(mOriginalTarget); 131 } 132 133 int32_t Touch::ScreenX(CallerType aCallerType) const { 134 if (nsContentUtils::ShouldResistFingerprinting(aCallerType, GetParentObject(), 135 RFPTarget::TouchEvents)) { 136 return ClientX(); 137 } 138 139 return mScreenPoint.x; 140 } 141 142 int32_t Touch::ScreenY(CallerType aCallerType) const { 143 if (nsContentUtils::ShouldResistFingerprinting(aCallerType, GetParentObject(), 144 RFPTarget::TouchEvents)) { 145 return ClientY(); 146 } 147 148 return mScreenPoint.y; 149 } 150 151 int32_t Touch::RadiusX(CallerType aCallerType) const { 152 if (nsContentUtils::ShouldResistFingerprinting(aCallerType, GetParentObject(), 153 RFPTarget::TouchEvents)) { 154 return 0; 155 } 156 157 return mRadius.x; 158 } 159 160 int32_t Touch::RadiusY(CallerType aCallerType) const { 161 if (nsContentUtils::ShouldResistFingerprinting(aCallerType, GetParentObject(), 162 RFPTarget::TouchEvents)) { 163 return 0; 164 } 165 166 return mRadius.y; 167 } 168 169 float Touch::RotationAngle(CallerType aCallerType) const { 170 if (nsContentUtils::ShouldResistFingerprinting(aCallerType, GetParentObject(), 171 RFPTarget::TouchEvents)) { 172 return 0.0f; 173 } 174 175 return mRotationAngle; 176 } 177 178 float Touch::Force(CallerType aCallerType) const { 179 if (nsContentUtils::ShouldResistFingerprinting(aCallerType, GetParentObject(), 180 RFPTarget::TouchEvents)) { 181 return 0.0f; 182 } 183 184 return mForce; 185 } 186 187 void Touch::InitializePoints(nsPresContext* aPresContext, WidgetEvent* aEvent) { 188 if (mPointsInitialized) { 189 return; 190 } 191 mClientPoint = RoundedToInt( 192 Event::GetClientCoords(aPresContext, aEvent, mRefPoint, mClientPoint)); 193 mPagePoint = RoundedToInt( 194 Event::GetPageCoords(aPresContext, aEvent, mRefPoint, mClientPoint)); 195 mScreenPoint = RoundedToInt( 196 Event::GetScreenCoords(aPresContext, aEvent, mRefPoint).extract()); 197 mPointsInitialized = true; 198 } 199 200 void Touch::SetTouchTarget(EventTarget* aTarget) { 201 mOriginalTarget = aTarget; 202 mTarget = aTarget; 203 } 204 205 bool Touch::Equals(Touch* aTouch) const { 206 return mRefPoint == aTouch->mRefPoint && mForce == aTouch->mForce && 207 mRotationAngle == aTouch->mRotationAngle && 208 mRadius.x == aTouch->mRadius.x && mRadius.y == aTouch->mRadius.y; 209 } 210 211 void Touch::SetSameAs(const Touch* aTouch) { 212 mRefPoint = aTouch->mRefPoint; 213 mForce = aTouch->mForce; 214 mRotationAngle = aTouch->mRotationAngle; 215 mRadius.x = aTouch->mRadius.x; 216 mRadius.y = aTouch->mRadius.y; 217 } 218 219 JSObject* Touch::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) { 220 return Touch_Binding::Wrap(aCx, this, aGivenProto); 221 } 222 223 // Parent ourselves to the global of the target. This achieves the desirable 224 // effects of parenting to the target, but avoids making the touch inaccessible 225 // when the target happens to be NAC and therefore reflected into the XBL scope. 226 nsIGlobalObject* Touch::GetParentObject() const { 227 if (!mOriginalTarget) { 228 return nullptr; 229 } 230 return mOriginalTarget->GetOwnerGlobal(); 231 } 232 233 } // namespace mozilla::dom