Document
public abstract class Document : Node, IDocument, INode, IEventTarget, IMarkupFormattable, IParentNode, IGlobalEventHandlers, IDocumentStyle, INonElementParentNode, IDisposable
Represents a document node.
using AngleSharp.Browser;
using AngleSharp.Browser.Dom;
using AngleSharp.Common;
using AngleSharp.Css.Dom;
using AngleSharp.Dom.Events;
using AngleSharp.Html.Dom;
using AngleSharp.Io;
using AngleSharp.Mathml.Dom;
using AngleSharp.Svg.Dom;
using AngleSharp.Text;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
namespace AngleSharp.Dom
{
public abstract class Document : Node, IDocument, INode, IEventTarget, IMarkupFormattable, IParentNode, IGlobalEventHandlers, IDocumentStyle, INonElementParentNode, IDisposable
{
private readonly List<WeakReference> _attachedReferences;
private readonly Queue<HtmlScriptElement> _loadingScripts;
private readonly MutationHost _mutations;
private readonly IBrowsingContext _context;
private readonly IEventLoop _loop;
private readonly Window _view;
private readonly IResourceLoader _loader;
private readonly Location _location;
private readonly TextSource _source;
private QuirksMode _quirksMode;
private Sandboxes _sandbox;
private bool _async;
private bool _designMode;
private bool _shown;
private bool _salvageable;
private bool _firedUnload;
private DocumentReadyState _ready;
private IElement _focus;
private HtmlAllCollection _all;
private HtmlCollection<IHtmlAnchorElement> _anchors;
private HtmlCollection<IElement> _children;
private DomImplementation _implementation;
private IStringList _styleSheetSets;
private HtmlCollection<IHtmlImageElement> _images;
private HtmlCollection<IHtmlScriptElement> _scripts;
private HtmlCollection<IHtmlEmbedElement> _plugins;
private HtmlCollection<IElement> _commands;
private HtmlCollection<IElement> _links;
private IStyleSheetList _styleSheets;
private HttpStatusCode _statusCode;
public TextSource Source => _source;
public abstract IEntityProvider Entities { get; }
public IDocument ImportAncestor { get; set; }
public IEventLoop Loop => _loop;
public string DesignMode {
get {
if (!_designMode)
return Keywords.Off;
return Keywords.On;
}
set {
_designMode = value.Isi(Keywords.On);
}
}
public IHtmlAllCollection All => _all ?? (_all = new HtmlAllCollection(this));
public IHtmlCollection<IHtmlAnchorElement> Anchors => _anchors ?? (_anchors = new HtmlCollection<IHtmlAnchorElement>(this, true, IsAnchor));
public int ChildElementCount => base.ChildNodes.OfType<Element>().Count();
public IHtmlCollection<IElement> Children => _children ?? (_children = new HtmlCollection<IElement>(base.ChildNodes.OfType<Element>()));
public IElement FirstElementChild {
get {
NodeList childNodes = base.ChildNodes;
int length = childNodes.Length;
for (int i = 0; i < length; i++) {
IElement element = childNodes[i] as IElement;
if (element != null)
return element;
}
return null;
}
}
public IElement LastElementChild {
get {
NodeList childNodes = base.ChildNodes;
for (int num = childNodes.Length - 1; num >= 0; num--) {
IElement element = childNodes[num] as IElement;
if (element != null)
return element;
}
return null;
}
}
public bool IsAsync => _async;
public IHtmlScriptElement CurrentScript {
get {
if (_loadingScripts.Count <= 0)
return null;
return _loadingScripts.Peek();
}
}
public IImplementation Implementation => _implementation ?? (_implementation = new DomImplementation(this));
public string LastModified { get; set; }
public IDocumentType Doctype => this.FindChild<DocumentType>();
public string ContentType { get; set; }
public DocumentReadyState ReadyState {
get {
return _ready;
}
protected set {
_ready = value;
this.QueueTaskAsync((CancellationToken _) => this.FireSimpleEvent(EventNames.ReadyStateChanged, false, false));
}
}
public IStyleSheetList StyleSheets => _styleSheets ?? (_styleSheets = this.CreateStyleSheets());
public IStringList StyleSheetSets => _styleSheetSets ?? (_styleSheetSets = this.CreateStyleSheetSets());
public string Referrer { get; set; }
public ILocation Location => _location;
public string DocumentUri {
get {
return _location.Href;
}
protected set {
_location.Changed -= LocationChanged;
_location.Href = value;
_location.Changed += LocationChanged;
}
}
public Url DocumentUrl => _location.Original;
public IWindow DefaultView => _view;
public string Direction {
get {
return ((DocumentElement as IHtmlElement) ?? new HtmlHtmlElement(this, null)).Direction;
}
set {
((DocumentElement as IHtmlElement) ?? new HtmlHtmlElement(this, null)).Direction = value;
}
}
public string CharacterSet => _source.CurrentEncoding.WebName;
public abstract IElement DocumentElement { get; }
public IElement ActiveElement => (from m in All
where m.IsFocused
select m).FirstOrDefault();
public string CompatMode => _quirksMode.GetCompatiblity();
public string Url => _location.Href;
public IHtmlCollection<IHtmlFormElement> Forms => new HtmlCollection<IHtmlFormElement>(this, true, null);
public IHtmlCollection<IHtmlImageElement> Images => _images ?? (_images = new HtmlCollection<IHtmlImageElement>(this, true, null));
public IHtmlCollection<IHtmlScriptElement> Scripts => _scripts ?? (_scripts = new HtmlCollection<IHtmlScriptElement>(this, true, null));
public IHtmlCollection<IHtmlEmbedElement> Plugins => _plugins ?? (_plugins = new HtmlCollection<IHtmlEmbedElement>(this, true, null));
public IHtmlCollection<IElement> Commands => _commands ?? (_commands = new HtmlCollection<IElement>(this, true, IsCommand));
public IHtmlCollection<IElement> Links => _links ?? (_links = new HtmlCollection<IElement>(this, true, IsLink));
public string Title {
get {
return GetTitle();
}
set {
SetTitle(value);
}
}
public IHtmlHeadElement Head => DocumentElement.FindChild<IHtmlHeadElement>();
public IHtmlElement Body {
get {
IElement documentElement = DocumentElement;
if (documentElement != null) {
foreach (INode childNode in documentElement.ChildNodes) {
HtmlBodyElement htmlBodyElement = childNode as HtmlBodyElement;
if (htmlBodyElement != null)
return htmlBodyElement;
HtmlFrameSetElement htmlFrameSetElement = childNode as HtmlFrameSetElement;
if (htmlFrameSetElement != null)
return htmlFrameSetElement;
}
}
return null;
}
set {
if (!(value is IHtmlBodyElement) && !(value is HtmlFrameSetElement))
throw new DomException(DomError.HierarchyRequest);
IHtmlElement body = Body;
if (body != value) {
if (body == null) {
IElement documentElement = DocumentElement;
if (documentElement == null)
throw new DomException(DomError.HierarchyRequest);
documentElement.AppendChild(value);
} else
ReplaceChild(value, body);
}
}
}
public IBrowsingContext Context => _context;
public HttpStatusCode StatusCode {
get {
return _statusCode;
}
private set {
_statusCode = value;
}
}
public string Cookie {
get {
return _context.GetCookie(_location.Original);
}
set {
_context.SetCookie(_location.Original, value);
}
}
public string Domain {
get {
if (!string.IsNullOrEmpty(DocumentUri))
return new Uri(DocumentUri).Host;
return string.Empty;
}
set {
if (_location != null)
_location.Host = value;
}
}
public string Origin => _location.Origin;
public string SelectedStyleSheetSet {
get {
IEnumerable<string> enabledStyleSheetSets = StyleSheets.GetEnabledStyleSheetSets();
string enabledName = enabledStyleSheetSets.FirstOrDefault();
IEnumerable<IStyleSheet> source = StyleSheets.Where(delegate(IStyleSheet m) {
if (!string.IsNullOrEmpty(m.Title))
return !m.IsDisabled;
return false;
});
if (enabledStyleSheetSets.Count() == 1 && !source.Any((IStyleSheet m) => !m.Title.Is(enabledName)))
return enabledName;
if (source.Any())
return null;
return string.Empty;
}
set {
if (value != null) {
StyleSheets.EnableStyleSheetSet(value);
LastStyleSheetSet = value;
}
}
}
public string LastStyleSheetSet { get; set; }
public string PreferredStyleSheetSet => (from m in All.OfType<IHtmlLinkElement>()
where m.IsPreferred()
select m.Title).FirstOrDefault();
public bool IsReady => ReadyState == DocumentReadyState.Complete;
public bool IsLoading => ReadyState == DocumentReadyState.Loading;
internal MutationHost Mutations => _mutations;
internal QuirksMode QuirksMode {
get {
return _quirksMode;
}
set {
_quirksMode = value;
}
}
internal Sandboxes ActiveSandboxing {
get {
return _sandbox;
}
set {
_sandbox = value;
}
}
internal bool IsInBrowsingContext => _context.Active != null;
internal bool IsToBePrinted => false;
internal IElement FocusElement => _focus;
public event DomEventHandler ReadyStateChanged {
add {
AddEventListener(EventNames.ReadyStateChanged, value, false);
}
remove {
RemoveEventListener(EventNames.ReadyStateChanged, value, false);
}
}
public event DomEventHandler Aborted {
add {
AddEventListener(EventNames.Abort, value, false);
}
remove {
RemoveEventListener(EventNames.Abort, value, false);
}
}
public event DomEventHandler Blurred {
add {
AddEventListener(EventNames.Blur, value, false);
}
remove {
RemoveEventListener(EventNames.Blur, value, false);
}
}
public event DomEventHandler Cancelled {
add {
AddEventListener(EventNames.Cancel, value, false);
}
remove {
RemoveEventListener(EventNames.Cancel, value, false);
}
}
public event DomEventHandler CanPlay {
add {
AddEventListener(EventNames.CanPlay, value, false);
}
remove {
RemoveEventListener(EventNames.CanPlay, value, false);
}
}
public event DomEventHandler CanPlayThrough {
add {
AddEventListener(EventNames.CanPlayThrough, value, false);
}
remove {
RemoveEventListener(EventNames.CanPlayThrough, value, false);
}
}
public event DomEventHandler Changed {
add {
AddEventListener(EventNames.Change, value, false);
}
remove {
RemoveEventListener(EventNames.Change, value, false);
}
}
public event DomEventHandler Clicked {
add {
AddEventListener(EventNames.Click, value, false);
}
remove {
RemoveEventListener(EventNames.Click, value, false);
}
}
public event DomEventHandler CueChanged {
add {
AddEventListener(EventNames.CueChange, value, false);
}
remove {
RemoveEventListener(EventNames.CueChange, value, false);
}
}
public event DomEventHandler DoubleClick {
add {
AddEventListener(EventNames.DblClick, value, false);
}
remove {
RemoveEventListener(EventNames.DblClick, value, false);
}
}
public event DomEventHandler Drag {
add {
AddEventListener(EventNames.Drag, value, false);
}
remove {
RemoveEventListener(EventNames.Drag, value, false);
}
}
public event DomEventHandler DragEnd {
add {
AddEventListener(EventNames.DragEnd, value, false);
}
remove {
RemoveEventListener(EventNames.DragEnd, value, false);
}
}
public event DomEventHandler DragEnter {
add {
AddEventListener(EventNames.DragEnter, value, false);
}
remove {
RemoveEventListener(EventNames.DragEnter, value, false);
}
}
public event DomEventHandler DragExit {
add {
AddEventListener(EventNames.DragExit, value, false);
}
remove {
RemoveEventListener(EventNames.DragExit, value, false);
}
}
public event DomEventHandler DragLeave {
add {
AddEventListener(EventNames.DragLeave, value, false);
}
remove {
RemoveEventListener(EventNames.DragLeave, value, false);
}
}
public event DomEventHandler DragOver {
add {
AddEventListener(EventNames.DragOver, value, false);
}
remove {
RemoveEventListener(EventNames.DragOver, value, false);
}
}
public event DomEventHandler DragStart {
add {
AddEventListener(EventNames.DragStart, value, false);
}
remove {
RemoveEventListener(EventNames.DragStart, value, false);
}
}
public event DomEventHandler Dropped {
add {
AddEventListener(EventNames.Drop, value, false);
}
remove {
RemoveEventListener(EventNames.Drop, value, false);
}
}
public event DomEventHandler DurationChanged {
add {
AddEventListener(EventNames.DurationChange, value, false);
}
remove {
RemoveEventListener(EventNames.DurationChange, value, false);
}
}
public event DomEventHandler Emptied {
add {
AddEventListener(EventNames.Emptied, value, false);
}
remove {
RemoveEventListener(EventNames.Emptied, value, false);
}
}
public event DomEventHandler Ended {
add {
AddEventListener(EventNames.Ended, value, false);
}
remove {
RemoveEventListener(EventNames.Ended, value, false);
}
}
public event DomEventHandler Error {
add {
AddEventListener(EventNames.Error, value, false);
}
remove {
RemoveEventListener(EventNames.Error, value, false);
}
}
public event DomEventHandler Focused {
add {
AddEventListener(EventNames.Focus, value, false);
}
remove {
RemoveEventListener(EventNames.Focus, value, false);
}
}
public event DomEventHandler Input {
add {
AddEventListener(EventNames.Input, value, false);
}
remove {
RemoveEventListener(EventNames.Input, value, false);
}
}
public event DomEventHandler Invalid {
add {
AddEventListener(EventNames.Invalid, value, false);
}
remove {
RemoveEventListener(EventNames.Invalid, value, false);
}
}
public event DomEventHandler KeyDown {
add {
AddEventListener(EventNames.Keydown, value, false);
}
remove {
RemoveEventListener(EventNames.Keydown, value, false);
}
}
public event DomEventHandler KeyPress {
add {
AddEventListener(EventNames.Keypress, value, false);
}
remove {
RemoveEventListener(EventNames.Keypress, value, false);
}
}
public event DomEventHandler KeyUp {
add {
AddEventListener(EventNames.Keyup, value, false);
}
remove {
RemoveEventListener(EventNames.Keyup, value, false);
}
}
public event DomEventHandler Loaded {
add {
AddEventListener(EventNames.Load, value, false);
}
remove {
RemoveEventListener(EventNames.Load, value, false);
}
}
public event DomEventHandler LoadedData {
add {
AddEventListener(EventNames.LoadedData, value, false);
}
remove {
RemoveEventListener(EventNames.LoadedData, value, false);
}
}
public event DomEventHandler LoadedMetadata {
add {
AddEventListener(EventNames.LoadedMetaData, value, false);
}
remove {
RemoveEventListener(EventNames.LoadedMetaData, value, false);
}
}
public event DomEventHandler Loading {
add {
AddEventListener(EventNames.LoadStart, value, false);
}
remove {
RemoveEventListener(EventNames.LoadStart, value, false);
}
}
public event DomEventHandler MouseDown {
add {
AddEventListener(EventNames.Mousedown, value, false);
}
remove {
RemoveEventListener(EventNames.Mousedown, value, false);
}
}
public event DomEventHandler MouseEnter {
add {
AddEventListener(EventNames.Mouseenter, value, false);
}
remove {
RemoveEventListener(EventNames.Mouseenter, value, false);
}
}
public event DomEventHandler MouseLeave {
add {
AddEventListener(EventNames.Mouseleave, value, false);
}
remove {
RemoveEventListener(EventNames.Mouseleave, value, false);
}
}
public event DomEventHandler MouseMove {
add {
AddEventListener(EventNames.Mousemove, value, false);
}
remove {
RemoveEventListener(EventNames.Mousemove, value, false);
}
}
public event DomEventHandler MouseOut {
add {
AddEventListener(EventNames.Mouseout, value, false);
}
remove {
RemoveEventListener(EventNames.Mouseout, value, false);
}
}
public event DomEventHandler MouseOver {
add {
AddEventListener(EventNames.Mouseover, value, false);
}
remove {
RemoveEventListener(EventNames.Mouseover, value, false);
}
}
public event DomEventHandler MouseUp {
add {
AddEventListener(EventNames.Mouseup, value, false);
}
remove {
RemoveEventListener(EventNames.Mouseup, value, false);
}
}
public event DomEventHandler MouseWheel {
add {
AddEventListener(EventNames.Wheel, value, false);
}
remove {
RemoveEventListener(EventNames.Wheel, value, false);
}
}
public event DomEventHandler Paused {
add {
AddEventListener(EventNames.Pause, value, false);
}
remove {
RemoveEventListener(EventNames.Pause, value, false);
}
}
public event DomEventHandler Played {
add {
AddEventListener(EventNames.Play, value, false);
}
remove {
RemoveEventListener(EventNames.Play, value, false);
}
}
public event DomEventHandler Playing {
add {
AddEventListener(EventNames.Playing, value, false);
}
remove {
RemoveEventListener(EventNames.Playing, value, false);
}
}
public event DomEventHandler Progress {
add {
AddEventListener(EventNames.Progress, value, false);
}
remove {
RemoveEventListener(EventNames.Progress, value, false);
}
}
public event DomEventHandler RateChanged {
add {
AddEventListener(EventNames.RateChange, value, false);
}
remove {
RemoveEventListener(EventNames.RateChange, value, false);
}
}
public event DomEventHandler Resetted {
add {
AddEventListener(EventNames.Reset, value, false);
}
remove {
RemoveEventListener(EventNames.Reset, value, false);
}
}
public event DomEventHandler Resized {
add {
AddEventListener(EventNames.Resize, value, false);
}
remove {
RemoveEventListener(EventNames.Resize, value, false);
}
}
public event DomEventHandler Scrolled {
add {
AddEventListener(EventNames.Scroll, value, false);
}
remove {
RemoveEventListener(EventNames.Scroll, value, false);
}
}
public event DomEventHandler Seeked {
add {
AddEventListener(EventNames.Seeked, value, false);
}
remove {
RemoveEventListener(EventNames.Seeked, value, false);
}
}
public event DomEventHandler Seeking {
add {
AddEventListener(EventNames.Seeking, value, false);
}
remove {
RemoveEventListener(EventNames.Seeking, value, false);
}
}
public event DomEventHandler Selected {
add {
AddEventListener(EventNames.Select, value, false);
}
remove {
RemoveEventListener(EventNames.Select, value, false);
}
}
public event DomEventHandler Shown {
add {
AddEventListener(EventNames.Show, value, false);
}
remove {
RemoveEventListener(EventNames.Show, value, false);
}
}
public event DomEventHandler Stalled {
add {
AddEventListener(EventNames.Stalled, value, false);
}
remove {
RemoveEventListener(EventNames.Stalled, value, false);
}
}
public event DomEventHandler Submitted {
add {
AddEventListener(EventNames.Submit, value, false);
}
remove {
RemoveEventListener(EventNames.Submit, value, false);
}
}
public event DomEventHandler Suspended {
add {
AddEventListener(EventNames.Suspend, value, false);
}
remove {
RemoveEventListener(EventNames.Suspend, value, false);
}
}
public event DomEventHandler TimeUpdated {
add {
AddEventListener(EventNames.TimeUpdate, value, false);
}
remove {
RemoveEventListener(EventNames.TimeUpdate, value, false);
}
}
public event DomEventHandler Toggled {
add {
AddEventListener(EventNames.Toggle, value, false);
}
remove {
RemoveEventListener(EventNames.Toggle, value, false);
}
}
public event DomEventHandler VolumeChanged {
add {
AddEventListener(EventNames.VolumeChange, value, false);
}
remove {
RemoveEventListener(EventNames.VolumeChange, value, false);
}
}
public event DomEventHandler Waiting {
add {
AddEventListener(EventNames.Waiting, value, false);
}
remove {
RemoveEventListener(EventNames.Waiting, value, false);
}
}
public Document(IBrowsingContext context, TextSource source)
: base(null, "#document", NodeType.Document, NodeFlags.None)
{
Referrer = string.Empty;
ContentType = MimeTypeNames.ApplicationXml;
_attachedReferences = new List<WeakReference>();
_async = true;
_designMode = false;
_firedUnload = false;
_salvageable = true;
_shown = false;
_context = context;
_source = source;
_ready = DocumentReadyState.Loading;
_sandbox = Sandboxes.None;
_quirksMode = QuirksMode.Off;
_loadingScripts = new Queue<HtmlScriptElement>();
_location = new Location("about:blank");
_location.Changed += LocationChanged;
_view = new Window(this);
_loader = context.GetService<IResourceLoader>();
_loop = context.GetService<IEventLoop>();
_mutations = new MutationHost(_loop);
_statusCode = HttpStatusCode.OK;
}
internal void AddScript(HtmlScriptElement script)
{
_loadingScripts.Enqueue(script);
}
public void Clear()
{
ReplaceAll(null, true);
}
public void Dispose()
{
Clear();
_loop?.CancelAll();
_loadingScripts.Clear();
_source.Dispose();
_view?.Dispose();
}
public void EnableStyleSheetsForSet(string name)
{
if (name != null)
StyleSheets.EnableStyleSheetSet(name);
}
public IDocument Open(string type = "text/html", string replace = null)
{
if (!ContentType.Is(MimeTypeNames.Html))
throw new DomException(DomError.InvalidState);
if (!IsInBrowsingContext || _context.Active == this) {
IDocument document = _context?.Parent.Active;
if (document != null && !document.Origin.Is(Origin))
throw new DomException(DomError.Security);
if (!_firedUnload && _loadingScripts.Count == 0) {
bool num = replace.Isi(Keywords.Replace);
IHistory sessionHistory = _context.SessionHistory;
int num2 = type?.IndexOf(';') ?? (-1);
if (!num && sessionHistory != null) {
bool num3 = sessionHistory.Length == 1 && sessionHistory[0].Url.Is("about:blank");
}
_salvageable = false;
if (!PromptToUnloadAsync().Result)
return this;
Unload(true).Wait();
Abort(false);
RemoveEventListeners();
foreach (Element item in this.Descendents<Element>()) {
item.RemoveEventListeners();
}
_loop?.CancelAll();
ReplaceAll(null, true);
_source.CurrentEncoding = TextEncoding.Utf8;
_salvageable = true;
_ready = DocumentReadyState.Loading;
if (type.Isi(Keywords.Replace))
type = MimeTypeNames.Html;
else if (num2 >= 0) {
type = type.Substring(0, num2);
}
type = type.StripLeadingTrailingSpaces();
type.Isi(MimeTypeNames.Html);
ContentType = type;
_firedUnload = false;
_source.Index = _source.Length;
}
return this;
}
return null;
}
public void Load(string url)
{
Location.Href = url;
}
void IDocument.Close()
{
if (IsLoading)
FinishLoadingAsync().Wait();
}
public void Write(string content)
{
if (IsReady) {
string content2 = content ?? string.Empty;
Open("text/html", null).Write(content2);
} else
_source.InsertText(content);
}
public void WriteLine(string content)
{
Write(content + "\n");
}
public IHtmlCollection<IElement> GetElementsByName(string name)
{
List<IElement> list = new List<IElement>();
base.ChildNodes.GetElementsByName(name, list);
return new HtmlCollection<IElement>(list);
}
public INode Import(INode externalNode, bool deep = true)
{
if (externalNode.NodeType == NodeType.Document)
throw new DomException(DomError.NotSupported);
return externalNode.Clone(deep);
}
public INode Adopt(INode externalNode)
{
if (externalNode.NodeType == NodeType.Document)
throw new DomException(DomError.NotSupported);
this.AdoptNode(externalNode);
return externalNode;
}
public Event CreateEvent(string type)
{
Event event = _context.GetFactory<IEventFactory>().Create(type);
if (event == null)
throw new DomException(DomError.NotSupported);
return event;
}
public INodeIterator CreateNodeIterator(INode root, FilterSettings settings = FilterSettings.All, NodeFilter filter = null)
{
return new NodeIterator(root, settings, filter);
}
public ITreeWalker CreateTreeWalker(INode root, FilterSettings settings = FilterSettings.All, NodeFilter filter = null)
{
return new TreeWalker(root, settings, filter);
}
public IRange CreateRange()
{
Range range = new Range(this);
AttachReference(range);
return range;
}
public void Prepend(params INode[] nodes)
{
this.PrependNodes(nodes);
}
public void Append(params INode[] nodes)
{
this.AppendNodes(nodes);
}
public IElement CreateElement(string localName)
{
if (localName.IsXmlName()) {
HtmlElement htmlElement = _context.GetFactory<IElementFactory<Document, HtmlElement>>().Create(this, localName, null, NodeFlags.None);
htmlElement.SetupElement();
return htmlElement;
}
throw new DomException(DomError.InvalidCharacter);
}
public IElement CreateElement(string namespaceUri, string qualifiedName)
{
Node.GetPrefixAndLocalName(qualifiedName, ref namespaceUri, out string prefix, out string localName);
if (namespaceUri.Is(NamespaceNames.HtmlUri)) {
HtmlElement htmlElement = _context.GetFactory<IElementFactory<Document, HtmlElement>>().Create(this, localName, prefix, NodeFlags.None);
htmlElement.SetupElement();
return htmlElement;
}
if (namespaceUri.Is(NamespaceNames.SvgUri)) {
SvgElement svgElement = _context.GetFactory<IElementFactory<Document, SvgElement>>().Create(this, localName, prefix, NodeFlags.None);
svgElement.SetupElement();
return svgElement;
}
if (namespaceUri.Is(NamespaceNames.MathMlUri)) {
MathElement mathElement = _context.GetFactory<IElementFactory<Document, MathElement>>().Create(this, localName, prefix, NodeFlags.None);
mathElement.SetupElement();
return mathElement;
}
AnyElement anyElement = new AnyElement(this, localName, prefix, namespaceUri, NodeFlags.None);
anyElement.SetupElement();
return anyElement;
}
public IComment CreateComment(string data)
{
return new Comment(this, data);
}
public IDocumentFragment CreateDocumentFragment()
{
return new DocumentFragment(this);
}
public IProcessingInstruction CreateProcessingInstruction(string target, string data)
{
if (!target.IsXmlName() || data.Contains("?>"))
throw new DomException(DomError.InvalidCharacter);
return new ProcessingInstruction(this, target) {
Data = data
};
}
public IText CreateTextNode(string data)
{
return new TextNode(this, data);
}
public IElement GetElementById(string elementId)
{
return base.ChildNodes.GetElementById(elementId);
}
public IElement QuerySelector(string selectors)
{
return base.ChildNodes.QuerySelector(selectors, DocumentElement);
}
public IHtmlCollection<IElement> QuerySelectorAll(string selectors)
{
return base.ChildNodes.QuerySelectorAll(selectors, DocumentElement);
}
public IHtmlCollection<IElement> GetElementsByClassName(string classNames)
{
return base.ChildNodes.GetElementsByClassName(classNames);
}
public IHtmlCollection<IElement> GetElementsByTagName(string tagName)
{
return base.ChildNodes.GetElementsByTagName(tagName);
}
public IHtmlCollection<IElement> GetElementsByTagName(string namespaceURI, string tagName)
{
return base.ChildNodes.GetElementsByTagName(namespaceURI, tagName);
}
public bool HasFocus()
{
return _context.Active == this;
}
public IAttr CreateAttribute(string localName)
{
if (!localName.IsXmlName())
throw new DomException(DomError.InvalidCharacter);
return new Attr(localName);
}
public IAttr CreateAttribute(string namespaceUri, string qualifiedName)
{
Node.GetPrefixAndLocalName(qualifiedName, ref namespaceUri, out string prefix, out string localName);
return new Attr(prefix, localName, string.Empty, namespaceUri);
}
public void Setup(IResponse response, MimeType contentType, IDocument importAncestor)
{
ContentType = contentType.Content;
StatusCode = response.StatusCode;
Referrer = response.Headers.GetOrDefault(HeaderNames.Referer, string.Empty);
DocumentUri = response.Address.Href;
Cookie = response.Headers.GetOrDefault(HeaderNames.SetCookie, string.Empty);
ImportAncestor = importAncestor;
ReadyState = DocumentReadyState.Loading;
}
public abstract Element CreateElementFrom(string name, string prefix, NodeFlags flags = NodeFlags.None);
public void DelayLoad(Task task)
{
if (!IsReady && task != null && !task.IsCompleted)
AttachReference(task);
}
internal IEnumerable<T> GetAttachedReferences<T>() where T : class
{
return from m in _attachedReferences.Select(delegate(WeakReference entry) {
if (!entry.IsAlive)
return null;
return entry.Target as T;
})
where m != null
select m;
}
internal void AttachReference(object value)
{
_attachedReferences.Add(new WeakReference(value));
}
internal void SetFocus(IElement element)
{
_focus = element;
}
internal async Task FinishLoadingAsync()
{
Task[] tasks = GetAttachedReferences<Task>().ToArray();
ReadyState = DocumentReadyState.Interactive;
while (_loadingScripts.Count > 0) {
await this.WaitForReadyAsync().ConfigureAwait(false);
await _loadingScripts.Dequeue().RunAsync(CancellationToken.None).ConfigureAwait(false);
}
await this.QueueTaskAsync(delegate {
this.FireSimpleEvent(EventNames.DomContentLoaded, false, false);
_view.FireSimpleEvent(EventNames.DomContentLoaded, false, false);
}).ConfigureAwait(false);
await Task.WhenAll(tasks).ConfigureAwait(false);
await this.QueueTaskAsync(delegate {
ReadyState = DocumentReadyState.Complete;
Body?.FireSimpleEvent(EventNames.Load, false, false);
this.FireSimpleEvent(EventNames.Load, false, false);
_view.FireSimpleEvent(EventNames.Load, false, false);
}).ConfigureAwait(false);
if (IsInBrowsingContext && !_shown) {
_shown = true;
await this.QueueTaskAsync(delegate {
this.Fire(delegate(PageTransitionEvent ev) {
ev.Init(EventNames.PageShow, false, false, false);
}, _view);
}).ConfigureAwait(false);
}
this.QueueTask(EmptyAppCache);
if (IsToBePrinted)
await PrintAsync().ConfigureAwait(false);
}
internal async Task<bool> PromptToUnloadAsync()
{
IEnumerable<IBrowsingContext> descendants = GetAttachedReferences<IBrowsingContext>();
if (_view.HasEventListener(EventNames.BeforeUnload)) {
Event unloadEvent = new Event(EventNames.BeforeUnload, false, true);
bool num = await this.QueueTaskAsync((CancellationToken _) => _view.Fire(unloadEvent)).ConfigureAwait(false);
_salvageable = false;
if (num) {
var data = new {
Document = this,
IsCancelled = true
};
await _context.InteractAsync(EventNames.ConfirmUnload, data).ConfigureAwait(false);
if (data.IsCancelled)
return false;
}
}
foreach (IBrowsingContext item in descendants) {
Document active = item.Active as Document;
if (active != null) {
if (!(await active.PromptToUnloadAsync().ConfigureAwait(false)))
return false;
_salvageable = (_salvageable && active._salvageable);
}
}
return true;
}
internal async Task Unload(bool recycle)
{
IEnumerable<IBrowsingContext> descendants = GetAttachedReferences<IBrowsingContext>();
if (_shown) {
_shown = false;
await this.QueueTaskAsync(delegate {
this.Fire(delegate(PageTransitionEvent ev) {
ev.Init(EventNames.PageHide, false, false, _salvageable);
}, _view);
}).ConfigureAwait(false);
}
if (_view.HasEventListener(EventNames.Unload)) {
if (!_firedUnload) {
await this.QueueTaskAsync((CancellationToken _) => _view.FireSimpleEvent(EventNames.Unload, false, false)).ConfigureAwait(false);
_firedUnload = true;
}
_salvageable = false;
}
CancelTasks();
foreach (IBrowsingContext item in descendants) {
Document active = item.Active as Document;
if (active != null) {
await active.Unload(false).ConfigureAwait(false);
_salvageable = (_salvageable && active._salvageable);
}
}
if (!recycle && !_salvageable && _context.Active == this)
_context.Active = null;
}
bool IDocument.ExecuteCommand(string commandId, bool showUserInterface, string value)
{
return _context.GetCommand(commandId)?.Execute(this, showUserInterface, value) ?? false;
}
bool IDocument.IsCommandEnabled(string commandId)
{
return _context.GetCommand(commandId)?.IsEnabled(this) ?? false;
}
bool IDocument.IsCommandIndeterminate(string commandId)
{
return _context.GetCommand(commandId)?.IsIndeterminate(this) ?? false;
}
bool IDocument.IsCommandExecuted(string commandId)
{
return _context.GetCommand(commandId)?.IsExecuted(this) ?? false;
}
bool IDocument.IsCommandSupported(string commandId)
{
return _context.GetCommand(commandId)?.IsSupported(this) ?? false;
}
string IDocument.GetCommandValue(string commandId)
{
return _context.GetCommand(commandId)?.GetValue(this);
}
private void Abort(bool fromUser = false)
{
if (fromUser && _context.Active == this)
this.QueueTaskAsync((CancellationToken _) => _view.FireSimpleEvent(EventNames.Abort, false, false));
foreach (IBrowsingContext attachedReference in GetAttachedReferences<IBrowsingContext>()) {
Document document = attachedReference.Active as Document;
if (document != null) {
document.Abort(false);
_salvageable = (_salvageable && document._salvageable);
}
}
foreach (IDownload item in from m in _loader.GetDownloads()
where !m.IsCompleted
select m) {
item.Cancel();
_salvageable = false;
}
}
private void CancelTasks()
{
foreach (CancellationTokenSource attachedReference in GetAttachedReferences<CancellationTokenSource>()) {
if (!attachedReference.IsCancellationRequested)
attachedReference.Cancel();
}
}
private static bool IsCommand(IElement element)
{
if (!(element is IHtmlMenuItemElement) && !(element is IHtmlButtonElement))
return element is IHtmlAnchorElement;
return true;
}
private static bool IsLink(IElement element)
{
if (element is IHtmlAnchorElement || element is IHtmlAreaElement)
return element.Attributes.Any((IAttr m) => m.Name.Is(AttributeNames.Href));
return false;
}
private static bool IsAnchor(IHtmlAnchorElement element)
{
return element.Attributes.Any((IAttr m) => m.Name.Is(AttributeNames.Name));
}
private void EmptyAppCache()
{
}
private async Task PrintAsync()
{
await this.QueueTaskAsync((CancellationToken _) => this.FireSimpleEvent(EventNames.BeforePrint, false, false)).ConfigureAwait(false);
await _context.InteractAsync(EventNames.Print, new {
Document = this
}).ConfigureAwait(false);
await this.QueueTaskAsync((CancellationToken _) => this.FireSimpleEvent(EventNames.AfterPrint, false, false)).ConfigureAwait(false);
}
private async void LocationChanged(object sender, Location.ChangedEventArgs e)
{
if (e.IsHashChanged) {
HashChangedEvent ev = new HashChangedEvent();
ev.Init(EventNames.HashChange, false, false, e.PreviousLocation, e.CurrentLocation);
ev.IsTrusted = true;
this.QueueTask(delegate {
ev.Dispatch(_view);
});
} else if (!e.IsReloaded) {
DocumentRequest request = DocumentRequest.Get(new Url(e.CurrentLocation), this, DocumentUri);
await _context.OpenAsync(request, CancellationToken.None);
} else {
DocumentRequest request2 = DocumentRequest.Get(_location.Original, this, Referrer);
await _context.OpenAsync(request2, CancellationToken.None);
}
}
protected sealed override string LocateNamespace(string prefix)
{
return DocumentElement?.LocateNamespaceFor(prefix);
}
protected sealed override string LocatePrefix(string namespaceUri)
{
return DocumentElement?.LocatePrefixFor(namespaceUri);
}
protected void CloneDocument(Document document, bool deep)
{
CloneNode(document, document, deep);
document._ready = _ready;
document.Referrer = Referrer;
document._location.Href = _location.Href;
document._quirksMode = _quirksMode;
document._sandbox = _sandbox;
document._async = _async;
document.ContentType = ContentType;
}
protected virtual string GetTitle()
{
return string.Empty;
}
protected abstract void SetTitle(string value);
}
}