Skip to content

Release 1.0.2 - #226

Merged
FlorianRappl merged 11 commits into
mainfrom
devel
Aug 21, 2026
Merged

Release 1.0.2#226
FlorianRappl merged 11 commits into
mainfrom
devel

Conversation

@FlorianRappl

Copy link
Copy Markdown
Contributor

Types of Changes

Prerequisites

Please make sure you can check the following two boxes:

  • I have read the CONTRIBUTING document
  • My code follows the code style of this project

Contribution Type

What types of changes does your code introduce? Put an x in all the boxes that apply:

  • Bug fix (non-breaking change which fixes an issue, please reference the issue id)
  • New feature (non-breaking change which adds functionality, make sure to open an associated issue first)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • My change requires a change to the documentation
  • I have updated the documentation accordingly
  • I have added tests to cover my changes
  • All new and existing tests passed

Description

Fixes oklab parsing and improved performance.

FlorianRappl and others added 11 commits August 1, 2026 10:39
CssStyleDeclaration.CreateProperty seeded every newly created property
with the raw value of an existing declaration of the same name before
handing it back:

    var newProperty = _context.CreateProperty(propertyName);
    var existing = GetProperty(propertyName);
    if (existing is not null) newProperty.RawValue = existing.RawValue;

That seed can never be observed. CreateProperty had a single caller,
SetProperty(name, value, priority), whose next statement is
`property.Value = propertyValue` - and both branches of the
CssProperty.Value setter assign _value unconditionally.

The lookup itself is not cheap. On a miss GetProperty falls through to
GetPropertyShorthand, i.e. TryCreateShorthand(force: true), which for a
shorthand such as background or border reconstructs the whole shorthand
from its longhands - allocating an ICssValue[], recursing per longhand
and calling CreateShorthand - only for the result to be overwritten on
the next line. Parsing a sheet paid for that on every declaration.

Dropping the seed leaves GetProperty and the rest of the public
behaviour untouched.

Measured on the sample sheets in AngleSharp.Performance.Css (net10.0):

  cdnjs.cloudflare      1.963 ms -> 1.499 ms   1379.8 KB -> 1226.6 KB
  csszengarden          1.743 ms -> 1.446 ms   1283.2 KB -> 1178.1 KB
  florian-rappl         4.137 ms -> 3.683 ms   2268.8 KB -> 2077.5 KB
  maxcdn.bootstrapcdn   7.811 ms -> 6.522 ms   4978.0 KB -> 4419.8 KB
  s.yimg                1.935 ms -> 1.807 ms   1032.2 KB -> 1000.5 KB
  static.licdn          1.904 ms -> 1.588 ms   1095.9 KB ->  972.1 KB
  style.aliunicorn      1.507 ms -> 1.434 ms    897.8 KB ->  876.1 KB

Inline declaration parsing improves by a similar margin (968.4 us ->
724.8 us); the cascade benchmarks are unchanged, as they merge
declarations instead of going through this setter.

SetPropertyOverwriteTests covers 28 re-declaration cases - longhand over
shorthand and back, !important in either order, an invalid value after a
valid one, an empty value, custom properties, grid-area/grid-row, font,
flex and border-radius. The expectations are a baseline captured from the
previous implementation, which produced identical output for all of them.
…tproperty

Avoid rebuilding shorthands when setting a declaration
Fallout v10.4.0 is the first stable-channel release; the previously pinned
11.0.18 belongs to the edge channel. The stable CLI ships as Fallout.GlobalTool
(the fallout command is unchanged), and Fallout.Common 10.4.0 resolves the
patched System.Security.Cryptography.Xml 10.0.10 on its own, so the manual
transitive pin is no longer needed (Fallout-build/Fallout#618).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Move the build orchestrator to the Fallout stable channel (10.4.0)
CssFontFaceRule kept only the seven descriptors named in its private
ContainedProperties set; CssDeclarationRule discarded everything else
silently and without consulting CssParserOptions, so
IsIncludingUnknownDeclarations had no effect inside @font-face even
though it is what keeps unrecognized declarations alive in style rules.
Standard CSS Fonts Level 4 descriptors (font-display, size-adjust,
ascent-override, font-feature-settings, ...) and vendor descriptors
(mso-*) were both lost, and ToCss emitted a well-formed looking rule so
a caller round-tripping a stylesheet had no way to notice.

Non-descriptor declarations now fall through to the same
IsAllowingUnknownDeclarations gate that style rules use, which also
covers @counter-style, @font-feature-values and @Viewport - the sibling
rules on the same base class.

Register the standard descriptors that had no declaration at all
(size-adjust, ascent-override, descent-override, line-gap-override,
font-feature-settings) with real value grammars, add a percentage
converter, and extend ContainedProperties so they are kept, typed, by
default rather than only under the opt-in.

Along the way:

- font-variation-settings accepted only `normal`, so `"wght" 400` was
  rejected in style rules and would have been rejected in the newly
  preserved @font-face. It now implements normal | [<string> <number>]#.
- SetValue added properties without checking they parsed, so an invalid
  descriptor serialized as a malformed `size-adjust: ;`. Invalid values
  are now ignored and leave an existing valid declaration standing,
  matching CssStyleDeclaration.
- ICssFontFaceRule.Features was a String.Empty/no-op stub despite its
  featureSettings DOM name; it now maps to font-feature-settings.

Fixes the silent loss reported downstream in mganss/HtmlSanitizer#541.
Fix oklab/oklch lightness misparsed as percentage when given as a number
@FlorianRappl FlorianRappl added this to the v1.0.2 milestone Aug 21, 2026
@FlorianRappl
FlorianRappl merged commit d158478 into main Aug 21, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants