1
- import 'dart:math' ;
2
1
import 'dart:ui' ;
3
2
4
3
import 'package:csslib/visitor.dart' as css;
@@ -17,17 +16,21 @@ Style declarationsToStyle(Map<String?, List<css.Expression>> declarations) {
17
16
style.backgroundColor = ExpressionMapping .expressionToColor (value.first) ?? style.backgroundColor;
18
17
break ;
19
18
case 'border' :
20
- List <css.LiteralTerm > borderWidths = value.whereType< css.LiteralTerm > ().toList ();
19
+ List <css.LiteralTerm ?> ? borderWidths = value.whereType< css.LiteralTerm > ().toList ();
21
20
/// List<css.LiteralTerm> might include other values than the ones we want for [BorderSide.width] , so make sure to remove those before passing it to [ExpressionMapping]
22
- borderWidths.removeWhere ((element) => element.text != "thin" && element.text != "medium" && element.text != "thick"
23
- && ! (element is css.LengthTerm ) && ! (element is css.PercentageTerm ) && ! (element is css.EmTerm ) && ! (element is css.RemTerm ) && ! (element is css.NumberTerm ));
24
- List <css.Expression > borderColors = value.where ((element) => ExpressionMapping .expressionToColor (element) != null ).toList ();
25
- List <css.LiteralTerm > potentialStyles = value.whereType< css.LiteralTerm > ().toList ();
21
+ borderWidths.removeWhere ((element) => element != null && element.text != "thin"
22
+ && element.text != "medium" && element.text != "thick"
23
+ && ! (element is css.LengthTerm ) && ! (element is css.PercentageTerm )
24
+ && ! (element is css.EmTerm ) && ! (element is css.RemTerm )
25
+ && ! (element is css.NumberTerm )
26
+ );
27
+ List <css.Expression ?>? borderColors = value.where ((element) => ExpressionMapping .expressionToColor (element) != null ).toList ();
28
+ List <css.LiteralTerm ?>? potentialStyles = value.whereType< css.LiteralTerm > ().toList ();
26
29
/// Currently doesn't matter, as Flutter only supports "solid" or "none", but may support more in the future.
27
30
List <String > possibleBorderValues = ["dotted" , "dashed" , "solid" , "double" , "groove" , "ridge" , "inset" , "outset" , "none" , "hidden" ];
28
31
/// List<css.LiteralTerm> might include other values than the ones we want for [BorderSide.style] , so make sure to remove those before passing it to [ExpressionMapping]
29
- potentialStyles.removeWhere ((element) => ! possibleBorderValues.contains (element.text));
30
- List <css.LiteralTerm > borderStyles = potentialStyles;
32
+ potentialStyles.removeWhere ((element) => element != null && ! possibleBorderValues.contains (element.text));
33
+ List <css.LiteralTerm ?> ? borderStyles = potentialStyles;
31
34
style.border = ExpressionMapping .expressionToBorder (borderWidths, borderStyles, borderColors);
32
35
break ;
33
36
case 'color' :
@@ -66,8 +69,15 @@ Style declarationsToStyle(Map<String?, List<css.Expression>> declarations) {
66
69
textDecorationList.removeWhere ((element) => element != null && element.text != "none"
67
70
&& element.text != "overline" && element.text != "underline" && element.text != "line-through" );
68
71
List <css.Expression ?>? nullableList = value;
69
- css.Expression ? textDecorationColor = nullableList.firstWhere (
70
- (css.Expression ? element) => element is css.HexColorTerm || element is css.FunctionTerm , orElse: () => null );
72
+ css.Expression ? textDecorationColor;
73
+ /// orElse: will not allow me to return null (even if the compiler says its okay, it errors on runtime).
74
+ /// try/catch is a workaround for this.
75
+ try {
76
+ textDecorationColor = nullableList.firstWhere (
77
+ (css.Expression ? element) => element is css.HexColorTerm || element is css.FunctionTerm );
78
+ } catch (e) {
79
+ textDecorationColor = null ;
80
+ }
71
81
List <css.LiteralTerm ?>? potentialStyles = value.whereType< css.LiteralTerm > ().toList ();
72
82
/// 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]
73
83
potentialStyles.removeWhere ((element) => element != null && element.text != "solid"
@@ -130,12 +140,12 @@ class DeclarationVisitor extends css.Visitor {
130
140
//Mapping functions
131
141
class ExpressionMapping {
132
142
133
- static Border expressionToBorder (List <css.Expression > borderWidths, List <css.LiteralTerm > borderStyles, List <css.Expression > borderColors) {
143
+ static Border expressionToBorder (List <css.Expression ?> ? borderWidths, List <css.LiteralTerm ?> ? borderStyles, List <css.Expression ?> ? borderColors) {
134
144
CustomBorderSide left = CustomBorderSide ();
135
145
CustomBorderSide top = CustomBorderSide ();
136
146
CustomBorderSide right = CustomBorderSide ();
137
147
CustomBorderSide bottom = CustomBorderSide ();
138
- if (borderWidths != null ) {
148
+ if (borderWidths != null && borderWidths.isNotEmpty ) {
139
149
top.width = expressionToBorderWidth (borderWidths.first);
140
150
if (borderWidths.length == 4 ) {
141
151
right.width = expressionToBorderWidth (borderWidths[1 ]);
@@ -158,7 +168,7 @@ class ExpressionMapping {
158
168
right.width = expressionToBorderWidth (borderWidths.first);
159
169
}
160
170
}
161
- if (borderStyles != null ) {
171
+ if (borderStyles != null && borderStyles.isNotEmpty ) {
162
172
top.style = expressionToBorderStyle (borderStyles.first);
163
173
if (borderStyles.length == 4 ) {
164
174
right.style = expressionToBorderStyle (borderStyles[1 ]);
@@ -181,7 +191,7 @@ class ExpressionMapping {
181
191
right.style = expressionToBorderStyle (borderStyles.first);
182
192
}
183
193
}
184
- if (borderColors != null ) {
194
+ if (borderColors != null && borderColors.isNotEmpty ) {
185
195
top.color = expressionToColor (borderColors.first);
186
196
if (borderColors.length == 4 ) {
187
197
right.color = expressionToColor (borderColors[1 ]);
@@ -205,24 +215,24 @@ class ExpressionMapping {
205
215
}
206
216
}
207
217
return Border (
208
- top: BorderSide (width: top.width, color: top.color, style: top.style),
209
- right: BorderSide (width: right.width, color: right.color, style: right.style),
210
- bottom: BorderSide (width: bottom.width, color: bottom.color, style: bottom.style),
211
- left: BorderSide (width: left.width, color: left.color, style: left.style)
218
+ top: BorderSide (width: top.width, color: top.color ?? Colors .black , style: top.style),
219
+ right: BorderSide (width: right.width, color: right.color ?? Colors .black , style: right.style),
220
+ bottom: BorderSide (width: bottom.width, color: bottom.color ?? Colors .black , style: bottom.style),
221
+ left: BorderSide (width: left.width, color: left.color ?? Colors .black , style: left.style)
212
222
);
213
223
}
214
224
215
- static double expressionToBorderWidth (css.LiteralTerm value) {
225
+ static double expressionToBorderWidth (css.Expression ? value) {
216
226
if (value is css.NumberTerm ) {
217
- return double .tryParse (value.text);
227
+ return double .tryParse (value.text) ?? 1.0 ;
218
228
} else if (value is css.PercentageTerm ) {
219
- return double .tryParse (value.text) / 100 ;
229
+ return ( double .tryParse (value.text) ?? 400 ) / 100 ;
220
230
} else if (value is css.EmTerm ) {
221
- return double .tryParse (value.text);
231
+ return double .tryParse (value.text) ?? 1.0 ;
222
232
} else if (value is css.RemTerm ) {
223
- return double .tryParse (value.text);
233
+ return double .tryParse (value.text) ?? 1.0 ;
224
234
} else if (value is css.LengthTerm ) {
225
- return double .tryParse (value.text.replaceAll (new RegExp (r'\s+(\d+\.\d+)\s+' ), '' ));
235
+ return double .tryParse (value.text.replaceAll (new RegExp (r'\s+(\d+\.\d+)\s+' ), '' )) ?? 1.0 ;
226
236
} else if (value is css.LiteralTerm ) {
227
237
switch (value.text) {
228
238
case "thin" :
@@ -233,27 +243,29 @@ class ExpressionMapping {
233
243
return 6.0 ;
234
244
}
235
245
}
236
- return null ;
246
+ return 4.0 ;
237
247
}
238
248
239
- static BorderStyle expressionToBorderStyle (css.LiteralTerm value) {
240
- if (value.text != "none" && value.text != "hidden" ) {
249
+ static BorderStyle expressionToBorderStyle (css.LiteralTerm ? value) {
250
+ if (value != null && value .text != "none" && value.text != "hidden" ) {
241
251
return BorderStyle .solid;
242
252
}
243
253
return BorderStyle .none;
244
254
}
245
255
246
- static Color ? expressionToColor (css.Expression value) {
247
- if (value is css.HexColorTerm ) {
248
- return stringToColor (value.text);
249
- } else if (value is css.FunctionTerm ) {
250
- if (value.text == 'rgba' || value.text == 'rgb' ) {
251
- return rgbOrRgbaToColor (value.span! .text);
252
- } else if (value.text == 'hsla' || value.text == 'hsl' ) {
253
- return hslToRgbToColor (value.span! .text);
256
+ static Color ? expressionToColor (css.Expression ? value) {
257
+ if (value != null ) {
258
+ if (value is css.HexColorTerm ) {
259
+ return stringToColor (value.text);
260
+ } else if (value is css.FunctionTerm ) {
261
+ if (value.text == 'rgba' || value.text == 'rgb' ) {
262
+ return rgbOrRgbaToColor (value.span! .text);
263
+ } else if (value.text == 'hsla' || value.text == 'hsl' ) {
264
+ return hslToRgbToColor (value.span! .text);
265
+ }
266
+ } else if (value is css.LiteralTerm ) {
267
+ return namedColorToColor (value.text);
254
268
}
255
- } else if (value is css.LiteralTerm ) {
256
- return namedColorToColor (value.text);
257
269
}
258
270
return null ;
259
271
}
@@ -562,28 +574,31 @@ class ExpressionMapping {
562
574
}
563
575
564
576
static Color hslToRgbToColor (String text) {
565
- print (text);
566
577
final hslText = text.replaceAll (')' , '' ).replaceAll (' ' , '' );
567
578
final hslValues = hslText.split (',' ).toList ();
568
- List <double > parsedHsl = [];
579
+ List <double ? > parsedHsl = [];
569
580
hslValues.forEach ((element) {
570
- if (element.contains ("%" )) {
571
- parsedHsl.add (double .tryParse (element.replaceAll ("%" , "" )) * 0.01 );
581
+ if (element.contains ("%" ) && double . tryParse (element. replaceAll ( "%" , "" )) != null ) {
582
+ parsedHsl.add (double .tryParse (element.replaceAll ("%" , "" ))! * 0.01 );
572
583
} else {
573
- parsedHsl.add (double .tryParse (element));
584
+ if (element != hslValues.first && (double .tryParse (element) == null || double .tryParse (element)! > 1 )) {
585
+ parsedHsl.add (null );
586
+ } else {
587
+ parsedHsl.add (double .tryParse (element));
588
+ }
574
589
}
575
590
});
576
- if (parsedHsl.length == 4 ) {
577
- return HSLColor .fromAHSL (parsedHsl.last, parsedHsl.first, parsedHsl[1 ], parsedHsl[2 ]).toColor ();
578
- }
579
- return HSLColor .fromAHSL (1.0 , parsedHsl.first, parsedHsl[1 ], parsedHsl.last).toColor ();
591
+ if (parsedHsl.length == 4 && ! parsedHsl.contains (null )) {
592
+ return HSLColor .fromAHSL (parsedHsl.last! , parsedHsl.first! , parsedHsl[1 ]! , parsedHsl[2 ]! ).toColor ();
593
+ } else if (parsedHsl.length == 3 && ! parsedHsl.contains (null )) {
594
+ return HSLColor .fromAHSL (1.0 , parsedHsl.first! , parsedHsl[1 ]! , parsedHsl.last! ).toColor ();
595
+ } else return Colors .black;
580
596
}
581
597
582
- static Color namedColorToColor (String text) {
583
- String namedColor = namedColors.keys.firstWhere ((element) => element.toLowerCase () == text.toLowerCase (), orElse: () => null );
584
- if (namedColor != null ) {
585
- return stringToColor (namedColors[namedColor]);
586
- }
587
- return null ;
598
+ static Color ? namedColorToColor (String text) {
599
+ String namedColor = namedColors.keys.firstWhere ((element) => element.toLowerCase () == text.toLowerCase (), orElse: () => "" );
600
+ if (namedColor != "" ) {
601
+ return stringToColor (namedColors[namedColor]! );
602
+ } else return null ;
588
603
}
589
604
}
0 commit comments