Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed the loading of link element source #1185

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 65 additions & 1 deletion src/AngleSharp.Core.Tests/Css/StyleExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
namespace AngleSharp.Core.Tests.Css
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
Expand Down Expand Up @@ -42,6 +44,35 @@ public void TestStyleSheetsDoesNotThrowStackOverflowException(Int32 count)
thread.Start();
thread.Join();
}

[Test]
public async Task AppendingStylesheetLinkShouldLoadResource()
{
var request = default(Request);

var stylingService = new MockStylingService();
var cfg = Configuration.Default
.WithOnly<IStylingService>(stylingService)
.WithMockRequester(req => request = req );
var html = @"<!doctype html><head><link rel=stylesheet href=/mock-stylesheet-1.css /></head><body></body>";
var document = await BrowsingContext.New(cfg).OpenAsync(m => m.Content(html));

// test with link element in the initial HTML
Assert.IsNotNull(request);
Assert.AreEqual("/mock-stylesheet-1.css", request.Address.PathName);

request = default(Request);

// test with dynamically added link element
var link = document.CreateElement("link");
link.SetAttribute(AttributeNames.Rel, "stylesheet");
link.SetAttribute(AttributeNames.Href, "/mock-stylesheet-2.css");

document.Body.AppendChild(link);

Assert.IsNotNull(request);
Assert.AreEqual("/mock-stylesheet-2.css", request.Address.PathName);
}
}

internal class MockStylingService : IStylingService
Expand All @@ -58,10 +89,12 @@ public Task<IStyleSheet> ParseStylesheetAsync(IResponse response, StyleOptions o
internal class MockStyleSheet : IStyleSheet
{
private readonly StyleOptions _options;
private readonly IMediaList _mediaList;

public MockStyleSheet(StyleOptions options)
{
_options = options;
_mediaList = new MockMediaList();
}

public void ToCss(TextWriter writer, IStyleFormatter formatter)
Expand All @@ -76,7 +109,7 @@ public void ToCss(TextWriter writer, IStyleFormatter formatter)

public String Title { get; } = "";

public IMediaList Media { get; } = null;
public IMediaList Media { get => _mediaList; }

public Boolean IsDisabled { get => _options.IsDisabled; set { } }

Expand All @@ -90,4 +123,35 @@ public void SetOwner(IElement element)

public String LocateNamespace(String prefix) => null;
}

internal class MockMediaList : IMediaList
{
public String this[Int32 index] => "";

public String MediaText { get; set; } = "";

public Int32 Length => 0;

public void Add(String medium)
{
}

public IEnumerator<ICssMedium> GetEnumerator()
{
return default;
}

public void Remove(String medium)
{
}

public void ToCss(TextWriter writer, IStyleFormatter formatter)
{
}

IEnumerator IEnumerable.GetEnumerator()
{
return default;
}
}
}
1 change: 1 addition & 0 deletions src/AngleSharp/Dom/Internal/DefaultAttributeObserver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ protected virtual void RegisterStandardObservers()
RegisterObserver<HtmlElement>(AttributeNames.DropZone, (element, value) => element.UpdateDropZone(value));
RegisterObserver<HtmlBaseElement>(AttributeNames.Href, (element, value) => element.UpdateUrl(value));
RegisterObserver<HtmlEmbedElement>(AttributeNames.Src, (element, value) => element.UpdateSource(value));
RegisterObserver<HtmlLinkElement>(AttributeNames.Rel, (element, value) => element.UpdateRel(value));
RegisterObserver<HtmlLinkElement>(AttributeNames.Sizes, (element, value) => element.UpdateSizes(value));
RegisterObserver<HtmlLinkElement>(AttributeNames.Media, (element, value) => element.UpdateMedia(value));
RegisterObserver<HtmlLinkElement>(AttributeNames.Disabled, (element, value) => element.UpdateDisabled(value));
Expand Down
42 changes: 32 additions & 10 deletions src/AngleSharp/Html/Dom/Internal/HtmlLinkElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ namespace AngleSharp.Html.Dom
using AngleSharp.Dom;
using AngleSharp.Html.LinkRels;
using AngleSharp.Io;
using AngleSharp.Text;
using System;

/// <summary>
Expand All @@ -16,6 +17,9 @@ sealed class HtmlLinkElement : HtmlElement, IHtmlLinkElement
private TokenList? _relList;
private SettableTokenList? _sizes;

private String? _source;
private Boolean _relationLoaded;

#endregion

#region ctor
Expand Down Expand Up @@ -175,17 +179,12 @@ public Boolean IsDisabled

#region Internal Methods

internal override void SetupElement()
internal void UpdateRel(String value)
{
var rel = this.GetOwnAttribute(AttributeNames.Rel);
_relList?.Update(value);
_relation = CreateFirstLegalRelation();

if (rel != null)
{
_relList?.Update(rel);
_relation = CreateFirstLegalRelation();
}

base.SetupElement();
LoadRelation();
}

internal void UpdateSizes(String value)
Expand Down Expand Up @@ -215,7 +214,30 @@ internal void UpdateDisabled(String value)

internal void UpdateSource(String value)
{
var task = _relation?.LoadAsync();
if (!value.Isi(_source))
{
_source = value;
_relationLoaded = false;
}
}

protected override void OnParentChanged()
{
base.OnParentChanged();

LoadRelation();
}

internal void LoadRelation()
{
if (_relationLoaded || _relation == null || Href == null)
{
return;
}

_relationLoaded = true;

var task = _relation.LoadAsync();
Owner?.DelayLoad(task);
}

Expand Down
Loading