Skip to content

Release 0.12 #28

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

Merged
merged 50 commits into from
May 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
dbfec4e
Updated reference
FlorianRappl Jan 7, 2019
d031bc5
Updated version
FlorianRappl Jan 7, 2019
e70e415
Improved CSS serialization, found issue wrt initial issue
FlorianRappl Jan 7, 2019
631dfa9
Started outlining all initial values
FlorianRappl Jan 9, 2019
687aa61
Implemented many initial values
FlorianRappl Jan 9, 2019
65de18c
test for issue #16
jogibear9988 Jan 23, 2019
aa08ead
Merge pull request #17 from jogibear9988/master
FlorianRappl Jan 23, 2019
aecb838
Fixed dep on unit test for publish
FlorianRappl Jan 24, 2019
67955ba
Updated README
FlorianRappl Apr 28, 2019
72540ca
Updated changelog
FlorianRappl May 3, 2019
8f5d6ae
Updated AngleSharp
FlorianRappl May 5, 2019
4c0babb
Updated and refactored
FlorianRappl May 5, 2019
d203d59
Added test for issue #27
FlorianRappl May 5, 2019
8779822
Fixed GetStyle when CSS not configured
FlorianRappl May 5, 2019
6eb73f8
Added src converter fixes #25
FlorianRappl May 5, 2019
406e3b4
Provided pointer-events fixes #16
FlorianRappl May 5, 2019
a136533
Added default style sheet provider fixes #21
FlorianRappl May 5, 2019
9cc365f
Fixed the NRE for IRenderDevice in @media #20
FlorianRappl May 5, 2019
847d59a
WIP CSSOM value model
FlorianRappl May 5, 2019
54ac3a8
Fixed stroke-width without unit #18
FlorianRappl May 5, 2019
85d51ae
Prepare value model with primitives as struct
FlorianRappl May 5, 2019
bafe780
Refactored CSS value naming
FlorianRappl May 8, 2019
fd3d653
Consolidation and type improvements
FlorianRappl May 8, 2019
f1d4841
More value consistency
FlorianRappl May 8, 2019
72ec96e
Refined composites w.r.t. fields
FlorianRappl May 9, 2019
68aeb5d
Cosmetic refactoring
FlorianRappl May 9, 2019
0b1ee49
New recombination algorithm
FlorianRappl May 10, 2019
e6db186
Always return shorthand - even if invalid values
FlorianRappl May 10, 2019
4f77ace
Started with cleanup
FlorianRappl May 10, 2019
1a85c05
Default values
FlorianRappl May 10, 2019
398f756
Reference right initial values
FlorianRappl May 11, 2019
fc7b80f
Started integration initial value in declaration info
FlorianRappl May 11, 2019
6d6af09
Use assign initial on declaration level only
FlorianRappl May 11, 2019
062d85e
Rewire shorthand resolution
FlorianRappl May 11, 2019
1033292
Optimized border parsing
FlorianRappl May 11, 2019
a290247
More consistency
FlorianRappl May 11, 2019
0ee93d6
Respect unknown decl rule
FlorianRappl May 12, 2019
20e091d
Improved background serialization
FlorianRappl May 12, 2019
78d67ab
Refined initial value handling
FlorianRappl May 12, 2019
0dc9599
Improved background handling
FlorianRappl May 12, 2019
2c06be0
Optimized the border radius converter and initial values
FlorianRappl May 12, 2019
492adae
Replaced Default with Initial value
FlorianRappl May 12, 2019
19163df
Prefer border serialization to explicit sides
FlorianRappl May 12, 2019
e93e2bb
More tests for correct border behavior
FlorianRappl May 12, 2019
894bd52
Added default render device
FlorianRappl May 12, 2019
a2c3ea3
CSSOM primitive improvements
FlorianRappl May 12, 2019
4bd41ad
Restructured file organization
FlorianRappl May 12, 2019
183022f
Documentation improvements
FlorianRappl May 12, 2019
c39ac49
Improved CSS API
FlorianRappl May 12, 2019
e3ad3b3
Enable media rules
FlorianRappl May 12, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,28 @@
# 0.12.0

