Skip to content

Commit 7fd6fb4

Browse files
committed
Merge remote-tracking branch 'tneotia/feature/text-transform' into everything
2 parents 46006b9 + 099f781 commit 7fd6fb4

File tree

4 files changed

+59
-2
lines changed

4 files changed

+59
-2
lines changed

lib/html_parser.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ class HtmlParser extends StatelessWidget {
449449
);
450450
} else if (tree is ReplacedElement) {
451451
if (tree is TextContentElement) {
452-
return TextSpan(text: tree.text);
452+
return TextSpan(text: tree.text?.transformed(tree.style.textTransform));
453453
} else {
454454
return WidgetSpan(
455455
alignment: tree.alignment,

lib/src/css_parser.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,18 @@ Style declarationsToStyle(Map<String, List<css.Expression>> declarations) {
338338
case 'text-shadow':
339339
style.textShadow = ExpressionMapping.expressionToTextShadow(value);
340340
break;
341+
case 'text-transform':
342+
final val = (value.first as css.LiteralTerm).text;
343+
if (val == 'uppercase') {
344+
style.textTransform = TextTransform.uppercase;
345+
} else if (val == 'lowercase') {
346+
style.textTransform = TextTransform.lowercase;
347+
} else if (val == 'capitalize') {
348+
style.textTransform = TextTransform.capitalize;
349+
} else {
350+
style.textTransform = TextTransform.none;
351+
}
352+
break;
341353
case 'width':
342354
style.width = ExpressionMapping.expressionToPaddingLength(value.first) ?? style.width;
343355
break;

lib/src/utils.dart

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import 'dart:convert';
22
import 'dart:math';
33

4-
import 'package:flutter/gestures.dart';
54
import 'package:flutter/material.dart';
5+
import 'package:flutter_html/style.dart';
66

77
Map<String, String> namedColors = {
88
"White": "#FFFFFF",
@@ -81,4 +81,34 @@ String getRandString(int len) {
8181
var random = Random.secure();
8282
var values = List<int>.generate(len, (i) => random.nextInt(255));
8383
return base64UrlEncode(values);
84+
}
85+
86+
extension TextTransformUtil on String? {
87+
String? transformed(TextTransform? transform) {
88+
if (this == null) return null;
89+
if (transform == TextTransform.uppercase) {
90+
return this!.toUpperCase();
91+
} else if (transform == TextTransform.lowercase) {
92+
return this!.toLowerCase();
93+
} else if (transform == TextTransform.capitalize) {
94+
final stringBuffer = StringBuffer();
95+
96+
var capitalizeNext = true;
97+
for (final letter in this!.toLowerCase().codeUnits) {
98+
// UTF-16: A-Z => 65-90, a-z => 97-122.
99+
if (capitalizeNext && letter >= 97 && letter <= 122) {
100+
stringBuffer.writeCharCode(letter - 32);
101+
capitalizeNext = false;
102+
} else {
103+
// UTF-16: 32 == space, 46 == period
104+
if (letter == 32 || letter == 46) capitalizeNext = true;
105+
stringBuffer.writeCharCode(letter);
106+
}
107+
}
108+
109+
return stringBuffer.toString();
110+
} else {
111+
return this;
112+
}
113+
}
84114
}

lib/style.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,8 @@ class Style {
191191
///
192192
TextOverflow? textOverflow;
193193

194+
TextTransform? textTransform;
195+
194196
Style({
195197
this.backgroundColor = Colors.transparent,
196198
this.color,
@@ -225,6 +227,7 @@ class Style {
225227
this.markerContent,
226228
this.maxLines,
227229
this.textOverflow,
230+
this.textTransform = TextTransform.none,
228231
}) {
229232
if (this.alignment == null &&
230233
(display == Display.BLOCK || display == Display.LIST_ITEM)) {
@@ -317,6 +320,7 @@ class Style {
317320
markerContent: other.markerContent,
318321
maxLines: other.maxLines,
319322
textOverflow: other.textOverflow,
323+
textTransform: other.textTransform,
320324
);
321325
}
322326

@@ -354,6 +358,7 @@ class Style {
354358
wordSpacing: child.wordSpacing ?? wordSpacing,
355359
maxLines: child.maxLines ?? maxLines,
356360
textOverflow: child.textOverflow ?? textOverflow,
361+
textTransform: child.textTransform ?? textTransform,
357362
);
358363
}
359364

@@ -391,6 +396,7 @@ class Style {
391396
Widget? markerContent,
392397
int? maxLines,
393398
TextOverflow? textOverflow,
399+
TextTransform? textTransform,
394400
bool? beforeAfterNull,
395401
}) {
396402
return Style(
@@ -428,6 +434,7 @@ class Style {
428434
markerContent: markerContent ?? this.markerContent,
429435
maxLines: maxLines ?? this.maxLines,
430436
textOverflow: textOverflow ?? this.textOverflow,
437+
textTransform: textTransform ?? this.textTransform,
431438
);
432439
}
433440

@@ -447,6 +454,7 @@ class Style {
447454
this.textShadow = textStyle.shadows;
448455
this.wordSpacing = textStyle.wordSpacing;
449456
this.lineHeight = LineHeight(textStyle.height ?? 1.2);
457+
this.textTransform = TextTransform.none;
450458
}
451459
}
452460

@@ -548,6 +556,13 @@ enum ListStylePosition {
548556
INSIDE,
549557
}
550558

559+
enum TextTransform {
560+
uppercase,
561+
lowercase,
562+
capitalize,
563+
none,
564+
}
565+
551566
enum VerticalAlign {
552567
BASELINE,
553568
SUB,

0 commit comments

Comments
 (0)