HtmlLinkElement
sealed class HtmlLinkElement : HtmlElement, IHtmlLinkElement, IHtmlElement, IElement, INode, IEventTarget, IParentNode, IChildNode, INonDocumentTypeChildNode, IElementCssInlineStyle, ILinkStyle, IDisposable
Represents the HTML link element.
using AngleSharp.Dom.Collections;
using AngleSharp.Dom.Css;
using AngleSharp.Extensions;
using AngleSharp.Html;
using AngleSharp.Network;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace AngleSharp.Dom.Html
{
internal sealed class HtmlLinkElement : HtmlElement, IHtmlLinkElement, IHtmlElement, IElement, INode, IEventTarget, IParentNode, IChildNode, INonDocumentTypeChildNode, IElementCssInlineStyle, ILinkStyle, IDisposable
{
private enum RelType : ushort
{
None,
Prefetch,
Icon,
Pingback,
Stylesheet,
Alternate,
Canonical,
Archives,
Author,
First,
Help,
Sidebar,
Tag,
Search,
Index,
License,
Up,
Next,
Last,
Prev
}
private IStyleSheet _sheet;
private Url _buffer;
private TokenList _relList;
private SettableTokenList _sizes;
private Task _loadingTask;
private CancellationTokenSource _cts;
internal bool IsVisited { get; set; }
internal bool IsActive { get; set; }
public Url Url => this.HyperReference(GetAttribute(AttributeNames.Href));
public string Href {
get {
return Url.Href;
}
set {
SetAttribute(AttributeNames.Href, value);
}
}
public string TargetLanguage {
get {
return GetAttribute(AttributeNames.HrefLang);
}
set {
SetAttribute(AttributeNames.HrefLang, value);
}
}
public string Charset {
get {
return GetAttribute(AttributeNames.Charset);
}
set {
SetAttribute(AttributeNames.Charset, value);
}
}
public string Relation {
get {
return GetAttribute(AttributeNames.Rel);
}
set {
SetAttribute(AttributeNames.Rel, value);
}
}
public ITokenList RelationList {
get {
if (_relList == null) {
_relList = new TokenList(GetAttribute(AttributeNames.Rel));
_relList.Changed += delegate {
UpdateAttribute(AttributeNames.Rel, _relList.ToString());
};
}
return _relList;
}
}
public ISettableTokenList Sizes {
get {
if (_sizes == null) {
_sizes = new SettableTokenList(GetAttribute(AttributeNames.Sizes));
_sizes.Changed += delegate {
UpdateAttribute(AttributeNames.Sizes, _sizes.Value);
};
}
return _sizes;
}
}
public string Rev {
get {
return GetAttribute(AttributeNames.Rev);
}
set {
SetAttribute(AttributeNames.Rev, value);
}
}
public bool IsDisabled {
get {
return GetAttribute(AttributeNames.Disabled).ToBoolean(false);
}
set {
SetAttribute(AttributeNames.Disabled, value ? string.Empty : null);
}
}
public string Target {
get {
return GetAttribute(AttributeNames.Target);
}
set {
SetAttribute(AttributeNames.Target, value);
}
}
public string Media {
get {
return GetAttribute(AttributeNames.Media);
}
set {
SetAttribute(AttributeNames.Media, value);
}
}
public string Type {
get {
return GetAttribute(AttributeNames.Type);
}
set {
SetAttribute(AttributeNames.Type, value);
}
}
public IStyleSheet Sheet => _sheet;
public HtmlLinkElement(Document owner)
: base(owner, Tags.Link, NodeFlags.SelfClosing | NodeFlags.Special)
{
RegisterAttributeObserver(AttributeNames.Media, UpdateMedia);
RegisterAttributeObserver(AttributeNames.Disabled, UpdateDisabled);
RegisterAttributeObserver(AttributeNames.Href, delegate {
TargetChanged();
});
RegisterAttributeObserver(AttributeNames.Type, delegate {
TargetChanged();
});
}
private void UpdateMedia(string value)
{
if (_sheet != null)
_sheet.Media.MediaText = value;
}
private void UpdateDisabled(string value)
{
if (_sheet != null)
_sheet.IsDisabled = (value != null);
}
public void Dispose()
{
if (_cts != null)
_cts.Cancel();
_cts = null;
_loadingTask = null;
}
private void TargetChanged()
{
if (base.Owner.Options.IsStyling) {
if (_cts != null)
_cts.Cancel();
Url url = Url;
if (url != null && (_buffer == null || !url.Equals(_buffer))) {
_buffer = url;
IRequester requester = base.Owner.Options.GetRequester(url.Scheme);
if (requester != null) {
_cts = new CancellationTokenSource();
_loadingTask = LoadAsync(requester, url, _cts.Token);
}
}
}
}
private async Task LoadAsync(IRequester requester, Url url, CancellationToken cancel)
{
IResponse response = await requester.LoadAsync(url, _cts.Token).ConfigureAwait(false);
if (response != null) {
_sheet = AngleSharp.Extensions.ConfigurationExtensions.ParseStyling(options: new StyleOptions {
Element = this,
Title = Title,
IsDisabled = IsDisabled,
IsAlternate = RelationList.Contains(Keywords.Alternate)
}, configuration: Owner.Options, response: response, type: Type);
response.Dispose();
}
}
}
}