Event
Represents an event argument.
using AngleSharp.Attributes;
using AngleSharp.Html;
using System;
using System.Collections.Generic;
using System.Linq;
namespace AngleSharp.Dom.Events
{
[DomName("Event")]
public class Event : EventArgs
{
private EventFlags _flags;
private EventPhase _phase;
private IEventTarget _current;
private IEventTarget _target;
private bool _bubbles;
private bool _cancelable;
private string _type;
private DateTime _time;
internal EventFlags Flags => _flags;
[DomName("type")]
public string Type {
get {
return _type;
}
}
[DomName("target")]
public IEventTarget OriginalTarget {
get { get; }
}
[DomName("currentTarget")]
public IEventTarget CurrentTarget {
get {
return _current;
}
}
[DomName("eventPhase")]
public EventPhase Phase {
get {
return _phase;
}
}
[DomName("bubbles")]
public bool IsBubbling {
get {
return _bubbles;
}
}
[DomName("cancelable")]
public bool IsCancelable {
get {
return _cancelable;
}
}
[DomName("defaultPrevented")]
public bool IsDefaultPrevented {
get {
return (_flags & EventFlags.Canceled) == EventFlags.Canceled;
}
}
[DomName("isTrusted")]
public bool IsTrusted { get; set; }
[DomName("timeStamp")]
public DateTime Time {
get {
return _time;
}
}
public Event()
{
_flags = EventFlags.None;
_phase = EventPhase.None;
_time = DateTime.Now;
}
[DomConstructor]
[DomInitDict(1, true)]
public Event(string type, bool bubbles = false, bool cancelable = false)
: this()
{
Init(type, bubbles, cancelable);
}
[DomName("stopPropagation")]
public void Stop()
{
_flags |= EventFlags.StopPropagation;
}
[DomName("stopImmediatePropagation")]
public void StopImmediately()
{
_flags |= EventFlags.StopImmediatePropagation;
}
[DomName("preventDefault")]
public void Cancel()
{
if (_cancelable)
_flags |= EventFlags.Canceled;
}
[DomName("initEvent")]
public void Init(string type, bool bubbles, bool cancelable)
{
_flags |= EventFlags.Initialized;
if ((_flags & EventFlags.Dispatch) != EventFlags.Dispatch) {
_flags &= ~(EventFlags.StopPropagation | EventFlags.StopImmediatePropagation | EventFlags.Canceled);
IsTrusted = false;
_target = null;
_type = type;
_bubbles = bubbles;
_cancelable = cancelable;
}
}
internal bool Dispatch(IEventTarget target)
{
_flags |= EventFlags.Dispatch;
_target = target;
List<IEventTarget> list = new List<IEventTarget>();
Node node = target as Node;
if (node != null) {
while ((node = node.Parent) != null) {
list.Add(node);
}
}
_phase = EventPhase.Capturing;
DispatchAt(Enumerable.Reverse(list));
_phase = EventPhase.AtTarget;
if ((_flags & EventFlags.StopPropagation) != EventFlags.StopPropagation)
CallListeners(target);
if (_bubbles) {
_phase = EventPhase.Bubbling;
DispatchAt(list);
}
_flags &= ~EventFlags.Dispatch;
_phase = EventPhase.None;
_current = null;
return (_flags & EventFlags.Canceled) == EventFlags.Canceled;
}
private void CallListeners(IEventTarget target)
{
_current = target;
target.InvokeEventListener(this);
}
private void DispatchAt(IEnumerable<IEventTarget> targets)
{
foreach (IEventTarget target in targets) {
CallListeners(target);
if ((_flags & EventFlags.StopPropagation) == EventFlags.StopPropagation)
break;
}
}
}
}