Skip to content

Commit 1c9efd4

Browse files
committed
Prepared computation model
1 parent baca67a commit 1c9efd4

File tree

83 files changed

+1182
-273
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+1182
-273
lines changed

src/AngleSharp.Css.Tests/Extensions/Nesting.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public void SimpleSelectorNestingImplicit()
2222
var element = document.QuerySelector(".bar");
2323
var style = window.GetComputedStyle(element);
2424

25-
Assert.AreEqual("1.4rem", style.GetFontSize());
25+
Assert.AreEqual("22.4px", style.GetFontSize());
2626
}
2727

2828
[Test]
@@ -39,7 +39,7 @@ public void SimpleSelectorNestingExplicit()
3939
var element = document.QuerySelector(".bar");
4040
var style = window.GetComputedStyle(element);
4141

42-
Assert.AreEqual("1.4rem", style.GetFontSize());
42+
Assert.AreEqual("22.4px", style.GetFontSize());
4343
}
4444

4545
[Test]
@@ -60,7 +60,7 @@ public void SimpleSelectorNestingOverwritten()
6060
var element = document.QuerySelector(".bar");
6161
var style = window.GetComputedStyle(element);
6262

63-
Assert.AreEqual("1.4rem", style.GetFontSize());
63+
Assert.AreEqual("22.4px", style.GetFontSize());
6464
}
6565

6666
[Test]

src/AngleSharp.Css/Declarations/ContentDeclaration.cs

+46-57
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ namespace AngleSharp.Css.Declarations
88
using AngleSharp.Text;
99
using System;
1010
using System.Collections.Generic;
11+
using System.Linq;
1112

1213
static class ContentDeclaration
1314
{
@@ -21,7 +22,7 @@ static class ContentDeclaration
2122

2223
sealed class ContentValueConverter : IValueConverter
2324
{
24-
private static readonly Dictionary<String, IContentMode> ContentModes = new(StringComparer.OrdinalIgnoreCase)
25+
private static readonly Dictionary<String, ContentMode> ContentModes = new(StringComparer.OrdinalIgnoreCase)
2526
{
2627
{ CssKeywords.OpenQuote, new OpenQuoteContentMode() },
2728
{ CssKeywords.NoOpenQuote, new NoOpenQuoteContentMode() },
@@ -117,86 +118,86 @@ public ContentValue(ICssValue[] modes)
117118
}
118119

119120
public String CssText => _modes.Length == 0 ? CssKeywords.None : _modes.Join(" ");
121+
122+
public ICssValue Compute(ICssComputeContext context)
123+
{
124+
var modes = _modes.Select(mode => mode.Compute(context)).ToArray();
125+
return new ContentValue(modes);
126+
}
120127
}
121128

122-
private interface IContentMode : ICssValue
129+
private abstract class ContentMode : ICssValue
123130
{
124-
String Stringify(IElement element);
131+
public String CssText => GetCssText();
132+
133+
public abstract String Stringify(IElement element);
134+
135+
public abstract String GetCssText();
136+
137+
ICssValue ICssValue.Compute(ICssComputeContext context)
138+
{
139+
return this;
140+
}
125141
}
126142

127143
/// <summary>
128144
/// Computes to none for the :before and :after pseudo-elements.
129145
/// </summary>
130-
private sealed class NormalContentMode : IContentMode
146+
private sealed class NormalContentMode : ContentMode
131147
{
132-
public String CssText => CssKeywords.Normal;
148+
public override String GetCssText() => CssKeywords.Normal;
133149

134-
public String Stringify(IElement element)
135-
{
136-
return String.Empty;
137-
}
150+
public override String Stringify(IElement element) => String.Empty;
138151
}
139152

140153
/// <summary>
141154
/// The value is replaced by the open quote string from the quotes
142155
/// property.
143156
/// </summary>
144-
private sealed class OpenQuoteContentMode : IContentMode
157+
private sealed class OpenQuoteContentMode : ContentMode
145158
{
146-
public String CssText => CssKeywords.OpenQuote;
159+
public override String GetCssText() => CssKeywords.OpenQuote;
147160

148-
public String Stringify(IElement element)
149-
{
150-
return String.Empty;
151-
}
161+
public override String Stringify(IElement element) => String.Empty;
152162
}
153163

154164
/// <summary>
155165
/// The value is replaced by the close string from the quotes
156166
/// property.
157167
/// </summary>
158-
private sealed class CloseQuoteContentMode : IContentMode
168+
private sealed class CloseQuoteContentMode : ContentMode
159169
{
160-
public String CssText => CssKeywords.CloseQuote;
170+
public override String GetCssText() => CssKeywords.CloseQuote;
161171

162-
public String Stringify(IElement element)
163-
{
164-
return String.Empty;
165-
}
172+
public override String Stringify(IElement element) => String.Empty;
166173
}
167174

168175
/// <summary>
169176
/// Introduces no content, but increments the level of nesting for
170177
/// quotes.
171178
/// </summary>
172-
private sealed class NoOpenQuoteContentMode : IContentMode
179+
private sealed class NoOpenQuoteContentMode : ContentMode
173180
{
174-
public String CssText => CssKeywords.NoOpenQuote;
181+
public override String GetCssText() => CssKeywords.NoOpenQuote;
175182

176-
public String Stringify(IElement element)
177-
{
178-
return String.Empty;
179-
}
183+
public override String Stringify(IElement element) => String.Empty;
180184
}
181185

182186
/// <summary>
183187
/// Introduces no content, but decrements the level of nesting for
184188
/// quotes.
185189
/// </summary>
186-
private sealed class NoCloseQuoteContentMode : IContentMode
190+
private sealed class NoCloseQuoteContentMode : ContentMode
187191
{
188-
public String CssText => CssKeywords.NoCloseQuote;
192+
public override String GetCssText() => CssKeywords.NoCloseQuote;
189193

190-
public String Stringify(IElement element)
191-
{
192-
return String.Empty;
193-
}
194+
public override String Stringify(IElement element) => String.Empty;
194195
}
195196

196197
/// <summary>
197198
/// Text content.
198199
/// </summary>
199-
private sealed class TextContentMode : IContentMode
200+
private sealed class TextContentMode : ContentMode
200201
{
201202
private readonly String _text;
202203

@@ -205,20 +206,17 @@ public TextContentMode(String text)
205206
_text = text;
206207
}
207208

208-
public String CssText => _text.CssString();
209+
public override String GetCssText() => _text.CssString();
209210

210-
public String Stringify(IElement element)
211-
{
212-
return _text;
213-
}
211+
public override String Stringify(IElement element) => _text;
214212
}
215213