Released on Sunday, May 12 2019.

- Reference latest AngleSharp
- Fixed empty value when removing properties (#14)
- Returns `null` in `GetStyle` if CSS not configured (#15)
- Added `pointer-events` and fixed border recombination (#16)
- Fixed `stroke-width` value without unit (#18)
- Fixed exception when not providing an `IRenderDevice` (#20)
- Fixed missing `CssStylingService.Default` in cascade (#21)
- Added extension helper `SetStyle` to modify all styles of many elements (#22)
- Fixed expansion of shorthand properties to longhand (#23)
- Opened CSSOM, e.g., declared `ICssFunctionValue` `public` (#24)
- Introduced special converter for the `src` declaration (#25)
- Fixed bug regarding CSS grid serialization (#27)
- Added `DefaultRenderDevice` implementation

# 0.10.1

Released on Monday, January 7 2019.

- Reference latest AngleSharp
- Updated reference to `System.Encoding.CodePages` (#13)

# 0.10.0

Released on Friday, January 4 2019.
Expand Down
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
[![GitHub Tag](https://img.shields.io/github/tag/AngleSharp/AngleSharp.Css.svg?style=flat-square)](https://github.com/AngleSharp/AngleSharp.Css/releases)
[![NuGet Count](https://img.shields.io/nuget/dt/AngleSharp.Css.svg?style=flat-square)](https://www.nuget.org/packages/AngleSharp.Css/)
[![Issues Open](https://img.shields.io/github/issues/AngleSharp/AngleSharp.Css.svg?style=flat-square)](https://github.com/AngleSharp/AngleSharp.Css/issues)
[![Gitter Chat](http://img.shields.io/badge/gitter-AngleSharp/AngleSharp-blue.svg?style=flat-square)](https://gitter.im/AngleSharp/AngleSharp)
[![StackOverflow Questions](https://img.shields.io/stackexchange/stackoverflow/t/anglesharp.svg?style=flat-square)](https://stackoverflow.com/tags/anglesharp)
[![CLA Assistant](https://cla-assistant.io/readme/badge/AngleSharp/AngleSharp.Css?style=flat-square)](https://cla-assistant.io/AngleSharp/AngleSharp.Css)

Expand All @@ -28,6 +29,20 @@ This will register a parser for CSS related content. The CSS parsing options and

For an interactive DOM (i.e., to handle `style` attribute changes in the HTML document) an observer needs to be registered as well.

Furthermore, for some CSSOM features (e.g., media queries) a render device is required.

```cs
var config = Configuration.Default
.WithCss()
.WithRenderDevice(new DefaultRenderDevice
{
DeviceHeight = 768,
DeviceWidth = 1024,
});
```

If no specific `IRenderDevice` (e.g., via creating an `DefaultRenderDevice` object) instance is created a default implementation will be set.

## Advantages of AngleSharp.Css

The core library already contains the CSS selector parser and the most basic classes and interfaces for dealing with the CSSOM. AngleSharp.Css brings the following advantages and use cases to life:
Expand Down Expand Up @@ -60,6 +75,16 @@ Participation in the project is highly welcome. For this project the same rules

If you have any question, concern, or spot an issue then please report it before opening a pull request. An initial discussion is appreciated regardless of the nature of the problem.

Live discussions can take place in our [Gitter chat](https://gitter.im/AngleSharp/AngleSharp), which supports using GitHub accounts.

This project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behavior in our community.

For more information see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct).

## .NET Foundation

This project is supported by the [.NET Foundation](https://dotnetfoundation.org).

## License

The MIT License (MIT)
Expand Down
7 changes: 3 additions & 4 deletions build.cake
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ using Octokit;

var target = Argument("target", "Default");
var configuration = Argument("configuration", "Release");
var isLocal = BuildSystem.IsLocalBuild;
var isRunningOnUnix = IsRunningOnUnix();
var isRunningOnWindows = IsRunningOnWindows();
var isRunningOnAppVeyor = AppVeyor.IsRunningOnAppVeyor;
Expand Down Expand Up @@ -140,7 +139,7 @@ Task("Create-Package")

Task("Publish-Package")
.IsDependentOn("Create-Package")
.WithCriteria(() => isLocal)
.IsDependentOn("Run-Unit-Tests")
.Does(() =>
{
var apiKey = EnvironmentVariable("NUGET_API_KEY");
Expand All @@ -161,8 +160,8 @@ Task("Publish-Package")
});

Task("Publish-Release")
.IsDependentOn("Publish-Package")
.WithCriteria(() => isLocal)
.IsDependentOn("Create-Package")
.IsDependentOn("Run-Unit-Tests")
.Does(() =>
{
var githubToken = EnvironmentVariable("GITHUB_API_TOKEN");
Expand Down
44 changes: 44 additions & 0 deletions doc/API.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# API Documentation

## CSSOM - Basics

The CSS Object Model (CSSOM) consists of multiple parts. On the one hand we have standard Document Object Model (DOM) exposed interfaces, such as the stylesheets, styles, or rules, on the other hand we have special constructs only available in AngleSharp to dig deeper into the provided CSS.

The AngleSharp CSS parser can construct objects of the following high-level types:

- `ICssStyleSheet`, representing a full CSS stylesheet
- `ICssRule`, representing a rule within a CSS stylesheet
- `ICssKeyframeRule`, representing a special keyframe rule (only exposed since the DOM directly connects to it)
- `ICssStyleDeclaration`, representing the keeper of CSS declarations

A CSS declaration is a CSS property, e.g., `color` together with its value (e.g., `red`) and priority ("important" or not). Declarations are rather complicated as they appear not only in primitive fashion as seen earlier (`color`), but also in form of *shorthands* such as `background`. In the latter case the shorthand is expanded into all contained *longhands* (e.g., `background-color`, `background-image`, ...) and stored in this primitive way. Retrieving the shorthand later on is done via a recombination of the *currently* available longhands.

The topic with longhands and shorthands is especially complicated in face of *defered computation*. This is the case once a calculated value is hit, which is necessary for the rule to be validated, but cannot be calculated during sheet evaluation time (i.e., the calculation has to take place with the cascade coming from the DOM). The simplest example is `var`. CSS variables are evaluated only with the cascade in mind. In this case no simple expansion of the shorthand into longhands is possible. Instead, AngleSharp will "fake" a potential expansion with a reference value, which can then be resolved later.

There are multiple types of rules. Depending on the type of rule other rules may be the children of the rule. While a style rule is the most elementary one (essentially just containing an `ICssStyleDeclaration` instance) one example of a container rule is the media rule. This type of rule hosts other rules.

## CSSOM - Values

The most interesting part of a CSS declaration is the value part. This is also the complicated part as values are always given in string form. The parsing is completely dependent on the type of declaration. Some fixed / known types and parsing rules exist, however, the exact setup of a declaration is completely arbitrary.

AngleSharp uses converters to parse a given source to an `ICssValue` instance. The converter follows the `IValueConverter` interface.

The `ICssValue` interface is split in various interfaces with respect to their usage.

![The CSSOM Value Tree](cssom-value-tree.png)

A converter may also implement the `IValueAggregator` interface, which indicates that the declaration behind it is actually a shorthand that can additionally merge values into a shorthand representation or split the shorthand representation into the atoms described by the shorthand.

For convenience some (extension) methods have been introduced to make working with the CSSOM (specifically values) simpler. The shown extension methods are placed in the `AngleSharp.Css.Dom` namespace.

```cs
// sheet is a stylesheet, e.g., obtained from a document, with content:
// p > a { border: 1px solid red }
var rule = sheet.GetStyleRuleWith("p>a");
var color = rule.GetValueOf("border-right-color").AsRgba();
// the color is an Int32, e.g., 0xFF_FF - same as rgba(255, 0, 0, 1)
```

The idea behind `GetStyleRuleWith` is to get the first top-level style rule that matches the given selector exactly. The text of the selector does not have to be equal to the text of the selector in the stylesheet, but it needs to be equal *semantically*, i.e., in the provided example the spaces do not matter as the semantics are not influenced by them.

The `GetValueOf` obtains the `ICssValue` instance behind the property with the given name. The `AsRgba` works (like all the other `As*` extension methods) against the `ICssValue` to get an elementary value out of it. This works in simple cases, but will fail, e.g., when there are multiple values available or when the primitive value is hidden in a composite one.
Binary file added doc/cssom-value-tree.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions doc/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# AngleSharp.Css Documentation

We have more detailed information regarding the following subjects:

- [API Documentation](API.md)

For help on AngleSharp itself, see [the full documentation](https://anglesharp.github.io/docs.html).
5 changes: 3 additions & 2 deletions src/AngleSharp.Css.Tests/AngleSharp.Css.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="AngleSharp.Xml" Version="0.12.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="NUnit" Version="3.11.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.11.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ public void CssAnimationCountDoubleIllegal()
{
var snippet = "animation : 10 20";
var property = ParseDeclaration(snippet);
Assert.IsNull(property);
Assert.IsFalse(property.HasValue);
}

[Test]
Expand Down
21 changes: 18 additions & 3 deletions src/AngleSharp.Css.Tests/Declarations/CssBorderProperty.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
using AngleSharp.Css.Dom;
using AngleSharp.Css.Parser;

namespace AngleSharp.Css.Tests.Declarations
{
using NUnit.Framework;
Expand Down Expand Up @@ -178,7 +181,7 @@ public void CssBorderColorRedBlueGreenBlackTransparentIllegal()
{
var snippet = "border-color: red blue green black transparent";
var property = ParseDeclaration(snippet);
Assert.IsNull(property);
Assert.IsFalse(property.HasValue);
}

[Test]
Expand Down Expand Up @@ -246,7 +249,7 @@ public void CssBorderStyleWavyIllegal()
{
var snippet = "border-style: wavy";
var property = ParseDeclaration(snippet);
Assert.IsNull(property);
Assert.IsFalse(property.HasValue);
}

[Test]
Expand Down Expand Up @@ -434,7 +437,7 @@ public void CssBorderWidthZerosIllegal()
{
var snippet = "border-width: 0 0 0 0 0";
var property = ParseDeclaration(snippet);
Assert.IsNull(property);
Assert.IsFalse(property.HasValue);
}

[Test]
Expand Down Expand Up @@ -554,5 +557,17 @@ public void CssBorderOutSetWithNoColor()
Assert.IsTrue(property.HasValue);
Assert.AreEqual("1px outset", property.Value);
}

[Test]
public void CssBorderAggregation()
{
var expectedCss = "border: 1px solid rgba(0, 0, 0, 1)";
var context = BrowsingContext.New(Configuration.Default.WithCss());
var style = new CssStyleDeclaration(context);
style.SetBorderWidth("1px");
style.SetBorderStyle("solid");
style.SetBorderColor("black");
Assert.AreEqual(expectedCss, style.CssText);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public void CssBorderBottomLeftRadiusPxPxLegal()
Assert.IsFalse(property.IsImportant);
Assert.IsFalse(property.IsInherited);
Assert.IsTrue(property.HasValue);
Assert.AreEqual("40px 40px", property.Value);
Assert.AreEqual("40px", property.Value);
}

[Test]
Expand Down Expand Up @@ -155,7 +155,7 @@ public void CssBorderRadiusFiveLengthsIllegal()
{
var snippet = "border-radius: 2px 4px 3px 0 1px";
var property = ParseDeclaration(snippet);
Assert.IsNull(property);
Assert.IsFalse(property.HasValue);
}

[Test]
Expand Down Expand Up @@ -199,15 +199,15 @@ public void CssBorderRadiusFiveTailFractionIllegal()
{
var snippet = "border-radius: 4px 3px 6px 1em / 2px 4px 0 20% 0";
var property = ParseDeclaration(snippet);
Assert.IsNull(property);
Assert.IsFalse(property.HasValue);
}

[Test]
public void CssBorderRadiusFiveHeadFractionIllegal()
{
var snippet = "border-radius: 4px 3px 6px 1em 0 / 2px 4px 0 20%";
var property = ParseDeclaration(snippet);
Assert.IsNull(property);
Assert.IsFalse(property.HasValue);
}

[Test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ public void CssColumsNumberPercenIllegal()
{
var snippet = "columns : 5 25% ";
var property = ParseDeclaration(snippet);
Assert.IsNull(property);
Assert.IsFalse(property.HasValue);
}

[Test]
Expand Down
9 changes: 9 additions & 0 deletions src/AngleSharp.Css.Tests/Declarations/CssGridProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -759,5 +759,14 @@ public void CssGridTemplateRowsAndColumnsWithFractionsLegal()
Assert.IsTrue(property.HasValue);
Assert.AreEqual("100px 1fr / 50px 1fr", property.Value);
}

[Test]
public void CssRuleWithOnlyGridTemplateAreasLegal_Issue27()
{
var snippet = @"div#A { grid-template-areas: ""a b b"" ""a c d"" }";
var rule = ParseRule(snippet);
var text = rule.CssText;
Assert.AreEqual(snippet, text);
}
}
}
2 changes: 1 addition & 1 deletion src/AngleSharp.Css.Tests/Declarations/CssMarginProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ public void CssMarginTooManyValuesIllegal()
{
var snippet = "margin: 10px 5% 8px 2% 3px auto";
var property = ParseDeclaration(snippet);
Assert.IsNull(property);
Assert.IsFalse(property.HasValue);
}

[Test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ public void CssOutlineDoubleColorIllegal()
{
var snippet = "outline : dotted #123456 rgb(255, 255, 255)";
var property = ParseDeclaration(snippet);
Assert.IsNull(property);
Assert.IsFalse(property.HasValue);
}

[Test]
Expand Down
4 changes: 2 additions & 2 deletions src/AngleSharp.Css.Tests/Declarations/CssPaddingProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public void CssPaddingAutoIllegal()
{
var snippet = "padding: auto ";
var property = ParseDeclaration(snippet);
Assert.IsNull(property);
Assert.IsFalse(property.HasValue);
}

[Test]
Expand Down Expand Up @@ -127,7 +127,7 @@ public void CssPaddingTooManyValuesIllegal()
{
var snippet = "padding: 10px 5% 8px 2% 3px";
var property = ParseDeclaration(snippet);
Assert.IsNull(property);
Assert.IsFalse(property.HasValue);
}

[Test]
Expand Down
14 changes: 13 additions & 1 deletion src/AngleSharp.Css.Tests/Declarations/CssStrokeProperty.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace AngleSharp.Css.Tests.Declarations
namespace AngleSharp.Css.Tests.Declarations
{
using NUnit.Framework;
using static CssConstructionFunctions;
Expand Down Expand Up @@ -370,5 +370,17 @@ public void CssStrokeWidthNoneIllegal()
Assert.IsFalse(property.IsInherited);
Assert.IsFalse(property.HasValue);
}

[Test]
public void CssStrokeWithoutUnit_Issue18()
{
var snippet = "stroke-width: 3";
var property = ParseDeclaration(snippet);
Assert.AreEqual("stroke-width", property.Name);
Assert.IsFalse(property.IsImportant);
Assert.IsFalse(property.IsInherited);
Assert.IsTrue(property.HasValue);
Assert.AreEqual("3", property.Value);
}
}
}
2 changes: 1 addition & 1 deletion src/AngleSharp.Css.Tests/Declarations/CssTextProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ public void CssTextDecorationIllegal()
{
var snippet = "text-decoration: line-pass";
var property = ParseDeclaration(snippet);
Assert.IsNull(property);
Assert.IsFalse(property.HasValue);
}

[Test]
Expand Down
Loading