/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "domstubs.idl"

interface nsIDOMEventTarget;

[ptr] native WidgetEventPtr(mozilla::WidgetEvent);
[ptr] native DOMEventPtr(mozilla::dom::Event);
[ptr] native IPCMessagePtr(IPC::Message);
[ptr] native ConstIPCMessagePtr(const IPC::Message);
[ptr] native EventTargetPtr(mozilla::dom::EventTarget);
%{C++
#ifdef ERROR
#undef ERROR
#endif

#include "mozilla/EventForwards.h"
class nsPresContext;
class nsInvalidateRequestList;
namespace IPC {
class Message;
}
namespace mozilla {
namespace dom {
class Event;
class EventTarget;
} // namespace dom
} // namespace mozilla
%}

/**
 * The nsIDOMEvent interface is the primary datatype for all events in
 * the Document Object Model.
 *
 * For more information on this interface please see 
 * http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html and
 * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
 */

[scriptable, builtinclass, uuid(02d54f52-a1f5-4ad2-b560-36f14012935e)]
interface nsIDOMEvent : nsISupports
{
  // PhaseType
  /**
   * The event isn't being dispatched.
   */
  const unsigned short      NONE                           = 0;
  /**
   * The current event phase is the capturing phase.
   */
  const unsigned short      CAPTURING_PHASE                = 1;

  /**
   * The event is currently being evaluated at the target EventTarget.
   */
  const unsigned short      AT_TARGET                      = 2;

  /**
   * The current event phase is the bubbling phase.
   */
  const unsigned short      BUBBLING_PHASE                 = 3;

  /**
   * The name of the event (case-insensitive). The name must be an XML 
   * name.
   */
  readonly attribute DOMString          type;

  /**
   * Used to indicate the EventTarget to which the event was originally 
   * dispatched.
   */
  readonly attribute nsIDOMEventTarget  target;

  /**
   * Used to indicate the EventTarget whose EventListeners are currently 
   * being processed. This is particularly useful during capturing and 
   * bubbling.
   */
  readonly attribute nsIDOMEventTarget  currentTarget;

  /**
   * Used to indicate which phase of event flow is currently being 
   * evaluated.
   */
  readonly attribute unsigned short     eventPhase;

  /**
   * Used to indicate whether or not an event is a bubbling event. If the 
   * event can bubble the value is true, else the value is false.
   */
  readonly attribute boolean            bubbles;

  /**
   * Used to indicate whether or not an event can have its default action 
   * prevented. If the default action can be prevented the value is true, 
   * else the value is false.
   */
  readonly attribute boolean            cancelable;

  /**
   * Used to specify the time (in milliseconds relative to the epoch) at 
   * which the event was created. Due to the fact that some systems may 
   * not provide this information the value of timeStamp may be not 
   * available for all events. When not available, a value of 0 will be 
   * returned. Examples of epoch time are the time of the system start or 
   * 0:0:0 UTC 1st January 1970.
   */
  readonly attribute DOMTimeStamp       timeStamp;

  /**
   * The stopPropagation method is used prevent further propagation of an 
   * event during event flow. If this method is called by any 
   * EventListener the event will cease propagating through the tree. The 
   * event will complete dispatch to all listeners on the current 
   * EventTarget before event flow stops. This method may be used during 
   * any stage of event flow.
   */
  void                      stopPropagation();

  /**
   * If an event is cancelable, the preventDefault method is used to 
   * signify that the event is to be canceled, meaning any default action 
   * normally taken by the implementation as a result of the event will 
   * not occur. If, during any stage of event flow, the preventDefault 
   * method is called the event is canceled. Any default action associated 
   * with the event will not occur. Calling this method for a 
   * non-cancelable event has no effect. Once preventDefault has been 
   * called it will remain in effect throughout the remainder of the 
   * event's propagation. This method may be used during any stage of 
   * event flow.
   */
  void                      preventDefault();

