Skip to content

Commit 28da60f

Browse files
committed
Improve text-decoration algorithm and make units optional on FontSize and LineHeight
1 parent cc3c833 commit 28da60f

File tree

4 files changed

+40
-38
lines changed

4 files changed

+40
-38
lines changed

lib/html_parser.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@ class HtmlParser extends StatelessWidget {
685685
tree.children?.forEach((child) {
686686
if ((child.style.fontSize?.size ?? parentFontSize) < 0) {
687687
child.style.fontSize =
688-
FontSize(parentFontSize * -child.style.fontSize.size, "");
688+
FontSize(parentFontSize * -child.style.fontSize.size);
689689
}
690690

691691
_processFontSize(child);

lib/src/css_parser.dart

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,17 @@ Style declarationsToStyle(Map<String, List<css.Expression>> declarations) {
4242
style.textAlign = ExpressionMapping.expressionToTextAlign(value.first);
4343
break;
4444
case 'text-decoration':
45-
List<css.LiteralTerm> exp1 = value.whereType<css.LiteralTerm>().toList();
46-
exp1.removeWhere((element) => element.text != "overline" && element.text != "underline" && element.text != "line-through");
47-
css.Expression exp2 = value.firstWhere((element) => element is css.HexColorTerm || element is css.FunctionTerm, orElse: null);
45+
List<css.LiteralTerm> textDecorationList = value.whereType<css.LiteralTerm>().toList();
46+
/// List<css.LiteralTerm> might include other values than the ones we want for [textDecorationList], so make sure to remove those before passing it to [ExpressionMapping]
47+
textDecorationList.removeWhere((element) => element.text != "overline" && element.text != "underline" && element.text != "line-through");
48+
css.Expression textDecorationColor = value.firstWhere((element) => element is css.HexColorTerm || element is css.FunctionTerm, orElse: null);
4849
List<css.LiteralTerm> temp = value.whereType<css.LiteralTerm>().toList();
49-
temp.removeWhere((element) => element is css.HexColorTerm || element is css.FunctionTerm);
50-
css.LiteralTerm exp3 = temp.last ?? null;
51-
style.textDecoration = ExpressionMapping.expressionToTextDecorationLine(exp1);
52-
if (exp2 != null) style.textDecorationColor = ExpressionMapping.expressionToColor(exp2);
53-
if (exp3 != null) style.textDecorationStyle = ExpressionMapping.expressionToTextDecorationStyle(exp3);
50+
/// List<css.LiteralTerm> might include other values than the ones we want for [textDecorationStyle], so make sure to remove those before passing it to [ExpressionMapping]
51+
temp.removeWhere((element) => element.text != "solid" && element.text != "double" && element.text != "dashed" && element.text != "dotted" && element.text != "wavy");
52+
css.LiteralTerm textDecorationStyle = temp.last ?? null;
53+
style.textDecoration = ExpressionMapping.expressionToTextDecorationLine(textDecorationList);
54+
if (textDecorationColor != null) style.textDecorationColor = ExpressionMapping.expressionToColor(textDecorationColor);
55+
if (textDecorationStyle != null) style.textDecorationStyle = ExpressionMapping.expressionToTextDecorationStyle(textDecorationStyle);
5456
break;
5557
case 'text-decoration-color':
5658
style.textDecorationColor = ExpressionMapping.expressionToColor(value.first);
@@ -170,15 +172,15 @@ class ExpressionMapping {
170172

171173
static FontSize expressionToFontSize(css.Expression value) {
172174
if (value is css.NumberTerm) {
173-
return FontSize(double.tryParse(value.text), "");
175+
return FontSize(double.tryParse(value.text));
174176
} else if (value is css.PercentageTerm) {
175177
return FontSize.percent(int.tryParse(value.text));
176178
} else if (value is css.EmTerm) {
177179
return FontSize.em(double.tryParse(value.text));
178180
} else if (value is css.RemTerm) {
179181
return FontSize.rem(double.tryParse(value.text));
180182
} else if (value is css.LengthTerm) {
181-
return FontSize(double.tryParse(value.text.replaceAll(new RegExp(r'\s+(\d+\.\d+)\s+'), '')), "");
183+
return FontSize(double.tryParse(value.text.replaceAll(new RegExp(r'\s+(\d+\.\d+)\s+'), '')));
182184
} else if (value is css.LiteralTerm) {
183185
switch (value.text) {
184186
case "xx-small":
@@ -263,7 +265,7 @@ class ExpressionMapping {
263265
} else if (value is css.RemTerm) {
264266
return LineHeight.rem(double.tryParse(value.text));
265267
} else if (value is css.LengthTerm) {
266-
return LineHeight(double.tryParse(value.text.replaceAll(new RegExp(r'\s+(\d+\.\d+)\s+'), '')), "length");
268+
return LineHeight(double.tryParse(value.text.replaceAll(new RegExp(r'\s+(\d+\.\d+)\s+'), '')), units: "length");
267269
}
268270
return LineHeight.normal;
269271
}

lib/src/styled_element.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ StyledElement parseStyledElement(
196196
break;
197197
case "h3":
198198
styledElement.style = Style(
199-
fontSize: FontSize(16.38, ""),
199+
fontSize: FontSize(16.38),
200200
fontWeight: FontWeight.bold,
201201
margin: EdgeInsets.symmetric(vertical: 16.5),
202202
display: Display.BLOCK,
@@ -212,15 +212,15 @@ StyledElement parseStyledElement(
212212
break;
213213
case "h5":
214214
styledElement.style = Style(
215-
fontSize: FontSize(11.62, ""),
215+
fontSize: FontSize(11.62),
216216
fontWeight: FontWeight.bold,
217217
margin: EdgeInsets.symmetric(vertical: 19.25),
218218
display: Display.BLOCK,
219219
);
220220
break;
221221
case "h6":
222222
styledElement.style = Style(
223-
fontSize: FontSize(9.38, ""),
223+
fontSize: FontSize(9.38),
224224
fontWeight: FontWeight.bold,
225225
margin: EdgeInsets.symmetric(vertical: 22),
226226
display: Display.BLOCK,

lib/style.dart

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -288,12 +288,12 @@ class Style {
288288

289289
FontSize finalFontSize = child.fontSize != null ?
290290
fontSize != null && child.fontSize?.units == "em" ?
291-
FontSize(child.fontSize.size * fontSize.size, "") : child.fontSize
291+
FontSize(child.fontSize.size * fontSize.size) : child.fontSize
292292
: fontSize != null && fontSize.size < 0 ?
293293
FontSize.percent(100) : fontSize;
294294
LineHeight finalLineHeight = child.lineHeight != null ?
295295
child.lineHeight?.units == "length" ?
296-
LineHeight(child.lineHeight.size / (finalFontSize == null ? 14 : finalFontSize.size) * 1.2, "") : child.lineHeight
296+
LineHeight(child.lineHeight.size / (finalFontSize == null ? 14 : finalFontSize.size) * 1.2) : child.lineHeight
297297
: lineHeight;
298298
return child.copyWith(
299299
color: child.color ?? color,
@@ -393,13 +393,13 @@ class Style {
393393
this.textDecorationThickness = textStyle.decorationThickness;
394394
this.fontFamily = textStyle.fontFamily;
395395
this.fontFeatureSettings = textStyle.fontFeatures;
396-
this.fontSize = FontSize(textStyle.fontSize, "");
396+
this.fontSize = FontSize(textStyle.fontSize);
397397
this.fontStyle = textStyle.fontStyle;
398398
this.fontWeight = textStyle.fontWeight;
399399
this.letterSpacing = textStyle.letterSpacing;
400400
this.textShadow = textStyle.shadows;
401401
this.wordSpacing = textStyle.wordSpacing;
402-
this.lineHeight = LineHeight(textStyle.height ?? 1.2, "");
402+
this.lineHeight = LineHeight(textStyle.height ?? 1.2);
403403
}
404404
}
405405

@@ -415,19 +415,19 @@ class FontSize {
415415
final double size;
416416
final String units;
417417

418-
const FontSize(this.size, this.units);
418+
const FontSize(this.size, {this.units = ""});
419419

420420
/// A percentage of the parent style's font size.
421421
factory FontSize.percent(int percent) {
422-
return FontSize(percent.toDouble() / -100.0, "%");
422+
return FontSize(percent.toDouble() / -100.0, units: "%");
423423
}
424424

425425
factory FontSize.em(double em) {
426-
return FontSize(em, "em");
426+
return FontSize(em, units: "em");
427427
}
428428

429429
factory FontSize.rem(double rem) {
430-
return FontSize(rem * 16 - 2, "rem");
430+
return FontSize(rem * 16 - 2, units: "rem");
431431
}
432432
// These values are calculated based off of the default (`medium`)
433433
// being 14px.
@@ -436,40 +436,40 @@ class FontSize {
436436
//
437437
// Negative values are computed during parsing to be a percentage of
438438
// the parent style's font size.
439-
static const xxSmall = FontSize(7.875, "");
440-
static const xSmall = FontSize(8.75, "");
441-
static const small = FontSize(11.375, "");
442-
static const medium = FontSize(14.0, "");
443-
static const large = FontSize(15.75, "");
444-
static const xLarge = FontSize(21.0, "");
445-
static const xxLarge = FontSize(28.0, "");
446-
static const smaller = FontSize(-0.83, "");
447-
static const larger = FontSize(-1.2, "");
439+
static const xxSmall = FontSize(7.875);
440+
static const xSmall = FontSize(8.75);
441+
static const small = FontSize(11.375);
442+
static const medium = FontSize(14.0);
443+
static const large = FontSize(15.75);
444+
static const xLarge = FontSize(21.0);
445+
static const xxLarge = FontSize(28.0);
446+
static const smaller = FontSize(-0.83);
447+
static const larger = FontSize(-1.2);
448448
}
449449

450450
class LineHeight {
451451
final double size;
452452
final String units;
453453

454-
const LineHeight(this.size, this.units);
454+
const LineHeight(this.size, {this.units = ""});
455455

456456
factory LineHeight.percent(double percent) {
457-
return LineHeight(percent / 100.0 * 1.2, "%");
457+
return LineHeight(percent / 100.0 * 1.2, units: "%");
458458
}
459459

460460
factory LineHeight.em(double em) {
461-
return LineHeight(em * 1.2, "em");
461+
return LineHeight(em * 1.2, units: "em");
462462
}
463463

464464
factory LineHeight.rem(double rem) {
465-
return LineHeight(rem * 1.2, "rem");
465+
return LineHeight(rem * 1.2, units: "rem");
466466
}
467467

468468
factory LineHeight.number(double num) {
469-
return LineHeight(num * 1.2, "number");
469+
return LineHeight(num * 1.2, units: "number");
470470
}
471471

472-
static const normal = LineHeight(1.2, "");
472+
static const normal = LineHeight(1.2);
473473
}
474474

475475
enum ListStyleType {

0 commit comments

Comments
 (0)