dom/events/TouchEvent.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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"
    14 namespace mozilla {
    16 #ifdef XP_WIN
    17 namespace widget {
    18 extern int32_t IsTouchDeviceSupportPresent();
    19 } // namespace widget
    20 #endif // #ifdef XP_WIN
    22 namespace dom {
    24 /******************************************************************************
    25  * TouchList
    26  *****************************************************************************/
    28 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TouchList)
    29   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
    30   NS_INTERFACE_MAP_ENTRY(nsISupports)
    31 NS_INTERFACE_MAP_END
    33 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(TouchList, mParent, mPoints)
    35 NS_IMPL_CYCLE_COLLECTING_ADDREF(TouchList)
    36 NS_IMPL_CYCLE_COLLECTING_RELEASE(TouchList)
    38 JSObject*
    39 TouchList::WrapObject(JSContext* aCx)
    40 {
    41   return TouchListBinding::Wrap(aCx, this);
    42 }
    44 // static
    45 bool
    46 TouchList::PrefEnabled(JSContext* aCx, JSObject* aGlobal)
    47 {
    48   return TouchEvent::PrefEnabled(aCx, aGlobal);
    49 }
    51 Touch*
    52 TouchList::IdentifiedTouch(int32_t aIdentifier) const
    53 {
    54   for (uint32_t i = 0; i < mPoints.Length(); ++i) {
    55     Touch* point = mPoints[i];
    56     if (point && point->Identifier() == aIdentifier) {
    57       return point;
    58     }
    59   }
    60   return nullptr;
    61 }
    63 /******************************************************************************
    64  * TouchEvent
    65  *****************************************************************************/
    67 TouchEvent::TouchEvent(EventTarget* aOwner,
    68                        nsPresContext* aPresContext,
    69                        WidgetTouchEvent* aEvent)
    70   : UIEvent(aOwner, aPresContext,
    71             aEvent ? aEvent : new WidgetTouchEvent(false, 0, nullptr))
    72 {
    73   if (aEvent) {
    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);
    79     }
    80   } else {
    81     mEventIsInternal = true;
    82     mEvent->time = PR_Now();
    83   }
    84 }
    86 NS_IMPL_CYCLE_COLLECTION_INHERITED(TouchEvent, UIEvent,
    87                                    mTouches,
    88                                    mTargetTouches,
    89                                    mChangedTouches)
    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)
    97 void
    98 TouchEvent::InitTouchEvent(const nsAString& aType,
    99                            bool aCanBubble,
   100                            bool aCancelable,
   101                            nsIDOMWindow* aView,
   102                            int32_t aDetail,
   103                            bool aCtrlKey,
   104                            bool aAltKey,
   105                            bool aShiftKey,
   106                            bool aMetaKey,
   107                            TouchList* aTouches,
   108                            TouchList* aTargetTouches,
   109                            TouchList* aChangedTouches,
   110                            ErrorResult& aRv)
   111 {
   112   aRv = UIEvent::InitUIEvent(aType, aCanBubble, aCancelable, aView, aDetail);
   113   if (aRv.Failed()) {
   114     return;
   115   }
   117   mEvent->AsInputEvent()->InitBasicModifiers(aCtrlKey, aAltKey,
   118                                              aShiftKey, aMetaKey);
   119   mTouches = aTouches;
   120   mTargetTouches = aTargetTouches;
   121   mChangedTouches = aChangedTouches;
   122 }
   124 TouchList*
   125 TouchEvent::Touches()
   126 {
   127   if (!mTouches) {
   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       nsTArray< nsRefPtr<Touch> > unchangedTouches;
   132       const nsTArray< nsRefPtr<Touch> >& touches = touchEvent->touches;
   133       for (uint32_t i = 0; i < touches.Length(); ++i) {
   134         if (!touches[i]->mChanged) {
   135           unchangedTouches.AppendElement(touches[i]);
   136         }
   137       }
   138       mTouches = new TouchList(ToSupports(this), unchangedTouches);
   139     } else {
   140       mTouches = new TouchList(ToSupports(this), touchEvent->touches);
   141     }
   142   }
   143   return mTouches;
   144 }
   146 TouchList*
   147 TouchEvent::TargetTouches()
   148 {
   149   if (!mTargetTouches) {
   150     nsTArray< nsRefPtr<Touch> > targetTouches;
   151     WidgetTouchEvent* touchEvent = mEvent->AsTouchEvent();
   152     const nsTArray< nsRefPtr<Touch> >& 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]);
   160         }
   161       }
   162     }
   163     mTargetTouches = new TouchList(ToSupports(this), targetTouches);
   164   }
   165   return mTargetTouches;
   166 }
   168 TouchList*
   169 TouchEvent::ChangedTouches()
   170 {
   171   if (!mChangedTouches) {
   172     nsTArray< nsRefPtr<Touch> > changedTouches;
   173     WidgetTouchEvent* touchEvent = mEvent->AsTouchEvent();
   174     const nsTArray< nsRefPtr<Touch> >& touches = touchEvent->touches;
   175     for (uint32_t i = 0; i < touches.Length(); ++i) {
   176       if (touches[i]->mChanged) {
   177         changedTouches.AppendElement(touches[i]);
   178       }
   179     }
   180     mChangedTouches = new TouchList(ToSupports(this), changedTouches);
   181   }
   182   return mChangedTouches;
   183 }
   185 // static
   186 bool
   187 TouchEvent::PrefEnabled(JSContext* aCx, JSObject* aGlobal)
   188 {
   189   bool prefValue = false;
   190   int32_t flag = 0;
   191   if (NS_SUCCEEDED(Preferences::GetInt("dom.w3c_touch_events.enabled",
   192                                         &flag))) {
   193     if (flag == 2) {
   194 #ifdef XP_WIN
   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();
   201       }
   202       prefValue = sIsTouchDeviceSupportPresent;
   203 #else
   204       NS_WARNING("dom.w3c_touch_events.enabled=2 not implemented!");
   205       prefValue = false;
   206 #endif
   207     } else {
   208       prefValue = !!flag;
   209     }
   210   }
   211   if (prefValue) {
   212     nsContentUtils::InitializeTouchEventTable();
   213   }
   214   return prefValue;
   215 }
   217 bool
   218 TouchEvent::AltKey()
   219 {
   220   return mEvent->AsTouchEvent()->IsAlt();
   221 }
   223 bool
   224 TouchEvent::MetaKey()
   225 {
   226   return mEvent->AsTouchEvent()->IsMeta();
   227 }
   229 bool
   230 TouchEvent::CtrlKey()
   231 {
   232   return mEvent->AsTouchEvent()->IsControl();
   233 }
   235 bool
   236 TouchEvent::ShiftKey()
   237 {
   238   return mEvent->AsTouchEvent()->IsShift();
   239 }
   241 } // namespace dom
   242 } // namespace mozilla
   244 using namespace mozilla;
   245 using namespace mozilla::dom;
   247 nsresult
   248 NS_NewDOMTouchEvent(nsIDOMEvent** aInstancePtrResult,
   249                     EventTarget* aOwner,
   250                     nsPresContext* aPresContext,
   251                     WidgetTouchEvent* aEvent)
   252 {
   253   TouchEvent* it = new TouchEvent(aOwner, aPresContext, aEvent);
   254   NS_ADDREF(it);
   255   *aInstancePtrResult = static_cast<Event*>(it);
   256   return NS_OK;
   257 }

mercurial