  /**
   * The initEvent method is used to initialize the value of an Event 
   * created through the DocumentEvent interface. This method may only be 
   * called before the Event has been dispatched via the dispatchEvent 
   * method, though it may be called multiple times during that phase if 
   * necessary. If called multiple times the final invocation takes 
   * precedence. If called from a subclass of Event interface only the 
   * values specified in the initEvent method are modified, all other 
   * attributes are left unchanged.
   *
   * @param   eventTypeArg Specifies the event type. This type may be 
   *                       any event type currently defined in this 
   *                       specification or a new event type.. The string 
   *                       must be an XML name.
   *                       Any new event type must not begin with any 
   *                       upper, lower, or mixed case version of the 
   *                       string "DOM". This prefix is reserved for 
   *                       future DOM event sets. It is also strongly 
   *                       recommended that third parties adding their 
   *                       own events use their own prefix to avoid 
   *                       confusion and lessen the probability of 
   *                       conflicts with other new events.
   * @param   canBubbleArg Specifies whether or not the event can bubble.
   * @param   cancelableArg Specifies whether or not the event's default 
   *                        action can be prevented.
   */
  void                      initEvent(in DOMString eventTypeArg,
                                      in boolean canBubbleArg,
                                      in boolean cancelableArg);

  /**
   * Used to indicate whether preventDefault() has been called for this event.
   */
  readonly attribute boolean defaultPrevented;

  /**
   * Prevents other event listeners from being triggered and,
   * unlike Event.stopPropagation() its effect is immediate.
   */
  void                       stopImmediatePropagation();

  const long ALT_MASK     = 0x00000001;
  const long CONTROL_MASK = 0x00000002;
  const long SHIFT_MASK   = 0x00000004;
  const long META_MASK    = 0x00000008;

  /** The original target of the event, before any retargetings. */
  readonly attribute nsIDOMEventTarget  originalTarget;
  /**
   * The explicit original target of the event.  If the event was retargeted
   * for some reason other than an anonymous boundary crossing, this will be set
   * to the target before the retargeting occurs.  For example, mouse events
   * are retargeted to their parent node when they happen over text nodes (bug
   * 185889), and in that case .target will show the parent and
   * .explicitOriginalTarget will show the text node.
   * .explicitOriginalTarget differs from .originalTarget in that it will never
   * contain anonymous content.
   */
  readonly attribute nsIDOMEventTarget  explicitOriginalTarget;

  /**
   * @deprecated Use nsIDOMEvent::defaultPrevented.
   * To be removed in bug 691151.
   */
  boolean                   getPreventDefault();

  readonly attribute boolean isTrusted;

  [noscript] void duplicatePrivateData();
  [noscript] void setTarget(in nsIDOMEventTarget aTarget);
  [notxpcom] boolean IsDispatchStopped();
  [notxpcom] WidgetEventPtr GetInternalNSEvent();
  [noscript,notxpcom] void SetTrusted(in boolean aTrusted);
  [notxpcom] void Serialize(in IPCMessagePtr aMsg,
                            in boolean aSerializeInterfaceType);
  [notxpcom] boolean Deserialize(in ConstIPCMessagePtr aMsg, out voidPtr aIter);
  [noscript,notxpcom] void SetOwner(in EventTargetPtr aOwner);
  [notxpcom] DOMEventPtr InternalDOMEvent();
};

dictionary EventInit
{
  boolean bubbles;
  boolean cancelable;
};