216214
/// <summary>
217215
/// The generated text is the value of all counters with the given name
218216
/// in scope at this pseudo-element, from outermost to innermost
219217
/// separated by the specified string.
220218
/// </summary>
221-
private sealed class CounterContentMode : IContentMode
219+
private sealed class CounterContentMode : ContentMode
222220
{
223221
private readonly CounterDefinition _counter;
224222

@@ -227,19 +225,16 @@ public CounterContentMode(CounterDefinition counter)
227225
_counter = counter;
228226
}
229227

230-
public String CssText => _counter.CssText;
228+
public override String GetCssText() => _counter.CssText;
231229

232-
public String Stringify(IElement element)
233-
{
234-
return String.Empty;
235-
}
230+
public override String Stringify(IElement element) => String.Empty;
236231
}
237232

238233
/// <summary>
239234
/// Returns the value of the element's attribute X as a string. If
240235
/// there is no attribute X, an empty string is returned.
241236
/// </summary>
242-
private sealed class AttributeContentMode : IContentMode
237+
private sealed class AttributeContentMode : ContentMode
243238
{
244239
private readonly String _attribute;
245240

@@ -248,20 +243,17 @@ public AttributeContentMode(String attribute)
248243
_attribute = attribute;
249244
}
250245

251-
public String CssText => FunctionNames.Attr.CssFunction(_attribute);
246+
public override String GetCssText() => FunctionNames.Attr.CssFunction(_attribute);
252247

253-
public String Stringify(IElement element)
254-
{
255-
return element.GetAttribute(_attribute) ?? String.Empty;
256-
}
248+
public override String Stringify(IElement element) => element.GetAttribute(_attribute) ?? String.Empty;
257249
}
258250

259251
/// <summary>
260252
/// The value is a URI that designates an external resource (such as an
261253
/// image). If the resource or image can't be displayed, it is either
262254
/// ignored or some placeholder shows up.
263255
/// </summary>
264-
private sealed class UrlContentMode : IContentMode
256+
private sealed class UrlContentMode : ContentMode
265257
{
266258
private readonly CssUrlValue _url;
267259

@@ -270,12 +262,9 @@ public UrlContentMode(CssUrlValue url)
270262
_url = url;
271263
}
272264

273-
public String CssText => _url.CssText;
265+
public override String GetCssText() => _url.CssText;
274266

