LCOV - code coverage report
Current view: top level - dom/events - Event.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 240 631 38.0 %
Date: 2017-07-14 16:53:18 Functions: 37 73 50.7 %
Legend: Lines: hit not hit

          Line data    Source code
       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 "AccessCheck.h"
       8             : #include "base/basictypes.h"
       9             : #include "ipc/IPCMessageUtils.h"
      10             : #include "mozilla/dom/Event.h"
      11             : #include "mozilla/dom/ShadowRoot.h"
      12             : #include "mozilla/ContentEvents.h"
      13             : #include "mozilla/DOMEventTargetHelper.h"
      14             : #include "mozilla/EventStateManager.h"
      15             : #include "mozilla/InternalMutationEvent.h"
      16             : #include "mozilla/dom/Performance.h"
      17             : #include "mozilla/MiscEvents.h"
      18             : #include "mozilla/MouseEvents.h"
      19             : #include "mozilla/Preferences.h"
      20             : #include "mozilla/TextEvents.h"
      21             : #include "mozilla/TouchEvents.h"
      22             : #include "nsContentUtils.h"
      23             : #include "nsCOMPtr.h"
      24             : #include "nsDeviceContext.h"
      25             : #include "nsError.h"
      26             : #include "nsGlobalWindow.h"
      27             : #include "nsIFrame.h"
      28             : #include "nsIContent.h"
      29             : #include "nsIDocument.h"
      30             : #include "nsIPresShell.h"
      31             : #include "nsIScrollableFrame.h"
      32             : #include "nsJSEnvironment.h"
      33             : #include "nsLayoutUtils.h"
      34             : #include "nsPIWindowRoot.h"
      35             : #include "nsRFPService.h"
      36             : #include "WorkerPrivate.h"
      37             : 
      38             : namespace mozilla {
      39             : namespace dom {
      40             : 
      41             : static char *sPopupAllowedEvents;
      42             : 
      43             : static bool sReturnHighResTimeStamp = false;
      44             : static bool sReturnHighResTimeStampIsSet = false;
      45             : 
      46         366 : Event::Event(EventTarget* aOwner,
      47             :              nsPresContext* aPresContext,
      48         366 :              WidgetEvent* aEvent)
      49             : {
      50         366 :   ConstructorInit(aOwner, aPresContext, aEvent);
      51         366 : }
      52             : 
      53           0 : Event::Event(nsPIDOMWindowInner* aParent)
      54             : {
      55           0 :   ConstructorInit(nsGlobalWindow::Cast(aParent), nullptr, nullptr);
      56           0 : }
      57             : 
      58             : void
      59         366 : Event::ConstructorInit(EventTarget* aOwner,
      60             :                        nsPresContext* aPresContext,
      61             :                        WidgetEvent* aEvent)
      62             : {
      63         366 :   SetOwner(aOwner);
      64         366 :   mIsMainThreadEvent = NS_IsMainThread();
      65             : 
      66         366 :   if (mIsMainThreadEvent && !sReturnHighResTimeStampIsSet) {
      67           2 :     Preferences::AddBoolVarCache(&sReturnHighResTimeStamp,
      68             :                                  "dom.event.highrestimestamp.enabled",
      69           2 :                                  sReturnHighResTimeStamp);
      70           2 :     sReturnHighResTimeStampIsSet = true;
      71             :   }
      72             : 
      73         366 :   mPrivateDataDuplicated = false;
      74         366 :   mWantsPopupControlCheck = false;
      75             : 
      76         366 :   if (aEvent) {
      77          31 :     mEvent = aEvent;
      78          31 :     mEventIsInternal = false;
      79             :   }
      80             :   else {
      81         335 :     mEventIsInternal = true;
      82             :     /*
      83             :       A derived class might want to allocate its own type of aEvent
      84             :       (derived from WidgetEvent). To do this, it should take care to pass
      85             :       a non-nullptr aEvent to this ctor, e.g.:
      86             : 
      87             :         FooEvent::FooEvent(..., WidgetEvent* aEvent)
      88             :           : Event(..., aEvent ? aEvent : new WidgetEvent())
      89             : 
      90             :       Then, to override the mEventIsInternal assignments done by the
      91             :       base ctor, it should do this in its own ctor:
      92             : 
      93             :         FooEvent::FooEvent(..., WidgetEvent* aEvent)
      94             :         ...
      95             :         {
      96             :           ...
      97             :           if (aEvent) {
      98             :             mEventIsInternal = false;
      99             :           }
     100             :           else {
     101             :             mEventIsInternal = true;
     102             :           }
     103             :           ...
     104             :         }
     105             :      */
     106         335 :     mEvent = new WidgetEvent(false, eVoidEvent);
     107         335 :     mEvent->mTime = PR_Now();
     108             :   }
     109             : 
     110         366 :   InitPresContextData(aPresContext);
     111         366 : }
     112             : 
     113             : void
     114         375 : Event::InitPresContextData(nsPresContext* aPresContext)
     115             : {
     116         375 :   mPresContext = aPresContext;
     117             :   // Get the explicit original target (if it's anonymous make it null)
     118             :   {
     119         750 :     nsCOMPtr<nsIContent> content = GetTargetFromFrame();
     120         375 :     mExplicitOriginalTarget = content;
     121         375 :     if (content && content->IsInAnonymousSubtree()) {
     122           4 :       mExplicitOriginalTarget = nullptr;
     123             :     }
     124             :   }
     125         375 : }
     126             : 
     127         738 : Event::~Event()
     128             : {
     129         260 :   NS_ASSERT_OWNINGTHREAD(Event);
     130             : 
     131         260 :   if (mEventIsInternal && mEvent) {
     132         258 :     delete mEvent;
     133             :   }
     134         696 : }
     135             : 
     136        2510 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Event)
     137         354 :   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
     138         269 :   NS_INTERFACE_MAP_ENTRY(nsISupports)
     139         269 :   NS_INTERFACE_MAP_ENTRY(nsIDOMEvent)
     140           0 : NS_INTERFACE_MAP_END
     141             : 
     142         701 : NS_IMPL_CYCLE_COLLECTING_ADDREF(Event)
     143         903 : NS_IMPL_CYCLE_COLLECTING_RELEASE(Event)
     144             : 
     145             : NS_IMPL_CYCLE_COLLECTION_CLASS(Event)
     146             : 
     147         350 : NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Event)
     148         350 :   NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
     149         350 : NS_IMPL_CYCLE_COLLECTION_TRACE_END
     150             : 
     151           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Event)
     152           0 :   if (tmp->mEventIsInternal) {
     153           0 :     tmp->mEvent->mTarget = nullptr;
     154           0 :     tmp->mEvent->mCurrentTarget = nullptr;
     155           0 :     tmp->mEvent->mOriginalTarget = nullptr;
     156           0 :     switch (tmp->mEvent->mClass) {
     157             :       case eMouseEventClass:
     158             :       case eMouseScrollEventClass:
     159             :       case eWheelEventClass:
     160             :       case eSimpleGestureEventClass:
     161             :       case ePointerEventClass:
     162           0 :         tmp->mEvent->AsMouseEventBase()->relatedTarget = nullptr;
     163           0 :         break;
     164             :       case eDragEventClass: {
     165           0 :         WidgetDragEvent* dragEvent = tmp->mEvent->AsDragEvent();
     166           0 :         dragEvent->mDataTransfer = nullptr;
     167           0 :         dragEvent->relatedTarget = nullptr;
     168           0 :         break;
     169             :       }
     170             :       case eClipboardEventClass:
     171           0 :         tmp->mEvent->AsClipboardEvent()->mClipboardData = nullptr;
     172           0 :         break;
     173             :       case eMutationEventClass:
     174           0 :         tmp->mEvent->AsMutationEvent()->mRelatedNode = nullptr;
     175           0 :         break;
     176             :       case eFocusEventClass:
     177           0 :         tmp->mEvent->AsFocusEvent()->mRelatedTarget = nullptr;
     178           0 :         break;
     179             :       default:
     180           0 :         break;
     181             :     }
     182             :   }
     183           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mPresContext);
     184           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mExplicitOriginalTarget);
     185           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner);
     186           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
     187           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     188             : 
     189          44 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Event)
     190          44 :   if (tmp->mEventIsInternal) {
     191          20 :     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvent->mTarget)
     192          20 :     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvent->mCurrentTarget)
     193          20 :     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvent->mOriginalTarget)
     194          20 :     switch (tmp->mEvent->mClass) {
     195             :       case eMouseEventClass:
     196             :       case eMouseScrollEventClass:
     197             :       case eWheelEventClass:
     198             :       case eSimpleGestureEventClass:
     199             :       case ePointerEventClass:
     200           0 :         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvent->relatedTarget");
     201           0 :         cb.NoteXPCOMChild(tmp->mEvent->AsMouseEventBase()->relatedTarget);
     202           0 :         break;
     203             :       case eDragEventClass: {
     204           0 :         WidgetDragEvent* dragEvent = tmp->mEvent->AsDragEvent();
     205           0 :         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvent->mDataTransfer");
     206           0 :         cb.NoteXPCOMChild(dragEvent->mDataTransfer);
     207           0 :         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvent->relatedTarget");
     208           0 :         cb.NoteXPCOMChild(dragEvent->relatedTarget);
     209           0 :         break;
     210             :       }
     211             :       case eClipboardEventClass:
     212           0 :         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvent->mClipboardData");
     213           0 :         cb.NoteXPCOMChild(tmp->mEvent->AsClipboardEvent()->mClipboardData);
     214           0 :         break;
     215             :       case eMutationEventClass:
     216           0 :         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvent->mRelatedNode");
     217           0 :         cb.NoteXPCOMChild(tmp->mEvent->AsMutationEvent()->mRelatedNode);
     218           0 :         break;
     219             :       case eFocusEventClass:
     220           0 :         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvent->mRelatedTarget");
     221           0 :         cb.NoteXPCOMChild(tmp->mEvent->AsFocusEvent()->mRelatedTarget);
     222           0 :         break;
     223             :       default:
     224          20 :         break;
     225             :     }
     226             :   }
     227          44 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPresContext)
     228          44 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExplicitOriginalTarget)
     229          44 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
     230          44 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     231             : 
     232             : 
     233             : JSObject*
     234          56 : Event::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
     235             : {
     236          56 :   return WrapObjectInternal(aCx, aGivenProto);
     237             : }
     238             : 
     239             : JSObject*
     240          27 : Event::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
     241             : {
     242          27 :   return EventBinding::Wrap(aCx, this, aGivenProto);
     243             : }
     244             : 
     245             : // nsIDOMEventInterface
     246             : NS_IMETHODIMP
     247          92 : Event::GetType(nsAString& aType)
     248             : {
     249          92 :   if (!mIsMainThreadEvent) {
     250           0 :     aType = mEvent->mSpecifiedEventTypeString;
     251           0 :     return NS_OK;
     252             :   }
     253          92 :   GetWidgetEventType(mEvent, aType);
     254          92 :   return NS_OK;
     255             : }
     256             : 
     257             : EventTarget*
     258          45 : Event::GetTarget() const
     259             : {
     260          45 :   return mEvent->GetDOMEventTarget();
     261             : }
     262             : 
     263             : NS_IMETHODIMP
     264          18 : Event::GetTarget(nsIDOMEventTarget** aTarget)
     265             : {
     266          18 :   NS_IF_ADDREF(*aTarget = GetTarget());
     267          18 :   return NS_OK;
     268             : }
     269             : 
     270             : EventTarget*
     271          30 : Event::GetCurrentTarget() const
     272             : {
     273          30 :   return mEvent->GetCurrentDOMEventTarget();
     274             : }
     275             : 
     276             : NS_IMETHODIMP
     277           0 : Event::GetCurrentTarget(nsIDOMEventTarget** aCurrentTarget)
     278             : {
     279           0 :   NS_IF_ADDREF(*aCurrentTarget = GetCurrentTarget());
     280           0 :   return NS_OK;
     281             : }
     282             : 
     283             : //
     284             : // Get the actual event target node (may have been retargeted for mouse events)
     285             : //
     286             : already_AddRefed<nsIContent>
     287         375 : Event::GetTargetFromFrame()
     288             : {
     289         375 :   if (!mPresContext) { return nullptr; }
     290             : 
     291             :   // Get the mTarget frame (have to get the ESM first)
     292         183 :   nsIFrame* targetFrame = mPresContext->EventStateManager()->GetEventTarget();
     293         183 :   if (!targetFrame) { return nullptr; }
     294             : 
     295             :   // get the real content
     296          10 :   nsCOMPtr<nsIContent> realEventContent;
     297           5 :   targetFrame->GetContentForEvent(mEvent, getter_AddRefs(realEventContent));
     298           5 :   return realEventContent.forget();
     299             : }
     300             : 
     301             : EventTarget*
     302           0 : Event::GetExplicitOriginalTarget() const
     303             : {
     304           0 :   if (mExplicitOriginalTarget) {
     305           0 :     return mExplicitOriginalTarget;
     306             :   }
     307           0 :   return GetTarget();
     308             : }
     309             : 
     310             : NS_IMETHODIMP
     311           0 : Event::GetExplicitOriginalTarget(nsIDOMEventTarget** aRealEventTarget)
     312             : {
     313           0 :   NS_IF_ADDREF(*aRealEventTarget = GetExplicitOriginalTarget());
     314           0 :   return NS_OK;
     315             : }
     316             : 
     317             : EventTarget*
     318           7 : Event::GetOriginalTarget() const
     319             : {
     320           7 :   return mEvent->GetOriginalDOMEventTarget();
     321             : }
     322             : 
     323             : NS_IMETHODIMP
     324           0 : Event::GetOriginalTarget(nsIDOMEventTarget** aOriginalTarget)
     325             : {
     326           0 :   NS_IF_ADDREF(*aOriginalTarget = GetOriginalTarget());
     327           0 :   return NS_OK;
     328             : }
     329             : 
     330             : EventTarget*
     331           0 : Event::GetComposedTarget() const
     332             : {
     333           0 :   EventTarget* et = GetOriginalTarget();
     334           0 :   nsCOMPtr<nsIContent> content = do_QueryInterface(et);
     335           0 :   if (!content) {
     336           0 :     return et;
     337             :   }
     338           0 :   nsIContent* nonChrome = content->FindFirstNonChromeOnlyAccessContent();
     339           0 :   return nonChrome ?
     340             :     static_cast<EventTarget*>(nonChrome) :
     341           0 :     static_cast<EventTarget*>(content->GetComposedDoc());
     342             : }
     343             : 
     344             : NS_IMETHODIMP_(void)
     345         365 : Event::SetTrusted(bool aTrusted)
     346             : {
     347         365 :   mEvent->mFlags.mIsTrusted = aTrusted;
     348         365 : }
     349             : 
     350             : bool
     351          36 : Event::Init(mozilla::dom::EventTarget* aGlobal)
     352             : {
     353          36 :   if (!mIsMainThreadEvent) {
     354           8 :     return workers::IsCurrentThreadRunningChromeWorker();
     355             :   }
     356          28 :   bool trusted = false;
     357          56 :   nsCOMPtr<nsPIDOMWindowInner> w = do_QueryInterface(aGlobal);
     358          28 :   if (w) {
     359          18 :     nsCOMPtr<nsIDocument> d = w->GetExtantDoc();
     360           9 :     if (d) {
     361           9 :       trusted = nsContentUtils::IsChromeDoc(d);
     362           9 :       nsIPresShell* s = d->GetShell();
     363           9 :       if (s) {
     364           9 :         InitPresContextData(s->GetPresContext());
     365             :       }
     366             :     }
     367             :   }
     368          28 :   return trusted;
     369             : }
     370             : 
     371             : // static
     372             : already_AddRefed<Event>
     373           0 : Event::Constructor(const GlobalObject& aGlobal,
     374             :                    const nsAString& aType,
     375             :                    const EventInit& aParam,
     376             :                    ErrorResult& aRv)
     377             : {
     378           0 :   nsCOMPtr<mozilla::dom::EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports());
     379           0 :   return Constructor(t, aType, aParam);
     380             : }
     381             : 
     382             : // static
     383             : already_AddRefed<Event>
     384           0 : Event::Constructor(EventTarget* aEventTarget,
     385             :                    const nsAString& aType,
     386             :                    const EventInit& aParam)
     387             : {
     388           0 :   RefPtr<Event> e = new Event(aEventTarget, nullptr, nullptr);
     389           0 :   bool trusted = e->Init(aEventTarget);
     390           0 :   e->InitEvent(aType, aParam.mBubbles, aParam.mCancelable);
     391           0 :   e->SetTrusted(trusted);
     392           0 :   e->SetComposed(aParam.mComposed);
     393           0 :   return e.forget();
     394             : }
     395             : 
     396             : uint16_t
     397           0 : Event::EventPhase() const
     398             : {
     399             :   // Note, remember to check that this works also
     400             :   // if or when Bug 235441 is fixed.
     401           0 :   if ((mEvent->mCurrentTarget &&
     402           0 :        mEvent->mCurrentTarget == mEvent->mTarget) ||
     403           0 :        mEvent->mFlags.InTargetPhase()) {
     404           0 :     return nsIDOMEvent::AT_TARGET;
     405             :   }
     406           0 :   if (mEvent->mFlags.mInCapturePhase) {
     407           0 :     return nsIDOMEvent::CAPTURING_PHASE;
     408             :   }
     409           0 :   if (mEvent->mFlags.mInBubblingPhase) {
     410           0 :     return nsIDOMEvent::BUBBLING_PHASE;
     411             :   }
     412           0 :   return nsIDOMEvent::NONE;
     413             : }
     414             : 
     415             : NS_IMETHODIMP
     416           0 : Event::GetEventPhase(uint16_t* aEventPhase)
     417             : {
     418           0 :   *aEventPhase = EventPhase();
     419           0 :   return NS_OK;
     420             : }
     421             : 
     422             : NS_IMETHODIMP
     423           0 : Event::GetBubbles(bool* aBubbles)
     424             : {
     425           0 :   *aBubbles = Bubbles();
     426           0 :   return NS_OK;
     427             : }
     428             : 
     429             : NS_IMETHODIMP
     430           0 : Event::GetCancelable(bool* aCancelable)
     431             : {
     432           0 :   *aCancelable = Cancelable();
     433           0 :   return NS_OK;
     434             : }
     435             : 
     436             : NS_IMETHODIMP
     437           0 : Event::GetTimeStamp(uint64_t* aTimeStamp)
     438             : {
     439           0 :   *aTimeStamp = mEvent->mTime;
     440           0 :   return NS_OK;
     441             : }
     442             : 
     443             : NS_IMETHODIMP
     444           0 : Event::StopPropagation()
     445             : {
     446           0 :   mEvent->StopPropagation();
     447           0 :   return NS_OK;
     448             : }
     449             : 
     450             : NS_IMETHODIMP
     451           0 : Event::StopImmediatePropagation()
     452             : {
     453           0 :   mEvent->StopImmediatePropagation();
     454           0 :   return NS_OK;
     455             : }
     456             : 
     457             : NS_IMETHODIMP
     458           0 : Event::StopCrossProcessForwarding()
     459             : {
     460           0 :   mEvent->StopCrossProcessForwarding();
     461           0 :   return NS_OK;
     462             : }
     463             : 
     464             : NS_IMETHODIMP
     465         290 : Event::GetIsTrusted(bool* aIsTrusted)
     466             : {
     467         290 :   *aIsTrusted = IsTrusted();
     468         290 :   return NS_OK;
     469             : }
     470             : 
     471             : NS_IMETHODIMP
     472           0 : Event::PreventDefault()
     473             : {
     474             :   // This method is called only from C++ code which must handle default action
     475             :   // of this event.  So, pass true always.
     476           0 :   PreventDefaultInternal(true);
     477           0 :   return NS_OK;
     478             : }
     479             : 
     480             : void
     481           0 : Event::PreventDefault(JSContext* aCx, CallerType aCallerType)
     482             : {
     483             :   // Note that at handling default action, another event may be dispatched.
     484             :   // Then, JS in content mey be call preventDefault()
     485             :   // even in the event is in system event group.  Therefore, don't refer
     486             :   // mInSystemGroup here.
     487           0 :   PreventDefaultInternal(aCallerType == CallerType::System);
     488           0 : }
     489             : 
     490             : void
     491           0 : Event::PreventDefaultInternal(bool aCalledByDefaultHandler)
     492             : {
     493           0 :   if (!mEvent->mFlags.mCancelable) {
     494           0 :     return;
     495             :   }
     496           0 :   if (mEvent->mFlags.mInPassiveListener) {
     497           0 :     nsCOMPtr<nsPIDOMWindowInner> win(do_QueryInterface(mOwner));
     498           0 :     if (win) {
     499           0 :       if (nsIDocument* doc = win->GetExtantDoc()) {
     500           0 :         nsString type;
     501           0 :         GetType(type);
     502           0 :         const char16_t* params[] = { type.get() };
     503           0 :         doc->WarnOnceAbout(nsIDocument::ePreventDefaultFromPassiveListener,
     504           0 :           false, params, ArrayLength(params));
     505             :       }
     506             :     }
     507           0 :     return;
     508             :   }
     509             : 
     510           0 :   mEvent->PreventDefault(aCalledByDefaultHandler);
     511             : 
     512           0 :   if (!IsTrusted()) {
     513           0 :     return;
     514             :   }
     515             : 
     516           0 :   WidgetDragEvent* dragEvent = mEvent->AsDragEvent();
     517           0 :   if (!dragEvent) {
     518           0 :     return;
     519             :   }
     520             : 
     521           0 :   nsCOMPtr<nsINode> node = do_QueryInterface(mEvent->mCurrentTarget);
     522           0 :   if (!node) {
     523             :     nsCOMPtr<nsPIDOMWindowOuter> win =
     524           0 :       do_QueryInterface(mEvent->mCurrentTarget);
     525           0 :     if (!win) {
     526           0 :       return;
     527             :     }
     528           0 :     node = win->GetExtantDoc();
     529             :   }
     530           0 :   if (!nsContentUtils::IsChromeDoc(node->OwnerDoc())) {
     531           0 :     dragEvent->mDefaultPreventedOnContent = true;
     532             :   }
     533             : }
     534             : 
     535             : void
     536         310 : Event::SetEventType(const nsAString& aEventTypeArg)
     537             : {
     538         310 :   if (mIsMainThreadEvent) {
     539         293 :     mEvent->mSpecifiedEventTypeString.Truncate();
     540         293 :     mEvent->mSpecifiedEventType =
     541         293 :       nsContentUtils::GetEventMessageAndAtom(aEventTypeArg, mEvent->mClass,
     542         879 :                                              &(mEvent->mMessage));
     543         293 :     mEvent->SetDefaultComposed();
     544             :   } else {
     545          17 :     mEvent->mSpecifiedEventType = nullptr;
     546          17 :     mEvent->mMessage = eUnidentifiedEvent;
     547          17 :     mEvent->mSpecifiedEventTypeString = aEventTypeArg;
     548          17 :     mEvent->SetComposed(aEventTypeArg);
     549             :   }
     550         310 :   mEvent->SetDefaultComposedInNativeAnonymousContent();
     551         310 : }
     552             : 
     553             : already_AddRefed<EventTarget>
     554           0 : Event::EnsureWebAccessibleRelatedTarget(EventTarget* aRelatedTarget)
     555             : {
     556           0 :   nsCOMPtr<EventTarget> relatedTarget = aRelatedTarget;
     557           0 :   if (relatedTarget) {
     558           0 :     nsCOMPtr<nsIContent> content = do_QueryInterface(relatedTarget);
     559             :     nsCOMPtr<nsIContent> currentTarget =
     560           0 :       do_QueryInterface(mEvent->mCurrentTarget);
     561             : 
     562           0 :     if (content && content->ChromeOnlyAccess() &&
     563           0 :         !nsContentUtils::CanAccessNativeAnon()) {
     564           0 :       content = content->FindFirstNonChromeOnlyAccessContent();
     565           0 :       relatedTarget = do_QueryInterface(content);
     566             :     }
     567             : 
     568             :     nsIContent* shadowRelatedTarget =
     569           0 :       GetShadowRelatedTarget(currentTarget, content);
     570           0 :     if (shadowRelatedTarget) {
     571           0 :       relatedTarget = shadowRelatedTarget;
     572             :     }
     573             : 
     574           0 :     if (relatedTarget) {
     575           0 :       relatedTarget = relatedTarget->GetTargetForDOMEvent();
     576             :     }
     577             :   }
     578           0 :   return relatedTarget.forget();
     579             : }
     580             : 
     581             : void
     582         310 : Event::InitEvent(const nsAString& aEventTypeArg,
     583             :                  bool aCanBubbleArg,
     584             :                  bool aCancelableArg)
     585             : {
     586             :   // Make sure this event isn't already being dispatched.
     587         310 :   NS_ENSURE_TRUE_VOID(!mEvent->mFlags.mIsBeingDispatched);
     588             : 
     589         310 :   if (IsTrusted()) {
     590             :     // Ensure the caller is permitted to dispatch trusted DOM events.
     591           0 :     if (!nsContentUtils::ThreadsafeIsCallerChrome()) {
     592           0 :       SetTrusted(false);
     593             :     }
     594             :   }
     595             : 
     596         310 :   SetEventType(aEventTypeArg);
     597             : 
     598         310 :   mEvent->mFlags.mBubbles = aCanBubbleArg;
     599         310 :   mEvent->mFlags.mCancelable = aCancelableArg;
     600             : 
     601         310 :   mEvent->mFlags.mDefaultPrevented = false;
     602         310 :   mEvent->mFlags.mDefaultPreventedByContent = false;
     603         310 :   mEvent->mFlags.mDefaultPreventedByChrome = false;
     604         310 :   mEvent->mFlags.mPropagationStopped = false;
     605         310 :   mEvent->mFlags.mImmediatePropagationStopped = false;
     606             : 
     607             :   // Clearing the old targets, so that the event is targeted correctly when
     608             :   // re-dispatching it.
     609         310 :   mEvent->mTarget = nullptr;
     610         310 :   mEvent->mOriginalTarget = nullptr;
     611             : }
     612             : 
     613             : NS_IMETHODIMP
     614          25 : Event::DuplicatePrivateData()
     615             : {
     616          25 :   NS_ASSERTION(mEvent, "No WidgetEvent for Event duplication!");
     617          25 :   if (mEventIsInternal) {
     618           0 :     return NS_OK;
     619             :   }
     620             : 
     621          25 :   mEvent = mEvent->Duplicate();
     622          25 :   mPresContext = nullptr;
     623          25 :   mEventIsInternal = true;
     624          25 :   mPrivateDataDuplicated = true;
     625             : 
     626          25 :   return NS_OK;
     627             : }
     628             : 
     629             : NS_IMETHODIMP
     630         163 : Event::SetTarget(nsIDOMEventTarget* aTarget)
     631             : {
     632         163 :   mEvent->mTarget = do_QueryInterface(aTarget);
     633         163 :   return NS_OK;
     634             : }
     635             : 
     636             : NS_IMETHODIMP_(bool)
     637           0 : Event::IsDispatchStopped()
     638             : {
     639           0 :   return mEvent->PropagationStopped();
     640             : }
     641             : 
     642             : NS_IMETHODIMP_(WidgetEvent*)
     643         774 : Event::WidgetEventPtr()
     644             : {
     645         774 :   return mEvent;
     646             : }
     647             : 
     648             : NS_IMETHODIMP_(Event*)
     649         603 : Event::InternalDOMEvent()
     650             : {
     651         603 :   return this;
     652             : }
     653             : 
     654             : // return true if eventName is contained within events, delimited by
     655             : // spaces
     656             : static bool
     657           0 : PopupAllowedForEvent(const char *eventName)
     658             : {
     659           0 :   if (!sPopupAllowedEvents) {
     660           0 :     Event::PopupAllowedEventsChanged();
     661             : 
     662           0 :     if (!sPopupAllowedEvents) {
     663           0 :       return false;
     664             :     }
     665             :   }
     666             : 
     667           0 :   nsDependentCString events(sPopupAllowedEvents);
     668             : 
     669           0 :   nsCString::const_iterator start, end;
     670           0 :   nsCString::const_iterator startiter(events.BeginReading(start));
     671           0 :   events.EndReading(end);
     672             : 
     673           0 :   while (startiter != end) {
     674           0 :     nsCString::const_iterator enditer(end);
     675             : 
     676           0 :     if (!FindInReadable(nsDependentCString(eventName), startiter, enditer))
     677           0 :       return false;
     678             : 
     679             :     // the match is surrounded by spaces, or at a string boundary
     680           0 :     if ((startiter == start || *--startiter == ' ') &&
     681           0 :         (enditer == end || *enditer == ' ')) {
     682           0 :       return true;
     683             :     }
     684             : 
     685             :     // Move on and see if there are other matches. (The delimitation
     686             :     // requirement makes it pointless to begin the next search before
     687             :     // the end of the invalid match just found.)
     688           0 :     startiter = enditer;
     689             :   }
     690             : 
     691           0 :   return false;
     692             : }
     693             : 
     694             : // static
     695             : PopupControlState
     696         810 : Event::GetEventPopupControlState(WidgetEvent* aEvent, nsIDOMEvent* aDOMEvent)
     697             : {
     698             :   // generally if an event handler is running, new windows are disallowed.
     699             :   // check for exceptions:
     700         810 :   PopupControlState abuse = openAbused;
     701             : 
     702         810 :   if (aDOMEvent && aDOMEvent->InternalDOMEvent()->GetWantsPopupControlCheck()) {
     703           0 :     nsAutoString type;
     704           0 :     aDOMEvent->GetType(type);
     705           0 :     if (PopupAllowedForEvent(NS_ConvertUTF16toUTF8(type).get())) {
     706           0 :       return openAllowed;
     707             :     }
     708             :   }
     709             : 
     710         810 :   switch(aEvent->mClass) {
     711             :   case eBasicEventClass:
     712             :     // For these following events only allow popups if they're
     713             :     // triggered while handling user input. See
     714             :     // nsPresShell::HandleEventInternal() for details.
     715         576 :     if (EventStateManager::IsHandlingUserInput()) {
     716           0 :       switch(aEvent->mMessage) {
     717             :       case eFormSelect:
     718           0 :         if (PopupAllowedForEvent("select")) {
     719           0 :           abuse = openControlled;
     720             :         }
     721           0 :         break;
     722             :       case eFormChange:
     723           0 :         if (PopupAllowedForEvent("change")) {
     724           0 :           abuse = openControlled;
     725             :         }
     726           0 :         break;
     727             :       default:
     728           0 :         break;
     729             :       }
     730             :     }
     731         576 :     break;
     732             :   case eEditorInputEventClass:
     733             :     // For this following event only allow popups if it's triggered
     734             :     // while handling user input. See
     735             :     // nsPresShell::HandleEventInternal() for details.
     736           0 :     if (EventStateManager::IsHandlingUserInput()) {
     737           0 :       switch(aEvent->mMessage) {
     738             :       case eEditorInput:
     739           0 :         if (PopupAllowedForEvent("input")) {
     740           0 :           abuse = openControlled;
     741             :         }
     742           0 :         break;
     743             :       default:
     744           0 :         break;
     745             :       }
     746             :     }
     747           0 :     break;
     748             :   case eInputEventClass:
     749             :     // For this following event only allow popups if it's triggered
     750             :     // while handling user input. See
     751             :     // nsPresShell::HandleEventInternal() for details.
     752           0 :     if (EventStateManager::IsHandlingUserInput()) {
     753           0 :       switch(aEvent->mMessage) {
     754             :       case eFormChange:
     755           0 :         if (PopupAllowedForEvent("change")) {
     756           0 :           abuse = openControlled;
     757             :         }
     758           0 :         break;
     759             :       case eXULCommand:
     760           0 :         abuse = openControlled;
     761           0 :         break;
     762             :       default:
     763           0 :         break;
     764             :       }
     765             :     }
     766           0 :     break;
     767             :   case eKeyboardEventClass:
     768           0 :     if (aEvent->IsTrusted()) {
     769           0 :       uint32_t key = aEvent->AsKeyboardEvent()->mKeyCode;
     770           0 :       switch(aEvent->mMessage) {
     771             :       case eKeyPress:
     772             :         // return key on focused button. see note at eMouseClick.
     773           0 :         if (key == NS_VK_RETURN) {
     774           0 :           abuse = openAllowed;
     775           0 :         } else if (PopupAllowedForEvent("keypress")) {
     776           0 :           abuse = openControlled;
     777             :         }
     778           0 :         break;
     779             :       case eKeyUp:
     780             :         // space key on focused button. see note at eMouseClick.
     781           0 :         if (key == NS_VK_SPACE) {
     782           0 :           abuse = openAllowed;
     783           0 :         } else if (PopupAllowedForEvent("keyup")) {
     784           0 :           abuse = openControlled;
     785             :         }
     786           0 :         break;
     787             :       case eKeyDown:
     788           0 :         if (PopupAllowedForEvent("keydown")) {
     789           0 :           abuse = openControlled;
     790             :         }
     791           0 :         break;
     792             :       default:
     793           0 :         break;
     794             :       }
     795             :     }
     796           0 :     break;
     797             :   case eTouchEventClass:
     798           0 :     if (aEvent->IsTrusted()) {
     799           0 :       switch (aEvent->mMessage) {
     800             :       case eTouchStart:
     801           0 :         if (PopupAllowedForEvent("touchstart")) {
     802           0 :           abuse = openControlled;
     803             :         }
     804           0 :         break;
     805             :       case eTouchEnd:
     806           0 :         if (PopupAllowedForEvent("touchend")) {
     807           0 :           abuse = openControlled;
     808             :         }
     809           0 :         break;
     810             :       default:
     811           0 :         break;
     812             :       }
     813             :     }
     814           0 :     break;
     815             :   case eMouseEventClass:
     816         134 :     if (aEvent->IsTrusted() &&
     817          67 :         aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) {
     818          67 :       switch(aEvent->mMessage) {
     819             :       case eMouseUp:
     820           0 :         if (PopupAllowedForEvent("mouseup")) {
     821           0 :           abuse = openControlled;
     822             :         }
     823           0 :         break;
     824             :       case eMouseDown:
     825           0 :         if (PopupAllowedForEvent("mousedown")) {
     826           0 :           abuse = openControlled;
     827             :         }
     828           0 :         break;
     829             :       case eMouseClick:
     830             :         /* Click events get special treatment because of their
     831             :            historical status as a more legitimate event handler. If
     832             :            click popups are enabled in the prefs, clear the popup
     833             :            status completely. */
     834           0 :         if (PopupAllowedForEvent("click")) {
     835           0 :           abuse = openAllowed;
     836             :         }
     837           0 :         break;
     838             :       case eMouseDoubleClick:
     839           0 :         if (PopupAllowedForEvent("dblclick")) {
     840           0 :           abuse = openControlled;
     841             :         }
     842           0 :         break;
     843             :       default:
     844          67 :         break;
     845             :       }
     846             :     }
     847          67 :     break;
     848             :   case ePointerEventClass:
     849          84 :     if (aEvent->IsTrusted() &&
     850          42 :         aEvent->AsPointerEvent()->button == WidgetMouseEvent::eLeftButton) {
     851           7 :       switch(aEvent->mMessage) {
     852             :       case ePointerUp:
     853           0 :         if (PopupAllowedForEvent("pointerup")) {
     854           0 :           abuse = openControlled;
     855             :         }
     856           0 :         break;
     857             :       case ePointerDown:
     858           0 :         if (PopupAllowedForEvent("pointerdown")) {
     859           0 :           abuse = openControlled;
     860             :         }
     861           0 :         break;
     862             :       default:
     863           7 :         break;
     864             :       }
     865             :     }
     866          42 :     break;
     867             :   case eFormEventClass:
     868             :     // For these following events only allow popups if they're
     869             :     // triggered while handling user input. See
     870             :     // nsPresShell::HandleEventInternal() for details.
     871           0 :     if (EventStateManager::IsHandlingUserInput()) {
     872           0 :       switch(aEvent->mMessage) {
     873             :       case eFormSubmit:
     874           0 :         if (PopupAllowedForEvent("submit")) {
     875           0 :           abuse = openControlled;
     876             :         }
     877           0 :         break;
     878             :       case eFormReset:
     879           0 :         if (PopupAllowedForEvent("reset")) {
     880           0 :           abuse = openControlled;
     881             :         }
     882           0 :         break;
     883             :       default:
     884           0 :         break;
     885             :       }
     886             :     }
     887           0 :     break;
     888             :   default:
     889         125 :     break;
     890             :   }
     891             : 
     892         810 :   return abuse;
     893             : }
     894             : 
     895             : // static
     896             : void
     897           0 : Event::PopupAllowedEventsChanged()
     898             : {
     899           0 :   if (sPopupAllowedEvents) {
     900           0 :     free(sPopupAllowedEvents);
     901             :   }
     902             : 
     903           0 :   nsAdoptingCString str = Preferences::GetCString("dom.popup_allowed_events");
     904             : 
     905             :   // We'll want to do this even if str is empty to avoid looking up
     906             :   // this pref all the time if it's not set.
     907           0 :   sPopupAllowedEvents = ToNewCString(str);
     908           0 : }
     909             : 
     910             : // static
     911             : void
     912           0 : Event::Shutdown()
     913             : {
     914           0 :   if (sPopupAllowedEvents) {
     915           0 :     free(sPopupAllowedEvents);
     916             :   }
     917           0 : }
     918             : 
     919             : // static
     920             : CSSIntPoint
     921          38 : Event::GetScreenCoords(nsPresContext* aPresContext,
     922             :                        WidgetEvent* aEvent,
     923             :                        LayoutDeviceIntPoint aPoint)
     924             : {
     925          38 :   if (EventStateManager::sIsPointerLocked) {
     926           0 :     return EventStateManager::sLastScreenPoint;
     927             :   }
     928             : 
     929          76 :   if (!aEvent ||
     930          50 :        (aEvent->mClass != eMouseEventClass &&
     931          24 :         aEvent->mClass != eMouseScrollEventClass &&
     932          24 :         aEvent->mClass != eWheelEventClass &&
     933          20 :         aEvent->mClass != ePointerEventClass &&
     934          16 :         aEvent->mClass != eTouchEventClass &&
     935          16 :         aEvent->mClass != eDragEventClass &&
     936           8 :         aEvent->mClass != eSimpleGestureEventClass)) {
     937           8 :     return CSSIntPoint(0, 0);
     938             :   }
     939             : 
     940             :   // Doing a straight conversion from LayoutDeviceIntPoint to CSSIntPoint
     941             :   // seem incorrect, but it is needed to maintain legacy functionality.
     942          30 :   WidgetGUIEvent* guiEvent = aEvent->AsGUIEvent();
     943          30 :   if (!aPresContext || !(guiEvent && guiEvent->mWidget)) {
     944           0 :     return CSSIntPoint(aPoint.x, aPoint.y);
     945             :   }
     946             : 
     947             :   nsPoint pt =
     948          30 :     LayoutDevicePixel::ToAppUnits(aPoint, aPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom());
     949             : 
     950          30 :   if (nsIPresShell* ps = aPresContext->GetPresShell()) {
     951          30 :     pt = pt.RemoveResolution(nsLayoutUtils::GetCurrentAPZResolutionScale(ps));
     952             :   }
     953             : 
     954          60 :   pt += LayoutDevicePixel::ToAppUnits(guiEvent->mWidget->WidgetToScreenOffset(),
     955          30 :                                       aPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom());
     956             : 
     957          30 :   return CSSPixel::FromAppUnitsRounded(pt);
     958             : }
     959             : 
     960             : // static
     961             : CSSIntPoint
     962          12 : Event::GetPageCoords(nsPresContext* aPresContext,
     963             :                      WidgetEvent* aEvent,
     964             :                      LayoutDeviceIntPoint aPoint,
     965             :                      CSSIntPoint aDefaultPoint)
     966             : {
     967             :   CSSIntPoint pagePoint =
     968          12 :     Event::GetClientCoords(aPresContext, aEvent, aPoint, aDefaultPoint);
     969             : 
     970             :   // If there is some scrolling, add scroll info to client point.
     971          12 :   if (aPresContext && aPresContext->GetPresShell()) {
     972          12 :     nsIPresShell* shell = aPresContext->GetPresShell();
     973          12 :     nsIScrollableFrame* scrollframe = shell->GetRootScrollFrameAsScrollable();
     974          12 :     if (scrollframe) {
     975           0 :       pagePoint += CSSIntPoint::FromAppUnitsRounded(scrollframe->GetScrollPosition());
     976             :     }
     977             :   }
     978             : 
     979          12 :   return pagePoint;
     980             : }
     981             : 
     982             : // static
     983             : CSSIntPoint
     984          34 : Event::GetClientCoords(nsPresContext* aPresContext,
     985             :                        WidgetEvent* aEvent,
     986             :                        LayoutDeviceIntPoint aPoint,
     987             :                        CSSIntPoint aDefaultPoint)
     988             : {
     989          34 :   if (EventStateManager::sIsPointerLocked) {
     990           0 :     return EventStateManager::sLastClientPoint;
     991             :   }
     992             : 
     993          68 :   if (!aEvent ||
     994          54 :       (aEvent->mClass != eMouseEventClass &&
     995          40 :        aEvent->mClass != eMouseScrollEventClass &&
     996          40 :        aEvent->mClass != eWheelEventClass &&
     997          40 :        aEvent->mClass != eTouchEventClass &&
     998          40 :        aEvent->mClass != eDragEventClass &&
     999          36 :        aEvent->mClass != ePointerEventClass &&
    1000          34 :        aEvent->mClass != eSimpleGestureEventClass) ||
    1001          52 :       !aPresContext ||
    1002          18 :       !aEvent->AsGUIEvent()->mWidget) {
    1003          16 :     return aDefaultPoint;
    1004             :   }
    1005             : 
    1006          18 :   nsIPresShell* shell = aPresContext->GetPresShell();
    1007          18 :   if (!shell) {
    1008           0 :     return CSSIntPoint(0, 0);
    1009             :   }
    1010          18 :   nsIFrame* rootFrame = shell->GetRootFrame();
    1011          18 :   if (!rootFrame) {
    1012           0 :     return CSSIntPoint(0, 0);
    1013             :   }
    1014             :   nsPoint pt =
    1015          18 :     nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, aPoint, rootFrame);
    1016             : 
    1017          18 :   return CSSIntPoint::FromAppUnitsRounded(pt);
    1018             : }
    1019             : 
    1020             : // static
    1021             : CSSIntPoint
    1022           0 : Event::GetOffsetCoords(nsPresContext* aPresContext,
    1023             :                        WidgetEvent* aEvent,
    1024             :                        LayoutDeviceIntPoint aPoint,
    1025             :                        CSSIntPoint aDefaultPoint)
    1026             : {
    1027           0 :   if (!aEvent->mTarget) {
    1028           0 :     return GetPageCoords(aPresContext, aEvent, aPoint, aDefaultPoint);
    1029             :   }
    1030           0 :   nsCOMPtr<nsIContent> content = do_QueryInterface(aEvent->mTarget);
    1031           0 :   if (!content || !aPresContext) {
    1032           0 :     return CSSIntPoint(0, 0);
    1033             :   }
    1034           0 :   nsCOMPtr<nsIPresShell> shell = aPresContext->GetPresShell();
    1035           0 :   if (!shell) {
    1036           0 :     return CSSIntPoint(0, 0);
    1037             :   }
    1038           0 :   shell->FlushPendingNotifications(FlushType::Layout);
    1039           0 :   nsIFrame* frame = content->GetPrimaryFrame();
    1040           0 :   if (!frame) {
    1041           0 :     return CSSIntPoint(0, 0);
    1042             :   }
    1043           0 :   nsIFrame* rootFrame = shell->GetRootFrame();
    1044           0 :   if (!rootFrame) {
    1045           0 :     return CSSIntPoint(0, 0);
    1046             :   }
    1047             :   CSSIntPoint clientCoords =
    1048           0 :     GetClientCoords(aPresContext, aEvent, aPoint, aDefaultPoint);
    1049           0 :   nsPoint pt = CSSPixel::ToAppUnits(clientCoords);
    1050           0 :   if (nsLayoutUtils::TransformPoint(rootFrame, frame, pt) ==
    1051             :       nsLayoutUtils::TRANSFORM_SUCCEEDED) {
    1052           0 :     pt -= frame->GetPaddingRectRelativeToSelf().TopLeft();
    1053           0 :     return CSSPixel::FromAppUnitsRounded(pt);
    1054             :   }
    1055           0 :   return CSSIntPoint(0, 0);
    1056             : }
    1057             : 
    1058             : // To be called ONLY by Event::GetType (which has the additional
    1059             : // logic for handling user-defined events).
    1060             : // static
    1061             : const char*
    1062          87 : Event::GetEventName(EventMessage aEventType)
    1063             : {
    1064          87 :   switch(aEventType) {
    1065             : #define MESSAGE_TO_EVENT(name_, _message, _type, _struct) \
    1066             :   case _message: return #name_;
    1067             : #include "mozilla/EventNameList.h"
    1068             : #undef MESSAGE_TO_EVENT
    1069             :   default:
    1070          31 :     break;
    1071             :   }
    1072             :   // XXXldb We can hit this case for WidgetEvent objects that we didn't
    1073             :   // create and that are not user defined events since this function and
    1074             :   // SetEventType are incomplete.  (But fixing that requires fixing the
    1075             :   // arrays in nsEventListenerManager too, since the events for which
    1076             :   // this is a problem generally *are* created by Event.)
    1077          31 :   return nullptr;
    1078             : }
    1079             : 
    1080             : bool
    1081          12 : Event::DefaultPrevented(CallerType aCallerType) const
    1082             : {
    1083          12 :   NS_ENSURE_TRUE(mEvent, false);
    1084             : 
    1085             :   // If preventDefault() has never been called, just return false.
    1086          12 :   if (!mEvent->DefaultPrevented()) {
    1087          12 :     return false;
    1088             :   }
    1089             : 
    1090             :   // If preventDefault() has been called by content, return true.  Otherwise,
    1091             :   // i.e., preventDefault() has been called by chrome, return true only when
    1092             :   // this is called by chrome.
    1093           0 :   return mEvent->DefaultPreventedByContent() ||
    1094           0 :          aCallerType == CallerType::System;
    1095             : }
    1096             : 
    1097             : double
    1098           0 : Event::TimeStampImpl() const
    1099             : {
    1100           0 :   if (!sReturnHighResTimeStamp) {
    1101           0 :     return static_cast<double>(mEvent->mTime);
    1102             :   }
    1103             : 
    1104           0 :   if (mEvent->mTimeStamp.IsNull()) {
    1105           0 :     return 0.0;
    1106             :   }
    1107             : 
    1108           0 :   if (mIsMainThreadEvent) {
    1109           0 :     if (NS_WARN_IF(!mOwner)) {
    1110           0 :       return 0.0;
    1111             :     }
    1112             : 
    1113           0 :     nsCOMPtr<nsPIDOMWindowInner> win = do_QueryInterface(mOwner);
    1114           0 :     if (NS_WARN_IF(!win)) {
    1115           0 :       return 0.0;
    1116             :     }
    1117             : 
    1118           0 :     Performance* perf = win->GetPerformance();
    1119           0 :     if (NS_WARN_IF(!perf)) {
    1120           0 :       return 0.0;
    1121             :     }
    1122             : 
    1123           0 :     return perf->GetDOMTiming()->TimeStampToDOMHighRes(mEvent->mTimeStamp);
    1124             :   }
    1125             : 
    1126             :   workers::WorkerPrivate* workerPrivate =
    1127           0 :     workers::GetCurrentThreadWorkerPrivate();
    1128           0 :   MOZ_ASSERT(workerPrivate);
    1129             : 
    1130           0 :   return workerPrivate->TimeStampToDOMHighRes(mEvent->mTimeStamp);
    1131             : }
    1132             : 
    1133             : double
    1134           0 : Event::TimeStamp() const
    1135             : {
    1136           0 :   return nsRFPService::ReduceTimePrecisionAsMSecs(TimeStampImpl());
    1137             : }
    1138             : 
    1139             : bool
    1140           0 : Event::GetPreventDefault() const
    1141             : {
    1142           0 :   nsCOMPtr<nsPIDOMWindowInner> win(do_QueryInterface(mOwner));
    1143           0 :   if (win) {
    1144           0 :     if (nsIDocument* doc = win->GetExtantDoc()) {
    1145           0 :       doc->WarnOnceAbout(nsIDocument::eGetPreventDefault);
    1146             :     }
    1147             :   }
    1148             :   // GetPreventDefault() is legacy and Gecko specific method.  Although,
    1149             :   // the result should be same as defaultPrevented, we don't need to break
    1150             :   // backward compatibility of legacy method.  Let's behave traditionally.
    1151           0 :   return DefaultPrevented();
    1152             : }
    1153             : 
    1154             : NS_IMETHODIMP
    1155           0 : Event::GetPreventDefault(bool* aReturn)
    1156             : {
    1157           0 :   NS_ENSURE_ARG_POINTER(aReturn);
    1158           0 :   *aReturn = GetPreventDefault();
    1159           0 :   return NS_OK;
    1160             : }
    1161             : 
    1162             : NS_IMETHODIMP
    1163           0 : Event::GetDefaultPrevented(bool* aReturn)
    1164             : {
    1165           0 :   NS_ENSURE_ARG_POINTER(aReturn);
    1166             :   // This method must be called by only event handlers implemented by C++.
    1167             :   // Then, the handlers must handle default action.  So, this method don't need
    1168             :   // to check if preventDefault() has been called by content or chrome.
    1169           0 :   *aReturn = DefaultPrevented();
    1170           0 :   return NS_OK;
    1171             : }
    1172             : 
    1173             : NS_IMETHODIMP_(void)
    1174           0 : Event::Serialize(IPC::Message* aMsg, bool aSerializeInterfaceType)
    1175             : {
    1176           0 :   if (aSerializeInterfaceType) {
    1177           0 :     IPC::WriteParam(aMsg, NS_LITERAL_STRING("event"));
    1178             :   }
    1179             : 
    1180           0 :   nsString type;
    1181           0 :   GetType(type);
    1182           0 :   IPC::WriteParam(aMsg, type);
    1183             : 
    1184           0 :   IPC::WriteParam(aMsg, Bubbles());
    1185           0 :   IPC::WriteParam(aMsg, Cancelable());
    1186           0 :   IPC::WriteParam(aMsg, IsTrusted());
    1187           0 :   IPC::WriteParam(aMsg, Composed());
    1188             : 
    1189             :   // No timestamp serialization for now!
    1190           0 : }
    1191             : 
    1192             : NS_IMETHODIMP_(bool)
    1193           0 : Event::Deserialize(const IPC::Message* aMsg, PickleIterator* aIter)
    1194             : {
    1195           0 :   nsString type;
    1196           0 :   NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &type), false);
    1197             : 
    1198           0 :   bool bubbles = false;
    1199           0 :   NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &bubbles), false);
    1200             : 
    1201           0 :   bool cancelable = false;
    1202           0 :   NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &cancelable), false);
    1203             : 
    1204           0 :   bool trusted = false;
    1205           0 :   NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &trusted), false);
    1206             : 
    1207           0 :   bool composed = false;
    1208           0 :   NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &composed), false);
    1209             : 
    1210           0 :   InitEvent(type, bubbles, cancelable);
    1211           0 :   SetTrusted(trusted);
    1212           0 :   SetComposed(composed);
    1213             : 
    1214           0 :   return true;
    1215             : }
    1216             : 
    1217             : NS_IMETHODIMP_(void)
    1218         366 : Event::SetOwner(EventTarget* aOwner)
    1219             : {
    1220         366 :   mOwner = nullptr;
    1221             : 
    1222         366 :   if (!aOwner) {
    1223         366 :     return;
    1224             :   }
    1225             : 
    1226         366 :   nsCOMPtr<nsINode> n = do_QueryInterface(aOwner);
    1227         366 :   if (n) {
    1228         291 :     mOwner = n->OwnerDoc()->GetScopeObject();
    1229         291 :     return;
    1230             :   }
    1231             : 
    1232          75 :   nsCOMPtr<nsPIDOMWindowInner> w = do_QueryInterface(aOwner);
    1233          75 :   if (w) {
    1234          38 :     mOwner = do_QueryInterface(w);
    1235          38 :     return;
    1236             :   }
    1237             : 
    1238          37 :   nsCOMPtr<DOMEventTargetHelper> eth = do_QueryInterface(aOwner);
    1239          37 :   if (eth) {
    1240          37 :     mOwner = eth->GetParentObject();
    1241          37 :     return;
    1242             :   }
    1243             : 
    1244             : #ifdef DEBUG
    1245           0 :   nsCOMPtr<nsPIWindowRoot> root = do_QueryInterface(aOwner);
    1246           0 :   MOZ_ASSERT(root, "Unexpected EventTarget!");
    1247             : #endif
    1248             : }
    1249             : 
    1250             : // static
    1251             : nsIContent*
    1252           0 : Event::GetShadowRelatedTarget(nsIContent* aCurrentTarget,
    1253             :                               nsIContent* aRelatedTarget)
    1254             : {
    1255           0 :   if (!aCurrentTarget || !aRelatedTarget) {
    1256           0 :     return nullptr;
    1257             :   }
    1258             : 
    1259             :   // Walk up the ancestor node trees of the related target until
    1260             :   // we encounter the node tree of the current target in order
    1261             :   // to find the adjusted related target. Walking up the tree may
    1262             :   // not find a common ancestor node tree if the related target is in
    1263             :   // an ancestor tree, but in that case it does not need to be adjusted.
    1264           0 :   ShadowRoot* currentTargetShadow = aCurrentTarget->GetContainingShadow();
    1265           0 :   if (!currentTargetShadow) {
    1266           0 :     return nullptr;
    1267             :   }
    1268             : 
    1269           0 :   nsIContent* relatedTarget = aCurrentTarget;
    1270           0 :   while (relatedTarget) {
    1271           0 :     ShadowRoot* ancestorShadow = relatedTarget->GetContainingShadow();
    1272           0 :     if (currentTargetShadow == ancestorShadow) {
    1273           0 :       return relatedTarget;
    1274             :     }
    1275             : 
    1276             :     // Didn't find the ancestor tree, thus related target does not have to
    1277             :     // adjusted.
    1278           0 :     if (!ancestorShadow) {
    1279           0 :       return nullptr;
    1280             :     }
    1281             : 
    1282           0 :     relatedTarget = ancestorShadow->GetHost();
    1283             :   }
    1284             : 
    1285           0 :   return nullptr;
    1286             : }
    1287             : 
    1288             : void
    1289          92 : Event::GetWidgetEventType(WidgetEvent* aEvent, nsAString& aType)
    1290             : {
    1291          92 :   if (!aEvent->mSpecifiedEventTypeString.IsEmpty()) {
    1292           5 :     aType = aEvent->mSpecifiedEventTypeString;
    1293           5 :     return;
    1294             :   }
    1295             : 
    1296          87 :   const char* name = GetEventName(aEvent->mMessage);
    1297             : 
    1298          87 :   if (name) {
    1299          56 :     CopyASCIItoUTF16(name, aType);
    1300          56 :     return;
    1301          62 :   } else if (aEvent->mMessage == eUnidentifiedEvent &&
    1302          31 :              aEvent->mSpecifiedEventType) {
    1303             :     // Remove "on"
    1304          31 :     aType = Substring(nsDependentAtomString(aEvent->mSpecifiedEventType), 2);
    1305          31 :     aEvent->mSpecifiedEventTypeString = aType;
    1306          31 :     return;
    1307             :   }
    1308             : 
    1309           0 :   aType.Truncate();
    1310             : }
    1311             : 
    1312             : NS_IMETHODIMP
    1313           0 : Event::GetCancelBubble(bool* aCancelBubble)
    1314             : {
    1315           0 :   NS_ENSURE_ARG_POINTER(aCancelBubble);
    1316           0 :   *aCancelBubble = CancelBubble();
    1317           0 :   return NS_OK;
    1318             : }
    1319             : 
    1320             : NS_IMETHODIMP
    1321           0 : Event::SetCancelBubble(bool aCancelBubble)
    1322             : {
    1323           0 :   if (aCancelBubble) {
    1324           0 :     mEvent->StopPropagation();
    1325             :   }
    1326           0 :   return NS_OK;
    1327             : }
    1328             : 
    1329             : } // namespace dom
    1330             : } // namespace mozilla
    1331             : 
    1332             : using namespace mozilla;
    1333             : using namespace mozilla::dom;
    1334             : 
    1335             : already_AddRefed<Event>
    1336         280 : NS_NewDOMEvent(EventTarget* aOwner,
    1337             :                nsPresContext* aPresContext,
    1338             :                WidgetEvent* aEvent)
    1339             : {
    1340         560 :   RefPtr<Event> it = new Event(aOwner, aPresContext, aEvent);
    1341         560 :   return it.forget();
    1342             : }

Generated by: LCOV version 1.13