dom/events/Event.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/events/Event.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1100 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#include "AccessCheck.h"
    1.10 +#include "base/basictypes.h"
    1.11 +#include "ipc/IPCMessageUtils.h"
    1.12 +#include "mozilla/dom/Event.h"
    1.13 +#include "mozilla/ContentEvents.h"
    1.14 +#include "mozilla/DOMEventTargetHelper.h"
    1.15 +#include "mozilla/EventStateManager.h"
    1.16 +#include "mozilla/InternalMutationEvent.h"
    1.17 +#include "mozilla/MiscEvents.h"
    1.18 +#include "mozilla/MouseEvents.h"
    1.19 +#include "mozilla/Preferences.h"
    1.20 +#include "mozilla/TextEvents.h"
    1.21 +#include "mozilla/TouchEvents.h"
    1.22 +#include "nsContentUtils.h"
    1.23 +#include "nsCOMPtr.h"
    1.24 +#include "nsDeviceContext.h"
    1.25 +#include "nsError.h"
    1.26 +#include "nsGlobalWindow.h"
    1.27 +#include "nsIFrame.h"
    1.28 +#include "nsIContent.h"
    1.29 +#include "nsIDocument.h"
    1.30 +#include "nsIPresShell.h"
    1.31 +#include "nsIScrollableFrame.h"
    1.32 +#include "nsJSEnvironment.h"
    1.33 +#include "nsLayoutUtils.h"
    1.34 +#include "nsPIWindowRoot.h"
    1.35 +
    1.36 +namespace mozilla {
    1.37 +namespace dom {
    1.38 +
    1.39 +namespace workers {
    1.40 +extern bool IsCurrentThreadRunningChromeWorker();
    1.41 +} // namespace workers
    1.42 +
    1.43 +static char *sPopupAllowedEvents;
    1.44 +
    1.45 +Event::Event(EventTarget* aOwner,
    1.46 +             nsPresContext* aPresContext,
    1.47 +             WidgetEvent* aEvent)
    1.48 +{
    1.49 +  ConstructorInit(aOwner, aPresContext, aEvent);
    1.50 +}
    1.51 +
    1.52 +Event::Event(nsPIDOMWindow* aParent)
    1.53 +{
    1.54 +  ConstructorInit(static_cast<nsGlobalWindow *>(aParent), nullptr, nullptr);
    1.55 +}
    1.56 +
    1.57 +void
    1.58 +Event::ConstructorInit(EventTarget* aOwner,
    1.59 +                       nsPresContext* aPresContext,
    1.60 +                       WidgetEvent* aEvent)
    1.61 +{
    1.62 +  SetIsDOMBinding();
    1.63 +  SetOwner(aOwner);
    1.64 +  mIsMainThreadEvent = mOwner || NS_IsMainThread();
    1.65 +  if (mIsMainThreadEvent) {
    1.66 +    nsJSContext::LikelyShortLivingObjectCreated();
    1.67 +  }
    1.68 +
    1.69 +  mPrivateDataDuplicated = false;
    1.70 +
    1.71 +  if (aEvent) {
    1.72 +    mEvent = aEvent;
    1.73 +    mEventIsInternal = false;
    1.74 +  }
    1.75 +  else {
    1.76 +    mEventIsInternal = true;
    1.77 +    /*
    1.78 +      A derived class might want to allocate its own type of aEvent
    1.79 +      (derived from WidgetEvent). To do this, it should take care to pass
    1.80 +      a non-nullptr aEvent to this ctor, e.g.:
    1.81 +      
    1.82 +        FooEvent::FooEvent(..., WidgetEvent* aEvent)
    1.83 +          : Event(..., aEvent ? aEvent : new WidgetEvent())
    1.84 +      
    1.85 +      Then, to override the mEventIsInternal assignments done by the
    1.86 +      base ctor, it should do this in its own ctor:
    1.87 +
    1.88 +        FooEvent::FooEvent(..., WidgetEvent* aEvent)
    1.89 +        ...
    1.90 +        {
    1.91 +          ...
    1.92 +          if (aEvent) {
    1.93 +            mEventIsInternal = false;
    1.94 +          }
    1.95 +          else {
    1.96 +            mEventIsInternal = true;
    1.97 +          }
    1.98 +          ...
    1.99 +        }
   1.100 +     */
   1.101 +    mEvent = new WidgetEvent(false, 0);
   1.102 +    mEvent->time = PR_Now();
   1.103 +  }
   1.104 +
   1.105 +  InitPresContextData(aPresContext);
   1.106 +}
   1.107 +
   1.108 +void
   1.109 +Event::InitPresContextData(nsPresContext* aPresContext)
   1.110 +{
   1.111 +  mPresContext = aPresContext;
   1.112 +  // Get the explicit original target (if it's anonymous make it null)
   1.113 +  {
   1.114 +    nsCOMPtr<nsIContent> content = GetTargetFromFrame();
   1.115 +    mExplicitOriginalTarget = content;
   1.116 +    if (content && content->IsInAnonymousSubtree()) {
   1.117 +      mExplicitOriginalTarget = nullptr;
   1.118 +    }
   1.119 +  }
   1.120 +}
   1.121 +
   1.122 +Event::~Event() 
   1.123 +{
   1.124 +  NS_ASSERT_OWNINGTHREAD(Event);
   1.125 +
   1.126 +  if (mEventIsInternal && mEvent) {
   1.127 +    delete mEvent;
   1.128 +  }
   1.129 +}
   1.130 +
   1.131 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Event)
   1.132 +  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   1.133 +  NS_INTERFACE_MAP_ENTRY(nsISupports)
   1.134 +  NS_INTERFACE_MAP_ENTRY(nsIDOMEvent)
   1.135 +NS_INTERFACE_MAP_END
   1.136 +
   1.137 +NS_IMPL_CYCLE_COLLECTING_ADDREF(Event)
   1.138 +NS_IMPL_CYCLE_COLLECTING_RELEASE(Event)
   1.139 +
   1.140 +NS_IMPL_CYCLE_COLLECTION_CLASS(Event)
   1.141 +
   1.142 +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Event)
   1.143 +  NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
   1.144 +NS_IMPL_CYCLE_COLLECTION_TRACE_END
   1.145 +
   1.146 +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Event)
   1.147 +  if (tmp->mEventIsInternal) {
   1.148 +    tmp->mEvent->target = nullptr;
   1.149 +    tmp->mEvent->currentTarget = nullptr;
   1.150 +    tmp->mEvent->originalTarget = nullptr;
   1.151 +    switch (tmp->mEvent->eventStructType) {
   1.152 +      case NS_MOUSE_EVENT:
   1.153 +      case NS_MOUSE_SCROLL_EVENT:
   1.154 +      case NS_WHEEL_EVENT:
   1.155 +      case NS_SIMPLE_GESTURE_EVENT:
   1.156 +      case NS_POINTER_EVENT:
   1.157 +        tmp->mEvent->AsMouseEventBase()->relatedTarget = nullptr;
   1.158 +        break;
   1.159 +      case NS_DRAG_EVENT: {
   1.160 +        WidgetDragEvent* dragEvent = tmp->mEvent->AsDragEvent();
   1.161 +        dragEvent->dataTransfer = nullptr;
   1.162 +        dragEvent->relatedTarget = nullptr;
   1.163 +        break;
   1.164 +      }
   1.165 +      case NS_CLIPBOARD_EVENT:
   1.166 +        tmp->mEvent->AsClipboardEvent()->clipboardData = nullptr;
   1.167 +        break;
   1.168 +      case NS_MUTATION_EVENT:
   1.169 +        tmp->mEvent->AsMutationEvent()->mRelatedNode = nullptr;
   1.170 +        break;
   1.171 +      case NS_FOCUS_EVENT:
   1.172 +        tmp->mEvent->AsFocusEvent()->relatedTarget = nullptr;
   1.173 +        break;
   1.174 +      default:
   1.175 +        break;
   1.176 +    }
   1.177 +  }
   1.178 +  NS_IMPL_CYCLE_COLLECTION_UNLINK(mPresContext);
   1.179 +  NS_IMPL_CYCLE_COLLECTION_UNLINK(mExplicitOriginalTarget);
   1.180 +  NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner);
   1.181 +  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
   1.182 +NS_IMPL_CYCLE_COLLECTION_UNLINK_END
   1.183 +
   1.184 +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Event)
   1.185 +  if (tmp->mEventIsInternal) {
   1.186 +    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvent->target)
   1.187 +    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvent->currentTarget)
   1.188 +    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvent->originalTarget)
   1.189 +    switch (tmp->mEvent->eventStructType) {
   1.190 +      case NS_MOUSE_EVENT:
   1.191 +      case NS_MOUSE_SCROLL_EVENT:
   1.192 +      case NS_WHEEL_EVENT:
   1.193 +      case NS_SIMPLE_GESTURE_EVENT:
   1.194 +      case NS_POINTER_EVENT:
   1.195 +        NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvent->relatedTarget");
   1.196 +        cb.NoteXPCOMChild(tmp->mEvent->AsMouseEventBase()->relatedTarget);
   1.197 +        break;
   1.198 +      case NS_DRAG_EVENT: {
   1.199 +        WidgetDragEvent* dragEvent = tmp->mEvent->AsDragEvent();
   1.200 +        NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvent->dataTransfer");
   1.201 +        cb.NoteXPCOMChild(dragEvent->dataTransfer);
   1.202 +        NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvent->relatedTarget");
   1.203 +        cb.NoteXPCOMChild(dragEvent->relatedTarget);
   1.204 +        break;
   1.205 +      }
   1.206 +      case NS_CLIPBOARD_EVENT:
   1.207 +        NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvent->clipboardData");
   1.208 +        cb.NoteXPCOMChild(tmp->mEvent->AsClipboardEvent()->clipboardData);
   1.209 +        break;
   1.210 +      case NS_MUTATION_EVENT:
   1.211 +        NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvent->mRelatedNode");
   1.212 +        cb.NoteXPCOMChild(tmp->mEvent->AsMutationEvent()->mRelatedNode);
   1.213 +        break;
   1.214 +      case NS_FOCUS_EVENT:
   1.215 +        NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvent->relatedTarget");
   1.216 +        cb.NoteXPCOMChild(tmp->mEvent->AsFocusEvent()->relatedTarget);
   1.217 +        break;
   1.218 +      default:
   1.219 +        break;
   1.220 +    }
   1.221 +  }
   1.222 +  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPresContext)
   1.223 +  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExplicitOriginalTarget)
   1.224 +  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
   1.225 +  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
   1.226 +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
   1.227 +
   1.228 +bool
   1.229 +Event::IsChrome(JSContext* aCx) const
   1.230 +{
   1.231 +  return mIsMainThreadEvent ?
   1.232 +    xpc::AccessCheck::isChrome(js::GetContextCompartment(aCx)) :
   1.233 +    mozilla::dom::workers::IsCurrentThreadRunningChromeWorker();
   1.234 +}
   1.235 +
   1.236 +// nsIDOMEventInterface
   1.237 +NS_METHOD
   1.238 +Event::GetType(nsAString& aType)
   1.239 +{
   1.240 +  if (!mIsMainThreadEvent || !mEvent->typeString.IsEmpty()) {
   1.241 +    aType = mEvent->typeString;
   1.242 +    return NS_OK;
   1.243 +  }
   1.244 +  const char* name = GetEventName(mEvent->message);
   1.245 +
   1.246 +  if (name) {
   1.247 +    CopyASCIItoUTF16(name, aType);
   1.248 +    return NS_OK;
   1.249 +  } else if (mEvent->message == NS_USER_DEFINED_EVENT && mEvent->userType) {
   1.250 +    aType = Substring(nsDependentAtomString(mEvent->userType), 2); // Remove "on"
   1.251 +    mEvent->typeString = aType;
   1.252 +    return NS_OK;
   1.253 +  }
   1.254 +
   1.255 +  aType.Truncate();
   1.256 +  return NS_OK;
   1.257 +}
   1.258 +
   1.259 +static EventTarget*
   1.260 +GetDOMEventTarget(nsIDOMEventTarget* aTarget)
   1.261 +{
   1.262 +  return aTarget ? aTarget->GetTargetForDOMEvent() : nullptr;
   1.263 +}
   1.264 +
   1.265 +EventTarget*
   1.266 +Event::GetTarget() const
   1.267 +{
   1.268 +  return GetDOMEventTarget(mEvent->target);
   1.269 +}
   1.270 +
   1.271 +NS_METHOD
   1.272 +Event::GetTarget(nsIDOMEventTarget** aTarget)
   1.273 +{
   1.274 +  NS_IF_ADDREF(*aTarget = GetTarget());
   1.275 +  return NS_OK;
   1.276 +}
   1.277 +
   1.278 +EventTarget*
   1.279 +Event::GetCurrentTarget() const
   1.280 +{
   1.281 +  return GetDOMEventTarget(mEvent->currentTarget);
   1.282 +}
   1.283 +
   1.284 +NS_IMETHODIMP
   1.285 +Event::GetCurrentTarget(nsIDOMEventTarget** aCurrentTarget)
   1.286 +{
   1.287 +  NS_IF_ADDREF(*aCurrentTarget = GetCurrentTarget());
   1.288 +  return NS_OK;
   1.289 +}
   1.290 +
   1.291 +//
   1.292 +// Get the actual event target node (may have been retargeted for mouse events)
   1.293 +//
   1.294 +already_AddRefed<nsIContent>
   1.295 +Event::GetTargetFromFrame()
   1.296 +{
   1.297 +  if (!mPresContext) { return nullptr; }
   1.298 +
   1.299 +  // Get the target frame (have to get the ESM first)
   1.300 +  nsIFrame* targetFrame = mPresContext->EventStateManager()->GetEventTarget();
   1.301 +  if (!targetFrame) { return nullptr; }
   1.302 +
   1.303 +  // get the real content
   1.304 +  nsCOMPtr<nsIContent> realEventContent;
   1.305 +  targetFrame->GetContentForEvent(mEvent, getter_AddRefs(realEventContent));
   1.306 +  return realEventContent.forget();
   1.307 +}
   1.308 +
   1.309 +EventTarget*
   1.310 +Event::GetExplicitOriginalTarget() const
   1.311 +{
   1.312 +  if (mExplicitOriginalTarget) {
   1.313 +    return mExplicitOriginalTarget;
   1.314 +  }
   1.315 +  return GetTarget();
   1.316 +}
   1.317 +
   1.318 +NS_IMETHODIMP
   1.319 +Event::GetExplicitOriginalTarget(nsIDOMEventTarget** aRealEventTarget)
   1.320 +{
   1.321 +  NS_IF_ADDREF(*aRealEventTarget = GetExplicitOriginalTarget());
   1.322 +  return NS_OK;
   1.323 +}
   1.324 +
   1.325 +EventTarget*
   1.326 +Event::GetOriginalTarget() const
   1.327 +{
   1.328 +  if (mEvent->originalTarget) {
   1.329 +    return GetDOMEventTarget(mEvent->originalTarget);
   1.330 +  }
   1.331 +
   1.332 +  return GetTarget();
   1.333 +}
   1.334 +
   1.335 +NS_IMETHODIMP
   1.336 +Event::GetOriginalTarget(nsIDOMEventTarget** aOriginalTarget)
   1.337 +{
   1.338 +  NS_IF_ADDREF(*aOriginalTarget = GetOriginalTarget());
   1.339 +  return NS_OK;
   1.340 +}
   1.341 +
   1.342 +NS_IMETHODIMP_(void)
   1.343 +Event::SetTrusted(bool aTrusted)
   1.344 +{
   1.345 +  mEvent->mFlags.mIsTrusted = aTrusted;
   1.346 +}
   1.347 +
   1.348 +bool
   1.349 +Event::Init(mozilla::dom::EventTarget* aGlobal)
   1.350 +{
   1.351 +  if (!mIsMainThreadEvent) {
   1.352 +    return nsContentUtils::ThreadsafeIsCallerChrome();
   1.353 +  }
   1.354 +  bool trusted = false;
   1.355 +  nsCOMPtr<nsPIDOMWindow> w = do_QueryInterface(aGlobal);
   1.356 +  if (w) {
   1.357 +    nsCOMPtr<nsIDocument> d = w->GetExtantDoc();
   1.358 +    if (d) {
   1.359 +      trusted = nsContentUtils::IsChromeDoc(d);
   1.360 +      nsIPresShell* s = d->GetShell();
   1.361 +      if (s) {
   1.362 +        InitPresContextData(s->GetPresContext());
   1.363 +      }
   1.364 +    }
   1.365 +  }
   1.366 +  return trusted;
   1.367 +}
   1.368 +
   1.369 +// static
   1.370 +already_AddRefed<Event>
   1.371 +Event::Constructor(const GlobalObject& aGlobal,
   1.372 +                   const nsAString& aType,
   1.373 +                   const EventInit& aParam,
   1.374 +                   ErrorResult& aRv)
   1.375 +{
   1.376 +  nsCOMPtr<mozilla::dom::EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports());
   1.377 +  nsRefPtr<Event> e = new Event(t, nullptr, nullptr);
   1.378 +  bool trusted = e->Init(t);
   1.379 +  aRv = e->InitEvent(aType, aParam.mBubbles, aParam.mCancelable);
   1.380 +  e->SetTrusted(trusted);
   1.381 +  return e.forget();
   1.382 +}
   1.383 +
   1.384 +uint16_t
   1.385 +Event::EventPhase() const
   1.386 +{
   1.387 +  // Note, remember to check that this works also
   1.388 +  // if or when Bug 235441 is fixed.
   1.389 +  if ((mEvent->currentTarget &&
   1.390 +       mEvent->currentTarget == mEvent->target) ||
   1.391 +       mEvent->mFlags.InTargetPhase()) {
   1.392 +    return nsIDOMEvent::AT_TARGET;
   1.393 +  }
   1.394 +  if (mEvent->mFlags.mInCapturePhase) {
   1.395 +    return nsIDOMEvent::CAPTURING_PHASE;
   1.396 +  }
   1.397 +  if (mEvent->mFlags.mInBubblingPhase) {
   1.398 +    return nsIDOMEvent::BUBBLING_PHASE;
   1.399 +  }
   1.400 +  return nsIDOMEvent::NONE;
   1.401 +}
   1.402 +
   1.403 +NS_IMETHODIMP
   1.404 +Event::GetEventPhase(uint16_t* aEventPhase)
   1.405 +{
   1.406 +  *aEventPhase = EventPhase();
   1.407 +  return NS_OK;
   1.408 +}
   1.409 +
   1.410 +NS_IMETHODIMP
   1.411 +Event::GetBubbles(bool* aBubbles)
   1.412 +{
   1.413 +  *aBubbles = Bubbles();
   1.414 +  return NS_OK;
   1.415 +}
   1.416 +
   1.417 +NS_IMETHODIMP
   1.418 +Event::GetCancelable(bool* aCancelable)
   1.419 +{
   1.420 +  *aCancelable = Cancelable();
   1.421 +  return NS_OK;
   1.422 +}
   1.423 +
   1.424 +NS_IMETHODIMP
   1.425 +Event::GetTimeStamp(uint64_t* aTimeStamp)
   1.426 +{
   1.427 +  *aTimeStamp = TimeStamp();
   1.428 +  return NS_OK;
   1.429 +}
   1.430 +
   1.431 +NS_IMETHODIMP
   1.432 +Event::StopPropagation()
   1.433 +{
   1.434 +  mEvent->mFlags.mPropagationStopped = true;
   1.435 +  return NS_OK;
   1.436 +}
   1.437 +
   1.438 +NS_IMETHODIMP
   1.439 +Event::StopImmediatePropagation()
   1.440 +{
   1.441 +  mEvent->mFlags.mPropagationStopped = true;
   1.442 +  mEvent->mFlags.mImmediatePropagationStopped = true;
   1.443 +  return NS_OK;
   1.444 +}
   1.445 +
   1.446 +NS_IMETHODIMP
   1.447 +Event::GetIsTrusted(bool* aIsTrusted)
   1.448 +{
   1.449 +  *aIsTrusted = IsTrusted();
   1.450 +  return NS_OK;
   1.451 +}
   1.452 +
   1.453 +NS_IMETHODIMP
   1.454 +Event::PreventDefault()
   1.455 +{
   1.456 +  // This method is called only from C++ code which must handle default action
   1.457 +  // of this event.  So, pass true always.
   1.458 +  PreventDefaultInternal(true);
   1.459 +  return NS_OK;
   1.460 +}
   1.461 +
   1.462 +void
   1.463 +Event::PreventDefault(JSContext* aCx)
   1.464 +{
   1.465 +  MOZ_ASSERT(aCx, "JS context must be specified");
   1.466 +
   1.467 +  // Note that at handling default action, another event may be dispatched.
   1.468 +  // Then, JS in content mey be call preventDefault()
   1.469 +  // even in the event is in system event group.  Therefore, don't refer
   1.470 +  // mInSystemGroup here.
   1.471 +  PreventDefaultInternal(IsChrome(aCx));
   1.472 +}
   1.473 +
   1.474 +void
   1.475 +Event::PreventDefaultInternal(bool aCalledByDefaultHandler)
   1.476 +{
   1.477 +  if (!mEvent->mFlags.mCancelable) {
   1.478 +    return;
   1.479 +  }
   1.480 +
   1.481 +  mEvent->mFlags.mDefaultPrevented = true;
   1.482 +
   1.483 +  // Note that even if preventDefault() has already been called by chrome,
   1.484 +  // a call of preventDefault() by content needs to overwrite
   1.485 +  // mDefaultPreventedByContent to true because in such case, defaultPrevented
   1.486 +  // must be true when web apps check it after they call preventDefault().
   1.487 +  if (!aCalledByDefaultHandler) {
   1.488 +    mEvent->mFlags.mDefaultPreventedByContent = true;
   1.489 +  }
   1.490 +
   1.491 +  if (!IsTrusted()) {
   1.492 +    return;
   1.493 +  }
   1.494 +
   1.495 +  WidgetDragEvent* dragEvent = mEvent->AsDragEvent();
   1.496 +  if (!dragEvent) {
   1.497 +    return;
   1.498 +  }
   1.499 +
   1.500 +  nsCOMPtr<nsINode> node = do_QueryInterface(mEvent->currentTarget);
   1.501 +  if (!node) {
   1.502 +    nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(mEvent->currentTarget);
   1.503 +    if (!win) {
   1.504 +      return;
   1.505 +    }
   1.506 +    node = win->GetExtantDoc();
   1.507 +  }
   1.508 +  if (!nsContentUtils::IsChromeDoc(node->OwnerDoc())) {
   1.509 +    dragEvent->mDefaultPreventedOnContent = true;
   1.510 +  }
   1.511 +}
   1.512 +
   1.513 +void
   1.514 +Event::SetEventType(const nsAString& aEventTypeArg)
   1.515 +{
   1.516 +  if (mIsMainThreadEvent) {
   1.517 +    mEvent->userType =
   1.518 +      nsContentUtils::GetEventIdAndAtom(aEventTypeArg, mEvent->eventStructType,
   1.519 +                                        &(mEvent->message));
   1.520 +  } else {
   1.521 +    mEvent->userType = nullptr;
   1.522 +    mEvent->message = NS_USER_DEFINED_EVENT;
   1.523 +    mEvent->typeString = aEventTypeArg;
   1.524 +  }
   1.525 +}
   1.526 +
   1.527 +NS_IMETHODIMP
   1.528 +Event::InitEvent(const nsAString& aEventTypeArg,
   1.529 +                 bool aCanBubbleArg,
   1.530 +                 bool aCancelableArg)
   1.531 +{
   1.532 +  // Make sure this event isn't already being dispatched.
   1.533 +  NS_ENSURE_TRUE(!mEvent->mFlags.mIsBeingDispatched, NS_OK);
   1.534 +
   1.535 +  if (IsTrusted()) {
   1.536 +    // Ensure the caller is permitted to dispatch trusted DOM events.
   1.537 +    if (!nsContentUtils::ThreadsafeIsCallerChrome()) {
   1.538 +      SetTrusted(false);
   1.539 +    }
   1.540 +  }
   1.541 +
   1.542 +  SetEventType(aEventTypeArg);
   1.543 +
   1.544 +  mEvent->mFlags.mBubbles = aCanBubbleArg;
   1.545 +  mEvent->mFlags.mCancelable = aCancelableArg;
   1.546 +
   1.547 +  mEvent->mFlags.mDefaultPrevented = false;
   1.548 +
   1.549 +  // Clearing the old targets, so that the event is targeted correctly when
   1.550 +  // re-dispatching it.
   1.551 +  mEvent->target = nullptr;
   1.552 +  mEvent->originalTarget = nullptr;
   1.553 +  return NS_OK;
   1.554 +}
   1.555 +
   1.556 +NS_IMETHODIMP
   1.557 +Event::DuplicatePrivateData()
   1.558 +{
   1.559 +  NS_ASSERTION(mEvent, "No WidgetEvent for Event duplication!");
   1.560 +  if (mEventIsInternal) {
   1.561 +    return NS_OK;
   1.562 +  }
   1.563 +
   1.564 +  mEvent = mEvent->Duplicate();
   1.565 +  mPresContext = nullptr;
   1.566 +  mEventIsInternal = true;
   1.567 +  mPrivateDataDuplicated = true;
   1.568 +
   1.569 +  return NS_OK;
   1.570 +}
   1.571 +
   1.572 +NS_IMETHODIMP
   1.573 +Event::SetTarget(nsIDOMEventTarget* aTarget)
   1.574 +{
   1.575 +#ifdef DEBUG
   1.576 +  {
   1.577 +    nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aTarget);
   1.578 +
   1.579 +    NS_ASSERTION(!win || !win->IsInnerWindow(),
   1.580 +                 "Uh, inner window set as event target!");
   1.581 +  }
   1.582 +#endif
   1.583 +
   1.584 +  mEvent->target = do_QueryInterface(aTarget);
   1.585 +  return NS_OK;
   1.586 +}
   1.587 +
   1.588 +NS_IMETHODIMP_(bool)
   1.589 +Event::IsDispatchStopped()
   1.590 +{
   1.591 +  return mEvent->mFlags.mPropagationStopped;
   1.592 +}
   1.593 +
   1.594 +NS_IMETHODIMP_(WidgetEvent*)
   1.595 +Event::GetInternalNSEvent()
   1.596 +{
   1.597 +  return mEvent;
   1.598 +}
   1.599 +
   1.600 +NS_IMETHODIMP_(Event*)
   1.601 +Event::InternalDOMEvent()
   1.602 +{
   1.603 +  return this;
   1.604 +}
   1.605 +
   1.606 +// return true if eventName is contained within events, delimited by
   1.607 +// spaces
   1.608 +static bool
   1.609 +PopupAllowedForEvent(const char *eventName)
   1.610 +{
   1.611 +  if (!sPopupAllowedEvents) {
   1.612 +    Event::PopupAllowedEventsChanged();
   1.613 +
   1.614 +    if (!sPopupAllowedEvents) {
   1.615 +      return false;
   1.616 +    }
   1.617 +  }
   1.618 +
   1.619 +  nsDependentCString events(sPopupAllowedEvents);
   1.620 +
   1.621 +  nsAFlatCString::const_iterator start, end;
   1.622 +  nsAFlatCString::const_iterator startiter(events.BeginReading(start));
   1.623 +  events.EndReading(end);
   1.624 +
   1.625 +  while (startiter != end) {
   1.626 +    nsAFlatCString::const_iterator enditer(end);
   1.627 +
   1.628 +    if (!FindInReadable(nsDependentCString(eventName), startiter, enditer))
   1.629 +      return false;
   1.630 +
   1.631 +    // the match is surrounded by spaces, or at a string boundary
   1.632 +    if ((startiter == start || *--startiter == ' ') &&
   1.633 +        (enditer == end || *enditer == ' ')) {
   1.634 +      return true;
   1.635 +    }
   1.636 +
   1.637 +    // Move on and see if there are other matches. (The delimitation
   1.638 +    // requirement makes it pointless to begin the next search before
   1.639 +    // the end of the invalid match just found.)
   1.640 +    startiter = enditer;
   1.641 +  }
   1.642 +
   1.643 +  return false;
   1.644 +}
   1.645 +
   1.646 +// static
   1.647 +PopupControlState
   1.648 +Event::GetEventPopupControlState(WidgetEvent* aEvent)
   1.649 +{
   1.650 +  // generally if an event handler is running, new windows are disallowed.
   1.651 +  // check for exceptions:
   1.652 +  PopupControlState abuse = openAbused;
   1.653 +
   1.654 +  switch(aEvent->eventStructType) {
   1.655 +  case NS_EVENT :
   1.656 +    // For these following events only allow popups if they're
   1.657 +    // triggered while handling user input. See
   1.658 +    // nsPresShell::HandleEventInternal() for details.
   1.659 +    if (EventStateManager::IsHandlingUserInput()) {
   1.660 +      switch(aEvent->message) {
   1.661 +      case NS_FORM_SELECTED :
   1.662 +        if (PopupAllowedForEvent("select")) {
   1.663 +          abuse = openControlled;
   1.664 +        }
   1.665 +        break;
   1.666 +      case NS_FORM_CHANGE :
   1.667 +        if (PopupAllowedForEvent("change")) {
   1.668 +          abuse = openControlled;
   1.669 +        }
   1.670 +        break;
   1.671 +      }
   1.672 +    }
   1.673 +    break;
   1.674 +  case NS_EDITOR_INPUT_EVENT :
   1.675 +    // For this following event only allow popups if it's triggered
   1.676 +    // while handling user input. See
   1.677 +    // nsPresShell::HandleEventInternal() for details.
   1.678 +    if (EventStateManager::IsHandlingUserInput()) {
   1.679 +      switch(aEvent->message) {
   1.680 +      case NS_EDITOR_INPUT:
   1.681 +        if (PopupAllowedForEvent("input")) {
   1.682 +          abuse = openControlled;
   1.683 +        }
   1.684 +        break;
   1.685 +      }
   1.686 +    }
   1.687 +    break;
   1.688 +  case NS_INPUT_EVENT :
   1.689 +    // For this following event only allow popups if it's triggered
   1.690 +    // while handling user input. See
   1.691 +    // nsPresShell::HandleEventInternal() for details.
   1.692 +    if (EventStateManager::IsHandlingUserInput()) {
   1.693 +      switch(aEvent->message) {
   1.694 +      case NS_FORM_CHANGE :
   1.695 +        if (PopupAllowedForEvent("change")) {
   1.696 +          abuse = openControlled;
   1.697 +        }
   1.698 +        break;
   1.699 +      case NS_XUL_COMMAND:
   1.700 +        abuse = openControlled;
   1.701 +        break;
   1.702 +      }
   1.703 +    }
   1.704 +    break;
   1.705 +  case NS_KEY_EVENT :
   1.706 +    if (aEvent->mFlags.mIsTrusted) {
   1.707 +      uint32_t key = aEvent->AsKeyboardEvent()->keyCode;
   1.708 +      switch(aEvent->message) {
   1.709 +      case NS_KEY_PRESS :
   1.710 +        // return key on focused button. see note at NS_MOUSE_CLICK.
   1.711 +        if (key == nsIDOMKeyEvent::DOM_VK_RETURN) {
   1.712 +          abuse = openAllowed;
   1.713 +        } else if (PopupAllowedForEvent("keypress")) {
   1.714 +          abuse = openControlled;
   1.715 +        }
   1.716 +        break;
   1.717 +      case NS_KEY_UP :
   1.718 +        // space key on focused button. see note at NS_MOUSE_CLICK.
   1.719 +        if (key == nsIDOMKeyEvent::DOM_VK_SPACE) {
   1.720 +          abuse = openAllowed;
   1.721 +        } else if (PopupAllowedForEvent("keyup")) {
   1.722 +          abuse = openControlled;
   1.723 +        }
   1.724 +        break;
   1.725 +      case NS_KEY_DOWN :
   1.726 +        if (PopupAllowedForEvent("keydown")) {
   1.727 +          abuse = openControlled;
   1.728 +        }
   1.729 +        break;
   1.730 +      }
   1.731 +    }
   1.732 +    break;
   1.733 +  case NS_TOUCH_EVENT :
   1.734 +    if (aEvent->mFlags.mIsTrusted) {
   1.735 +      switch (aEvent->message) {
   1.736 +      case NS_TOUCH_START :
   1.737 +        if (PopupAllowedForEvent("touchstart")) {
   1.738 +          abuse = openControlled;
   1.739 +        }
   1.740 +        break;
   1.741 +      case NS_TOUCH_END :
   1.742 +        if (PopupAllowedForEvent("touchend")) {
   1.743 +          abuse = openControlled;
   1.744 +        }
   1.745 +        break;
   1.746 +      }
   1.747 +    }
   1.748 +    break;
   1.749 +  case NS_MOUSE_EVENT :
   1.750 +    if (aEvent->mFlags.mIsTrusted &&
   1.751 +        aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) {
   1.752 +      switch(aEvent->message) {
   1.753 +      case NS_MOUSE_BUTTON_UP :
   1.754 +        if (PopupAllowedForEvent("mouseup")) {
   1.755 +          abuse = openControlled;
   1.756 +        }
   1.757 +        break;
   1.758 +      case NS_MOUSE_BUTTON_DOWN :
   1.759 +        if (PopupAllowedForEvent("mousedown")) {
   1.760 +          abuse = openControlled;
   1.761 +        }
   1.762 +        break;
   1.763 +      case NS_MOUSE_CLICK :
   1.764 +        /* Click events get special treatment because of their
   1.765 +           historical status as a more legitimate event handler. If
   1.766 +           click popups are enabled in the prefs, clear the popup
   1.767 +           status completely. */
   1.768 +        if (PopupAllowedForEvent("click")) {
   1.769 +          abuse = openAllowed;
   1.770 +        }
   1.771 +        break;
   1.772 +      case NS_MOUSE_DOUBLECLICK :
   1.773 +        if (PopupAllowedForEvent("dblclick")) {
   1.774 +          abuse = openControlled;
   1.775 +        }
   1.776 +        break;
   1.777 +      }
   1.778 +    }
   1.779 +    break;
   1.780 +  case NS_FORM_EVENT :
   1.781 +    // For these following events only allow popups if they're
   1.782 +    // triggered while handling user input. See
   1.783 +    // nsPresShell::HandleEventInternal() for details.
   1.784 +    if (EventStateManager::IsHandlingUserInput()) {
   1.785 +      switch(aEvent->message) {
   1.786 +      case NS_FORM_SUBMIT :
   1.787 +        if (PopupAllowedForEvent("submit")) {
   1.788 +          abuse = openControlled;
   1.789 +        }
   1.790 +        break;
   1.791 +      case NS_FORM_RESET :
   1.792 +        if (PopupAllowedForEvent("reset")) {
   1.793 +          abuse = openControlled;
   1.794 +        }
   1.795 +        break;
   1.796 +      }
   1.797 +    }
   1.798 +    break;
   1.799 +  default:
   1.800 +    break;
   1.801 +  }
   1.802 +
   1.803 +  return abuse;
   1.804 +}
   1.805 +
   1.806 +// static
   1.807 +void
   1.808 +Event::PopupAllowedEventsChanged()
   1.809 +{
   1.810 +  if (sPopupAllowedEvents) {
   1.811 +    nsMemory::Free(sPopupAllowedEvents);
   1.812 +  }
   1.813 +
   1.814 +  nsAdoptingCString str = Preferences::GetCString("dom.popup_allowed_events");
   1.815 +
   1.816 +  // We'll want to do this even if str is empty to avoid looking up
   1.817 +  // this pref all the time if it's not set.
   1.818 +  sPopupAllowedEvents = ToNewCString(str);
   1.819 +}
   1.820 +
   1.821 +// static
   1.822 +void
   1.823 +Event::Shutdown()
   1.824 +{
   1.825 +  if (sPopupAllowedEvents) {
   1.826 +    nsMemory::Free(sPopupAllowedEvents);
   1.827 +  }
   1.828 +}
   1.829 +
   1.830 +nsIntPoint
   1.831 +Event::GetScreenCoords(nsPresContext* aPresContext,
   1.832 +                       WidgetEvent* aEvent,
   1.833 +                       LayoutDeviceIntPoint aPoint)
   1.834 +{
   1.835 +  if (!nsContentUtils::IsCallerChrome()) {
   1.836 +    // For non-chrome callers, return client coordinates instead.
   1.837 +    // For some events, the result will be zero; specifically, for dragend
   1.838 +    // events (there is no widget associated with dragend events, which
   1.839 +    // causes GetClientX() to return zero).  Since dragend is for the drag
   1.840 +    // originator and not for the receiver, it is probably not widely used
   1.841 +    // (receivers get a drop event).  Therefore, returning 0 should not break
   1.842 +    // many web pages.  Also, a few years ago Firefox returned 0.
   1.843 +    // See:  https://bugzilla.mozilla.org/show_bug.cgi?id=466379
   1.844 +    CSSIntPoint clientCoords = GetClientCoords(aPresContext, aEvent, aPoint, CSSIntPoint(0, 0));
   1.845 +    return nsIntPoint(clientCoords.x, clientCoords.y);
   1.846 +  }
   1.847 +
   1.848 +  if (EventStateManager::sIsPointerLocked) {
   1.849 +    return EventStateManager::sLastScreenPoint;
   1.850 +  }
   1.851 +
   1.852 +  if (!aEvent || 
   1.853 +       (aEvent->eventStructType != NS_MOUSE_EVENT &&
   1.854 +        aEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
   1.855 +        aEvent->eventStructType != NS_WHEEL_EVENT &&
   1.856 +        aEvent->eventStructType != NS_POINTER_EVENT &&
   1.857 +        aEvent->eventStructType != NS_TOUCH_EVENT &&
   1.858 +        aEvent->eventStructType != NS_DRAG_EVENT &&
   1.859 +        aEvent->eventStructType != NS_SIMPLE_GESTURE_EVENT)) {
   1.860 +    return nsIntPoint(0, 0);
   1.861 +  }
   1.862 +
   1.863 +  WidgetGUIEvent* guiEvent = aEvent->AsGUIEvent();
   1.864 +  if (!guiEvent->widget) {
   1.865 +    return LayoutDeviceIntPoint::ToUntyped(aPoint);
   1.866 +  }
   1.867 +
   1.868 +  LayoutDeviceIntPoint offset = aPoint +
   1.869 +    LayoutDeviceIntPoint::FromUntyped(guiEvent->widget->WidgetToScreenOffset());
   1.870 +  nscoord factor = aPresContext->DeviceContext()->UnscaledAppUnitsPerDevPixel();
   1.871 +  return nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(offset.x * factor),
   1.872 +                    nsPresContext::AppUnitsToIntCSSPixels(offset.y * factor));
   1.873 +}
   1.874 +
   1.875 +// static
   1.876 +CSSIntPoint
   1.877 +Event::GetPageCoords(nsPresContext* aPresContext,
   1.878 +                     WidgetEvent* aEvent,
   1.879 +                     LayoutDeviceIntPoint aPoint,
   1.880 +                     CSSIntPoint aDefaultPoint)
   1.881 +{
   1.882 +  CSSIntPoint pagePoint =
   1.883 +    Event::GetClientCoords(aPresContext, aEvent, aPoint, aDefaultPoint);
   1.884 +
   1.885 +  // If there is some scrolling, add scroll info to client point.
   1.886 +  if (aPresContext && aPresContext->GetPresShell()) {
   1.887 +    nsIPresShell* shell = aPresContext->GetPresShell();
   1.888 +    nsIScrollableFrame* scrollframe = shell->GetRootScrollFrameAsScrollable();
   1.889 +    if (scrollframe) {
   1.890 +      pagePoint += CSSIntPoint::FromAppUnitsRounded(scrollframe->GetScrollPosition());
   1.891 +    }
   1.892 +  }
   1.893 +
   1.894 +  return pagePoint;
   1.895 +}
   1.896 +
   1.897 +// static
   1.898 +CSSIntPoint
   1.899 +Event::GetClientCoords(nsPresContext* aPresContext,
   1.900 +                       WidgetEvent* aEvent,
   1.901 +                       LayoutDeviceIntPoint aPoint,
   1.902 +                       CSSIntPoint aDefaultPoint)
   1.903 +{
   1.904 +  if (EventStateManager::sIsPointerLocked) {
   1.905 +    return EventStateManager::sLastClientPoint;
   1.906 +  }
   1.907 +
   1.908 +  if (!aEvent ||
   1.909 +      (aEvent->eventStructType != NS_MOUSE_EVENT &&
   1.910 +       aEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
   1.911 +       aEvent->eventStructType != NS_WHEEL_EVENT &&
   1.912 +       aEvent->eventStructType != NS_TOUCH_EVENT &&
   1.913 +       aEvent->eventStructType != NS_DRAG_EVENT &&
   1.914 +       aEvent->eventStructType != NS_POINTER_EVENT &&
   1.915 +       aEvent->eventStructType != NS_SIMPLE_GESTURE_EVENT) ||
   1.916 +      !aPresContext ||
   1.917 +      !aEvent->AsGUIEvent()->widget) {
   1.918 +    return aDefaultPoint;
   1.919 +  }
   1.920 +
   1.921 +  nsIPresShell* shell = aPresContext->GetPresShell();
   1.922 +  if (!shell) {
   1.923 +    return CSSIntPoint(0, 0);
   1.924 +  }
   1.925 +
   1.926 +  nsIFrame* rootFrame = shell->GetRootFrame();
   1.927 +  if (!rootFrame) {
   1.928 +    return CSSIntPoint(0, 0);
   1.929 +  }
   1.930 +  nsPoint pt =
   1.931 +    nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent,
   1.932 +      LayoutDeviceIntPoint::ToUntyped(aPoint), rootFrame);
   1.933 +
   1.934 +  return CSSIntPoint::FromAppUnitsRounded(pt);
   1.935 +}
   1.936 +
   1.937 +// To be called ONLY by Event::GetType (which has the additional
   1.938 +// logic for handling user-defined events).
   1.939 +// static
   1.940 +const char*
   1.941 +Event::GetEventName(uint32_t aEventType)
   1.942 +{
   1.943 +  switch(aEventType) {
   1.944 +#define ID_TO_EVENT(name_, _id, _type, _struct) \
   1.945 +  case _id: return #name_;
   1.946 +#include "mozilla/EventNameList.h"
   1.947 +#undef ID_TO_EVENT
   1.948 +  default:
   1.949 +    break;
   1.950 +  }
   1.951 +  // XXXldb We can hit this case for WidgetEvent objects that we didn't
   1.952 +  // create and that are not user defined events since this function and
   1.953 +  // SetEventType are incomplete.  (But fixing that requires fixing the
   1.954 +  // arrays in nsEventListenerManager too, since the events for which
   1.955 +  // this is a problem generally *are* created by Event.)
   1.956 +  return nullptr;
   1.957 +}
   1.958 +
   1.959 +bool
   1.960 +Event::DefaultPrevented(JSContext* aCx) const
   1.961 +{
   1.962 +  MOZ_ASSERT(aCx, "JS context must be specified");
   1.963 +
   1.964 +  NS_ENSURE_TRUE(mEvent, false);
   1.965 +
   1.966 +  // If preventDefault() has never been called, just return false.
   1.967 +  if (!mEvent->mFlags.mDefaultPrevented) {
   1.968 +    return false;
   1.969 +  }
   1.970 +
   1.971 +  // If preventDefault() has been called by content, return true.  Otherwise,
   1.972 +  // i.e., preventDefault() has been called by chrome, return true only when
   1.973 +  // this is called by chrome.
   1.974 +  return mEvent->mFlags.mDefaultPreventedByContent || IsChrome(aCx);
   1.975 +}
   1.976 +
   1.977 +bool
   1.978 +Event::GetPreventDefault() const
   1.979 +{
   1.980 +  if (mOwner) {
   1.981 +    if (nsIDocument* doc = mOwner->GetExtantDoc()) {
   1.982 +      doc->WarnOnceAbout(nsIDocument::eGetPreventDefault);
   1.983 +    }
   1.984 +  }
   1.985 +  // GetPreventDefault() is legacy and Gecko specific method.  Although,
   1.986 +  // the result should be same as defaultPrevented, we don't need to break
   1.987 +  // backward compatibility of legacy method.  Let's behave traditionally.
   1.988 +  return DefaultPrevented();
   1.989 +}
   1.990 +
   1.991 +NS_IMETHODIMP
   1.992 +Event::GetPreventDefault(bool* aReturn)
   1.993 +{
   1.994 +  NS_ENSURE_ARG_POINTER(aReturn);
   1.995 +  *aReturn = GetPreventDefault();
   1.996 +  return NS_OK;
   1.997 +}
   1.998 +
   1.999 +NS_IMETHODIMP
  1.1000 +Event::GetDefaultPrevented(bool* aReturn)
  1.1001 +{
  1.1002 +  NS_ENSURE_ARG_POINTER(aReturn);
  1.1003 +  // This method must be called by only event handlers implemented by C++.
  1.1004 +  // Then, the handlers must handle default action.  So, this method don't need
  1.1005 +  // to check if preventDefault() has been called by content or chrome.
  1.1006 +  *aReturn = DefaultPrevented();
  1.1007 +  return NS_OK;
  1.1008 +}
  1.1009 +
  1.1010 +NS_IMETHODIMP_(void)
  1.1011 +Event::Serialize(IPC::Message* aMsg, bool aSerializeInterfaceType)
  1.1012 +{
  1.1013 +  if (aSerializeInterfaceType) {
  1.1014 +    IPC::WriteParam(aMsg, NS_LITERAL_STRING("event"));
  1.1015 +  }
  1.1016 +
  1.1017 +  nsString type;
  1.1018 +  GetType(type);
  1.1019 +  IPC::WriteParam(aMsg, type);
  1.1020 +
  1.1021 +  IPC::WriteParam(aMsg, Bubbles());
  1.1022 +  IPC::WriteParam(aMsg, Cancelable());
  1.1023 +  IPC::WriteParam(aMsg, IsTrusted());
  1.1024 +
  1.1025 +  // No timestamp serialization for now!
  1.1026 +}
  1.1027 +
  1.1028 +NS_IMETHODIMP_(bool)
  1.1029 +Event::Deserialize(const IPC::Message* aMsg, void** aIter)
  1.1030 +{
  1.1031 +  nsString type;
  1.1032 +  NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &type), false);
  1.1033 +
  1.1034 +  bool bubbles = false;
  1.1035 +  NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &bubbles), false);
  1.1036 +
  1.1037 +  bool cancelable = false;
  1.1038 +  NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &cancelable), false);
  1.1039 +
  1.1040 +  bool trusted = false;
  1.1041 +  NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &trusted), false);
  1.1042 +
  1.1043 +  nsresult rv = InitEvent(type, bubbles, cancelable);
  1.1044 +  NS_ENSURE_SUCCESS(rv, false);
  1.1045 +  SetTrusted(trusted);
  1.1046 +
  1.1047 +  return true;
  1.1048 +}
  1.1049 +
  1.1050 +NS_IMETHODIMP_(void)
  1.1051 +Event::SetOwner(mozilla::dom::EventTarget* aOwner)
  1.1052 +{
  1.1053 +  mOwner = nullptr;
  1.1054 +
  1.1055 +  if (!aOwner) {
  1.1056 +    return;
  1.1057 +  }
  1.1058 +
  1.1059 +  nsCOMPtr<nsINode> n = do_QueryInterface(aOwner);
  1.1060 +  if (n) {
  1.1061 +    mOwner = do_QueryInterface(n->OwnerDoc()->GetScopeObject());
  1.1062 +    return;
  1.1063 +  }
  1.1064 +
  1.1065 +  nsCOMPtr<nsPIDOMWindow> w = do_QueryInterface(aOwner);
  1.1066 +  if (w) {
  1.1067 +    if (w->IsOuterWindow()) {
  1.1068 +      mOwner = w->GetCurrentInnerWindow();
  1.1069 +    } else {
  1.1070 +      mOwner.swap(w);
  1.1071 +    }
  1.1072 +    return;
  1.1073 +  }
  1.1074 +
  1.1075 +  nsCOMPtr<DOMEventTargetHelper> eth = do_QueryInterface(aOwner);
  1.1076 +  if (eth) {
  1.1077 +    mOwner = eth->GetOwner();
  1.1078 +    return;
  1.1079 +  }
  1.1080 +
  1.1081 +#ifdef DEBUG
  1.1082 +  nsCOMPtr<nsPIWindowRoot> root = do_QueryInterface(aOwner);
  1.1083 +  MOZ_ASSERT(root, "Unexpected EventTarget!");
  1.1084 +#endif
  1.1085 +}
  1.1086 +
  1.1087 +} // namespace dom
  1.1088 +} // namespace mozilla
  1.1089 +
  1.1090 +using namespace mozilla;
  1.1091 +using namespace mozilla::dom;
  1.1092 +
  1.1093 +nsresult
  1.1094 +NS_NewDOMEvent(nsIDOMEvent** aInstancePtrResult,
  1.1095 +               EventTarget* aOwner,
  1.1096 +               nsPresContext* aPresContext,
  1.1097 +               WidgetEvent* aEvent) 
  1.1098 +{
  1.1099 +  Event* it = new Event(aOwner, aPresContext, aEvent);
  1.1100 +  NS_ADDREF(it);
  1.1101 +  *aInstancePtrResult = static_cast<Event*>(it);
  1.1102 +  return NS_OK;
  1.1103 +}

mercurial