%{C++

nsresult
NS_NewDOMEvent(nsIDOMEvent** aInstancePtrResult,
               mozilla::dom::EventTarget* aOwner,
               nsPresContext* aPresContext,
               mozilla::WidgetEvent* aEvent);
nsresult
NS_NewDOMDataContainerEvent(nsIDOMEvent** aInstancePtrResult,
                            mozilla::dom::EventTarget* aOwner,
                            nsPresContext* aPresContext,
                            mozilla::WidgetEvent* aEvent);
nsresult
NS_NewDOMUIEvent(nsIDOMEvent** aInstancePtrResult,
                 mozilla::dom::EventTarget* aOwner,
                 nsPresContext* aPresContext,
                 mozilla::WidgetGUIEvent* aEvent);
nsresult
NS_NewDOMMouseEvent(nsIDOMEvent** aInstancePtrResult,
                    mozilla::dom::EventTarget* aOwner,
                    nsPresContext* aPresContext,
                    mozilla::WidgetMouseEvent* aEvent);
nsresult
NS_NewDOMFocusEvent(nsIDOMEvent** aInstancePtrResult,
                    mozilla::dom::EventTarget* aOwner,
                    nsPresContext* aPresContext,
                    mozilla::InternalFocusEvent* aEvent);
nsresult
NS_NewDOMMouseScrollEvent(nsIDOMEvent** aInstancePtrResult,
                          mozilla::dom::EventTarget* aOwner,
                          nsPresContext* aPresContext,
                          mozilla::WidgetMouseScrollEvent* aEvent);
nsresult
NS_NewDOMWheelEvent(nsIDOMEvent** aInstancePtrResult,
                    mozilla::dom::EventTarget* aOwner,
                    nsPresContext* aPresContext,
                    mozilla::WidgetWheelEvent* aEvent);
nsresult
NS_NewDOMDragEvent(nsIDOMEvent** aInstancePtrResult,
                   mozilla::dom::EventTarget* aOwner,
                   nsPresContext* aPresContext,
                   mozilla::WidgetDragEvent* aEvent);
nsresult
NS_NewDOMClipboardEvent(nsIDOMEvent** aInstancePtrResult,
                        mozilla::dom::EventTarget* aOwner,
                        nsPresContext* aPresContext,
                        mozilla::InternalClipboardEvent* aEvent);

nsresult
NS_NewDOMKeyboardEvent(nsIDOMEvent** aInstancePtrResult,
                       mozilla::dom::EventTarget* aOwner,
                       nsPresContext* aPresContext,
                       mozilla::WidgetKeyboardEvent* aEvent);
nsresult
NS_NewDOMCompositionEvent(nsIDOMEvent** aInstancePtrResult,
                          mozilla::dom::EventTarget* aOwner,
                          nsPresContext* aPresContext,
                          mozilla::WidgetCompositionEvent* aEvent);
nsresult
NS_NewDOMMutationEvent(nsIDOMEvent** aResult,
                       mozilla::dom::EventTarget* aOwner,
                       nsPresContext* aPresContext,
                       mozilla::InternalMutationEvent* aEvent);
nsresult
NS_NewDOMDeviceMotionEvent(nsIDOMEvent** aResult,
                           mozilla::dom::EventTarget* aOwner,
                           nsPresContext* aPresContext,
                           mozilla::WidgetEvent* aEvent);
nsresult
NS_NewDOMTextEvent(nsIDOMEvent** aResult,
                   mozilla::dom::EventTarget* aOwner,
                   nsPresContext* aPresContext,
                   mozilla::WidgetTextEvent* aEvent);
nsresult
NS_NewDOMBeforeUnloadEvent(nsIDOMEvent** aResult,
                           mozilla::dom::EventTarget* aOwner,
                           nsPresContext* aPresContext,
                           mozilla::WidgetEvent* aEvent);
nsresult
NS_NewDOMSVGEvent(nsIDOMEvent** aResult,
                  mozilla::dom::EventTarget* aOwner,
                  nsPresContext* aPresContext,
                  mozilla::WidgetEvent* aEvent);
nsresult
NS_NewDOMSVGZoomEvent(nsIDOMEvent** aResult,
                      mozilla::dom::EventTarget* aOwner,
                      nsPresContext* aPresContext,
                      mozilla::WidgetGUIEvent* aEvent);
nsresult
NS_NewDOMTimeEvent(nsIDOMEvent** aResult,
                   mozilla::dom::EventTarget* aOwner,
                   nsPresContext* aPresContext,
                   mozilla::WidgetEvent* aEvent);
nsresult
NS_NewDOMXULCommandEvent(nsIDOMEvent** aResult,
                         mozilla::dom::EventTarget* aOwner,
                         nsPresContext* aPresContext,
                         mozilla::WidgetInputEvent* aEvent);
nsresult
NS_NewDOMCommandEvent(nsIDOMEvent** aInstancePtrResult,
                      mozilla::dom::EventTarget* aOwner,
                      nsPresContext* aPresContext,
                      mozilla::WidgetCommandEvent* aEvent);
nsresult
NS_NewDOMMessageEvent(nsIDOMEvent** aInstancePtrResult,
                      mozilla::dom::EventTarget* aOwner,
                      nsPresContext* aPresContext,
                      mozilla::WidgetEvent* aEvent);
nsresult
NS_NewDOMProgressEvent(nsIDOMEvent** aInstancePtrResult,
                       mozilla::dom::EventTarget* aOwner,
                       nsPresContext* aPresContext,
                       mozilla::WidgetEvent* aEvent);
// This empties aInvalidateRequests.
nsresult
NS_NewDOMNotifyPaintEvent(nsIDOMEvent** aResult,
                          mozilla::dom::EventTarget* aOwner,
                          nsPresContext* aPresContext,
                          mozilla::WidgetEvent* aEvent,
                          uint32_t aEventType = 0,
                          nsInvalidateRequestList* aInvalidateRequests = nullptr);
nsresult
NS_NewDOMAudioAvailableEvent(nsIDOMEvent** aResult,
                             mozilla::dom::EventTarget* aOwner,
                             nsPresContext* aPresContext,
                             mozilla::WidgetEvent* aEvent,
                             uint32_t aEventType = 0,
                             float* aFrameBuffer = nullptr,
                             uint32_t aFrameBufferLength = 0,
                             float aTime = 0);
nsresult
NS_NewDOMSimpleGestureEvent(nsIDOMEvent** aInstancePtrResult,
                            mozilla::dom::EventTarget* aOwner,
                            nsPresContext* aPresContext,
                            mozilla::WidgetSimpleGestureEvent* aEvent);
nsresult
NS_NewDOMScrollAreaEvent(nsIDOMEvent** aInstancePtrResult,
                         mozilla::dom::EventTarget* aOwner,
                         nsPresContext* aPresContext,
                         mozilla::InternalScrollAreaEvent* aEvent);
nsresult
NS_NewDOMTransitionEvent(nsIDOMEvent** aInstancePtrResult,
                         mozilla::dom::EventTarget* aOwner,
                         nsPresContext* aPresContext,
                         mozilla::InternalTransitionEvent* aEvent);
nsresult
NS_NewDOMAnimationEvent(nsIDOMEvent** aInstancePtrResult,
                        mozilla::dom::EventTarget* aOwner,
                        nsPresContext* aPresContext,
                        mozilla::InternalAnimationEvent* aEvent);
nsresult
NS_NewDOMPointerEvent(nsIDOMEvent** aInstancePtrResult,
                      mozilla::dom::EventTarget* aOwner,
                      nsPresContext* aPresContext,
                      mozilla::WidgetPointerEvent* aEvent);
nsresult
NS_NewDOMTouchEvent(nsIDOMEvent** aInstancePtrResult,
                    mozilla::dom::EventTarget* aOwner,
                    nsPresContext* aPresContext,
                    mozilla::WidgetTouchEvent* aEvent);
nsresult
NS_NewDOMMozSettingsEvent(nsIDOMEvent** aInstancePtrResult,
                          mozilla::dom::EventTarget* aOwner,
                          nsPresContext* aPresContext,
                          mozilla::WidgetEvent* aEvent);
nsresult
NS_NewDOMMozApplicationEvent(nsIDOMEvent** aInstancePtrResult,
                             mozilla::dom::EventTarget* aOwner,
                             nsPresContext* aPresContext,
                             mozilla::WidgetEvent* aEvent);
%}
