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/TouchEvent.h"
8 #include "mozilla/dom/Touch.h"
9 #include "mozilla/dom/TouchListBinding.h"
10 #include "mozilla/Preferences.h"
11 #include "mozilla/TouchEvents.h"
12 #include "nsContentUtils.h"
18 extern int32_t IsTouchDeviceSupportPresent();
20 #endif // #ifdef XP_WIN
24 /******************************************************************************
26 *****************************************************************************/
28 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TouchList
)
29 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
30 NS_INTERFACE_MAP_ENTRY(nsISupports
)
33 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TouchList
, mParent
, mPoints
)
35 NS_IMPL_CYCLE_COLLECTING_ADDREF(TouchList
)
36 NS_IMPL_CYCLE_COLLECTING_RELEASE(TouchList
)
39 TouchList::WrapObject(JSContext
* aCx
)
41 return TouchListBinding::Wrap(aCx
, this);
46 TouchList::PrefEnabled(JSContext
* aCx
, JSObject
* aGlobal
)
48 return TouchEvent::PrefEnabled(aCx
, aGlobal
);
52 TouchList::IdentifiedTouch(int32_t aIdentifier
) const
54 for (uint32_t i
= 0; i
< mPoints
.Length(); ++i
) {
55 Touch
* point
= mPoints
[i
];
56 if (point
&& point
->Identifier() == aIdentifier
) {
63 /******************************************************************************
65 *****************************************************************************/
67 TouchEvent::TouchEvent(EventTarget
* aOwner
,
68 nsPresContext
* aPresContext
,
69 WidgetTouchEvent
* aEvent
)
70 : UIEvent(aOwner
, aPresContext
,
71 aEvent
? aEvent
: new WidgetTouchEvent(false, 0, nullptr))
74 mEventIsInternal
= false;
76 for (uint32_t i
= 0; i
< aEvent
->touches
.Length(); ++i
) {
77 Touch
* touch
= aEvent
->touches
[i
];
78 touch
->InitializePoints(mPresContext
, aEvent
);
81 mEventIsInternal
= true;
82 mEvent
->time
= PR_Now();
86 NS_IMPL_CYCLE_COLLECTION_INHERITED(TouchEvent
, UIEvent
,
91 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TouchEvent
)
92 NS_INTERFACE_MAP_END_INHERITING(UIEvent
)
94 NS_IMPL_ADDREF_INHERITED(TouchEvent
, UIEvent
)
95 NS_IMPL_RELEASE_INHERITED(TouchEvent
, UIEvent
)
98 TouchEvent::InitTouchEvent(const nsAString
& aType
,
108 TouchList
* aTargetTouches
,
109 TouchList
* aChangedTouches
,
112 aRv
= UIEvent::InitUIEvent(aType
, aCanBubble
, aCancelable
, aView
, aDetail
);
117 mEvent
->AsInputEvent()->InitBasicModifiers(aCtrlKey
, aAltKey
,
118 aShiftKey
, aMetaKey
);
120 mTargetTouches
= aTargetTouches
;
121 mChangedTouches
= aChangedTouches
;
125 TouchEvent::Touches()
128 WidgetTouchEvent
* touchEvent
= mEvent
->AsTouchEvent();
129 if (mEvent
->message
== NS_TOUCH_END
|| mEvent
->message
== NS_TOUCH_CANCEL
) {
130 // for touchend events, remove any changed touches from the touches array
131 WidgetTouchEvent::AutoTouchArray unchangedTouches
;
132 const WidgetTouchEvent::TouchArray
& touches
= touchEvent
->touches
;
133 for (uint32_t i
= 0; i
< touches
.Length(); ++i
) {
134 if (!touches
[i
]->mChanged
) {
135 unchangedTouches
.AppendElement(touches
[i
]);
138 mTouches
= new TouchList(ToSupports(this), unchangedTouches
);
140 mTouches
= new TouchList(ToSupports(this), touchEvent
->touches
);
147 TouchEvent::TargetTouches()
149 if (!mTargetTouches
) {
150 WidgetTouchEvent::AutoTouchArray targetTouches
;
151 WidgetTouchEvent
* touchEvent
= mEvent
->AsTouchEvent();
152 const WidgetTouchEvent::TouchArray
& touches
= touchEvent
->touches
;
153 for (uint32_t i
= 0; i
< touches
.Length(); ++i
) {
154 // for touchend/cancel events, don't append to the target list if this is a
155 // touch that is ending
156 if ((mEvent
->message
!= NS_TOUCH_END
&&
157 mEvent
->message
!= NS_TOUCH_CANCEL
) || !touches
[i
]->mChanged
) {
158 if (touches
[i
]->mTarget
== mEvent
->originalTarget
) {
159 targetTouches
.AppendElement(touches
[i
]);
163 mTargetTouches
= new TouchList(ToSupports(this), targetTouches
);
165 return mTargetTouches
;
169 TouchEvent::ChangedTouches()
171 if (!mChangedTouches
) {
172 WidgetTouchEvent::AutoTouchArray changedTouches
;
173 WidgetTouchEvent
* touchEvent
= mEvent
->AsTouchEvent();
174 const WidgetTouchEvent::TouchArray
& touches
= touchEvent
->touches
;
175 for (uint32_t i
= 0; i
< touches
.Length(); ++i
) {
176 if (touches
[i
]->mChanged
) {
177 changedTouches
.AppendElement(touches
[i
]);
180 mChangedTouches
= new TouchList(ToSupports(this), changedTouches
);
182 return mChangedTouches
;
187 TouchEvent::PrefEnabled(JSContext
* aCx
, JSObject
* aGlobal
)
189 bool prefValue
= false;
191 if (NS_SUCCEEDED(Preferences::GetInt("dom.w3c_touch_events.enabled",
195 static bool sDidCheckTouchDeviceSupport
= false;
196 static bool sIsTouchDeviceSupportPresent
= false;
197 // On Windows we auto-detect based on device support.
198 if (!sDidCheckTouchDeviceSupport
) {
199 sDidCheckTouchDeviceSupport
= true;
200 sIsTouchDeviceSupportPresent
= widget::IsTouchDeviceSupportPresent();
202 prefValue
= sIsTouchDeviceSupportPresent
;
204 NS_WARNING("dom.w3c_touch_events.enabled=2 not implemented!");
212 nsContentUtils::InitializeTouchEventTable();
220 return mEvent
->AsTouchEvent()->IsAlt();
224 TouchEvent::MetaKey()
226 return mEvent
->AsTouchEvent()->IsMeta();
230 TouchEvent::CtrlKey()
232 return mEvent
->AsTouchEvent()->IsControl();
236 TouchEvent::ShiftKey()
238 return mEvent
->AsTouchEvent()->IsShift();
242 } // namespace mozilla
244 using namespace mozilla
;
245 using namespace mozilla::dom
;
248 NS_NewDOMTouchEvent(nsIDOMEvent
** aInstancePtrResult
,
250 nsPresContext
* aPresContext
,
251 WidgetTouchEvent
* aEvent
)
253 TouchEvent
* it
= new TouchEvent(aOwner
, aPresContext
, aEvent
);
255 *aInstancePtrResult
= static_cast<Event
*>(it
);