HtmlLinkElement
sealed class HtmlLinkElement : HtmlElement, IHtmlLinkElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IElementCssInlineStyle, ILinkStyle
Represents the HTML link element.
using AngleSharp.Dom.Collections;
using AngleSharp.Dom.Css;
using AngleSharp.Extensions;
using AngleSharp.Html;
using AngleSharp.Network;
using AngleSharp.Services.Styling;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace AngleSharp.Dom.Html
{
internal sealed class HtmlLinkElement : HtmlElement, IHtmlLinkElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IElementCssInlineStyle, ILinkStyle
{
private IStyleSheet _sheet;
private TokenList _relList;
private SettableTokenList _sizes;
private Task<IResponse> _current;
internal bool IsVisited { get; set; }
internal bool IsActive { get; set; }
public Url Url => this.HyperReference(GetOwnAttribute(AttributeNames.Href));
public string Href {
get {
return Url.Href;
}
set {
SetOwnAttribute(AttributeNames.Href, value);
}
}
public string TargetLanguage {
get {
return GetOwnAttribute(AttributeNames.HrefLang);
}
set {
SetOwnAttribute(AttributeNames.HrefLang, value);
}
}
public string Charset {
get {
return GetOwnAttribute(AttributeNames.Charset);
}
set {
SetOwnAttribute(AttributeNames.Charset, value);
}
}
public string Relation {
get {
return GetOwnAttribute(AttributeNames.Rel);
}
set {
SetOwnAttribute(AttributeNames.Rel, value);
}
}
public ITokenList RelationList {
get {
if (_relList == null) {
_relList = new TokenList(GetOwnAttribute(AttributeNames.Rel));
_relList.Changed += delegate {
UpdateAttribute(AttributeNames.Rel, _relList.ToString());
};
}
return _relList;
}
}
public ISettableTokenList Sizes {
get {
if (_sizes == null) {
_sizes = new SettableTokenList(GetOwnAttribute(AttributeNames.Sizes));
_sizes.Changed += delegate {
UpdateAttribute(AttributeNames.Sizes, _sizes.Value);
};
}
return _sizes;
}
}
public string Rev {
get {
return GetOwnAttribute(AttributeNames.Rev);
}
set {
SetOwnAttribute(AttributeNames.Rev, value);
}
}
public bool IsDisabled {
get {
return GetOwnAttribute(AttributeNames.Disabled).ToBoolean(false);
}
set {
SetOwnAttribute(AttributeNames.Disabled, value ? string.Empty : null);
}
}
public string Target {
get {
return GetOwnAttribute(AttributeNames.Target);
}
set {
SetOwnAttribute(AttributeNames.Target, value);
}
}
public string Media {
get {
return GetOwnAttribute(AttributeNames.Media);
}
set {
SetOwnAttribute(AttributeNames.Media, value);
}
}
public string Type {
get {
return GetOwnAttribute(AttributeNames.Type);
}
set {
SetOwnAttribute(AttributeNames.Type, value);
}
}
public IStyleSheet Sheet => _sheet;
public HtmlLinkElement(Document owner, string prefix = null)
: base(owner, Tags.Link, prefix, NodeFlags.SelfClosing | NodeFlags.Special)
{
RegisterAttributeObserver(AttributeNames.Media, UpdateMedia);
RegisterAttributeObserver(AttributeNames.Disabled, UpdateDisabled);
string href = AttributeNames.Href;
Action<string> callback = delegate(string value) {
UpdateSource(value);
};
RegisterAttributeObserver(href, callback);
RegisterAttributeObserver(AttributeNames.Type, delegate(string value) {
UpdateType(value);
});
RegisterAttributeObserver(AttributeNames.Rel, delegate {
UpdateType(Type);
});
}
private void UpdateMedia(string value)
{
if (_sheet != null)
_sheet.Media.MediaText = value;
}
private void UpdateDisabled(string value)
{
if (_sheet != null)
_sheet.IsDisabled = (value != null);
}
private void UpdateType(string value)
{
if (_current != null && !_current.IsFaulted && _current.IsCompleted && _current.Result != null) {
string type = value ?? MimeTypes.Css;
IConfiguration options = base.Owner.Options;
if (options.IsStyling() && RelationList.Contains(Keywords.StyleSheet)) {
IStyleEngine styleEngine = options.GetStyleEngine(type);
if (styleEngine != null) {
StyleOptions styleOptions = new StyleOptions();
styleOptions.Element = this;
styleOptions.Title = base.Title;
styleOptions.IsDisabled = IsDisabled;
styleOptions.IsAlternate = RelationList.Contains(Keywords.Alternate);
styleOptions.Configuration = options;
StyleOptions options2 = styleOptions;
using (IResponse response = _current.Result)
try {
_sheet = styleEngine.Parse(response, options2);
} catch {
}
}
}
}
}
private void UpdateSource(string value)
{
base.Owner.Tasks.Cancel(_current);
if (!string.IsNullOrEmpty(value)) {
ResourceRequest request = this.CreateRequestFor(Url);
_current = base.Owner.Tasks.Add((CancellationToken cancel) => base.Owner.Loader.FetchAsync(request, cancel));
_current.ContinueWith(delegate(Task<IResponse> m) {
if (!m.IsFaulted && m.Exception == null) {
UpdateType(Type);
this.FireSimpleEvent(EventNames.Load, false, false);
} else
this.FireSimpleEvent(EventNames.Error, false, false);
});
}
}
}
}