275-
public String Stringify(IElement element)
276-
{
277-
return String.Empty;
278-
}
267+
public override String Stringify(IElement element) => String.Empty;
279268
}
280269
}
281270
}

src/AngleSharp.Css/Dom/ICssProperty.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
namespace AngleSharp.Css.Dom
22
{
33
using AngleSharp.Attributes;
4+
using AngleSharp.Css.Values;
45
using System;
56

67
/// <summary>
@@ -61,8 +62,8 @@ public interface ICssProperty : IStyleFormattable
6162
/// <summary>
6263
/// Creates a computed version of the property.
6364
/// </summary>
64-
/// <param name="device">The device to compute for.</param>
65+
/// <param name="context">The context to compute for.</param>
6566
/// <returns>The computed version of the property if uncomputed, otherwise the same.</returns>
66-
ICssProperty Compute(IRenderDevice device);
67+
ICssProperty Compute(ICssComputeContext context);
6768
}
6869
}

src/AngleSharp.Css/Dom/ICssValue.cs

+8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
namespace AngleSharp.Css.Dom
22
{
33
using System;
4+
using AngleSharp.Css.Values;
45

56
/// <summary>
67
/// Represents a value of a CSS property.
@@ -11,5 +12,12 @@ public interface ICssValue
1112
/// The text representation of the value.
1213
/// </summary>
1314
String CssText { get; }
15+
16+
/// <summary>
17+
/// Computes the current value using the given context.
18+
/// </summary>
19+
/// <param name="context">The used compute context.</param>
20+
/// <returns>The computed value or the original value, if already computed.</returns>
21+
ICssValue Compute(ICssComputeContext context);
1422
}
1523
}

src/AngleSharp.Css/Dom/Internal/CssProperty.cs

+5-5
Original file line numberDiff line numberDiff line change
@@ -89,13 +89,13 @@ public Boolean IsImportant
8989

9090
#region Methods
9191

92-
public ICssProperty Compute(IRenderDevice device)
92+
public ICssProperty Compute(ICssComputeContext context)
9393
{
94-
if (_value is Length length && length.Type != Length.Unit.Px)
94+
var computedValue = _value?.Compute(context);
95+
96+
if (computedValue != _value)
9597
{
96-
var px = length.ToPixel(device);
97-
var value = new Length(px, Length.Unit.Px);
98-
return new CssProperty(_name, _converter, _flags, value, _important);
98+
return new CssProperty(_name, _converter, _flags, computedValue, _important);
9999
}
100100

101101
return this;

src/AngleSharp.Css/Dom/Internal/CssStyleDeclaration.cs

-5
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,6 @@ sealed class CssStyleDeclaration : ICssStyleDeclaration
3232

3333
#region ctor
3434

35-
public CssStyleDeclaration()
36-
: this(default(IBrowsingContext))
37-
{
38-
}
39-
4035
public CssStyleDeclaration(IBrowsingContext context)
4136
{
4237
_declarations = new List<ICssProperty>();

src/AngleSharp.Css/Extensions/CssOmExtensions.cs

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
namespace AngleSharp.Css.Dom
22
{
33
using AngleSharp.Css.Parser;
4+
using AngleSharp.Css.Values;
45
using AngleSharp.Text;
56
using System;
67
using System.Linq;
@@ -66,18 +67,18 @@ public static ICssValue GetValueOf(this ICssStyleRule rule, String propertyName)
6667
}
6768

6869
/// <summary>
69-
/// Computes the values with knowledge of the device.
70+
/// Computes the declarations using the given compute context.
7071
/// </summary>
7172
/// <param name="style">The base (raw) style.</param>
72-
/// <param name="device">The device to use for the calculation.</param>
73+
/// <param name="context">The context to use for the calculation.</param>
7374
/// <returns>A new style declaration with the existing or computed values.</returns>
74-
public static ICssStyleDeclaration Compute(this ICssStyleDeclaration style, IRenderDevice device)
75+
public static ICssStyleDeclaration Compute(this ICssStyleDeclaration style, ICssComputeContext context)
7576
{
76-
var computedStyle = new CssStyleDeclaration();
77+
var computedStyle = new CssStyleDeclaration(context.Context);
7778

7879
foreach (var property in style)
7980
{
80-
computedStyle.AddProperty(property.Compute(device));
81+
computedStyle.AddProperty(property.Compute(context));
8182
}
8283

8384
return computedStyle;

0 commit comments

Comments
 (0)