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.HasFlag(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;
}
[DomInitDict(1, true)]
[DomConstructor]
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.HasFlag(EventFlags.Dispatch)) {
_flags &= ~(EventFlags.StopPropagation | EventFlags.StopImmediatePropagation | EventFlags.Canceled);
IsTrusted = false;
_target = null;
_type = type;
_bubbles = bubbles;
_cancelable = cancelable;
}
}
internal bool Dispatch(EventTarget target)
{
_flags |= EventFlags.Dispatch;
_target = target;
List<EventTarget> list = new List<EventTarget>();
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.HasFlag(EventFlags.StopPropagation))
CallListeners(target);
if (_bubbles) {
_phase = EventPhase.Bubbling;
DispatchAt(list);
}
_flags &= ~EventFlags.Dispatch;
_phase = EventPhase.None;
_current = null;
return _flags.HasFlag(EventFlags.Canceled);
}
private void CallListeners(EventTarget target)
{
_current = target;
target.CallEventListener(this);
}
private void DispatchAt(IEnumerable<EventTarget> targets)
{
foreach (EventTarget target in targets) {
CallListeners(target);
if (_flags.HasFlag(EventFlags.StopPropagation))
break;
}
}
}
}