@@ -102,6 +102,7 @@ class ParseContext {
102
102
String blockType; // blockType can be 'p', 'div', 'ul', 'ol', 'blockquote'
103
103
bool condenseWhitespace = true ;
104
104
bool spansOnly = false ;
105
+ bool inBlock = false ;
105
106
TextStyle childStyle;
106
107
107
108
ParseContext (
@@ -113,6 +114,7 @@ class ParseContext {
113
114
this .blockType,
114
115
this .condenseWhitespace = true ,
115
116
this .spansOnly = false ,
117
+ this .inBlock = false ,
116
118
this .childStyle}) {
117
119
childStyle = childStyle ?? TextStyle ();
118
120
}
@@ -126,6 +128,7 @@ class ParseContext {
126
128
blockType = parseContext.blockType;
127
129
condenseWhitespace = parseContext.condenseWhitespace;
128
130
spansOnly = parseContext.spansOnly;
131
+ inBlock = parseContext.inBlock;
129
132
childStyle = parseContext.childStyle ?? TextStyle ();
130
133
}
131
134
}
@@ -298,14 +301,14 @@ class HtmlRichTextParser extends StatelessWidget {
298
301
return ;
299
302
}
300
303
301
- // empty strings of whitespace might be significant or not, condense it by default
302
- if (node.text.trim () == "" &&
303
- node.text.indexOf (" " ) != - 1 &&
304
- parseContext.condenseWhitespace) {
305
- node.text = " " ;
306
- }
304
+ // if (node.text.trim() == "" &&
305
+ // node.text.indexOf(" ") != -1 &&
306
+ // parseContext.condenseWhitespace) {
307
+ // node.text = " ";
308
+ // }
307
309
308
310
// we might want to preserve internal whitespace
311
+ // empty strings of whitespace might be significant or not, condense it by default
309
312
String finalText = parseContext.condenseWhitespace
310
313
? condenseHtmlWhitespace (node.text)
311
314
: node.text;
@@ -315,6 +318,9 @@ class HtmlRichTextParser extends StatelessWidget {
315
318
parseContext.parentElement is LinkTextSpan ))
316
319
finalText = finalText.trim ();
317
320
321
+ // if the finalText is actually empty, just return
322
+ if (finalText.isEmpty) return ;
323
+
318
324
// NOW WE HAVE OUR TRULY FINAL TEXT
319
325
// debugPrint("Plain Text Node: '$finalText'");
320
326
@@ -326,10 +332,48 @@ class HtmlRichTextParser extends StatelessWidget {
326
332
327
333
// in this class, a ParentElement must be a BlockText, LinkTextSpan, Row, Column, TextSpan
328
334
335
+ // the parseContext might actually be a block level style element, so we
336
+ // need to honor the indent and styling specified by that block style.
337
+ // e.g. ol, ul, blockquote
338
+ bool treatLikeBlock =
339
+ ['blockquote' , 'ul' , 'ol' ].indexOf (parseContext.blockType) != - 1 ;
340
+
329
341
// if there is no parentElement, contain the span in a BlockText
330
342
if (parseContext.parentElement == null ) {
343
+ // if this is inside a context that should be treated like a block
344
+ // but the context is not actually a block, create a block
345
+ // and append it to the root widget tree
346
+ if (treatLikeBlock) {
347
+ Decoration decoration;
348
+ if (parseContext.blockType == 'blockquote' ) {
349
+ decoration = BoxDecoration (
350
+ border:
351
+ Border (left: BorderSide (color: Colors .black38, width: 2.0 )),
352
+ );
353
+ parseContext.childStyle = parseContext.childStyle.merge (TextStyle (
354
+ fontStyle: FontStyle .italic,
355
+ ));
356
+ }
357
+ BlockText blockText = BlockText (
358
+ margin: EdgeInsets .only (
359
+ top: 8.0 ,
360
+ bottom: 8.0 ,
361
+ left: parseContext.indentLevel * indentSize),
362
+ padding: EdgeInsets .all (2.0 ),
363
+ decoration: decoration,
364
+ child: RichText (
365
+ textAlign: TextAlign .left,
366
+ text: span,
367
+ ),
368
+ );
369
+ parseContext.rootWidgetList.add (blockText);
370
+ } else {
371
+ parseContext.rootWidgetList
372
+ .add (BlockText (child: RichText (text: span)));
373
+ }
374
+
375
+ // this allows future items to be added as children
331
376
parseContext.parentElement = span;
332
- parseContext.rootWidgetList.add (BlockText (child: RichText (text: span)));
333
377
334
378
// if the parent is a LinkTextSpan, keep the main attributes of that span going.
335
379
} else if (parseContext.parentElement is LinkTextSpan ) {
@@ -348,6 +392,7 @@ class HtmlRichTextParser extends StatelessWidget {
348
392
}
349
393
return ;
350
394
}
395
+
351
396
// OTHER ELEMENT NODES
352
397
else if (node is dom.Element ) {
353
398
assert (() {
@@ -460,6 +505,7 @@ class HtmlRichTextParser extends StatelessWidget {
460
505
child: RichText (text: span),
461
506
);
462
507
parseContext.rootWidgetList.add (blockElement);
508
+ nextContext.inBlock = true ;
463
509
}
464
510
nextContext.childStyle = linkStyle;
465
511
nextContext.parentElement = span;
@@ -559,6 +605,7 @@ class HtmlRichTextParser extends StatelessWidget {
559
605
parseContext.rootWidgetList.add (blockText);
560
606
nextContext.parentElement = blockText.child.text;
561
607
nextContext.spansOnly = true ;
608
+ nextContext.inBlock = true ;
562
609
break ;
563
610
564
611
case "h1" :
@@ -614,10 +661,11 @@ class HtmlRichTextParser extends StatelessWidget {
614
661
));
615
662
}
616
663
BlockText blockText = BlockText (
617
- margin: EdgeInsets .symmetric (vertical: 8.0 ),
618
- padding: EdgeInsets .only (
619
- left: parseContext.indentLevel * indentSize,
620
- ),
664
+ margin: EdgeInsets .only (
665
+ top: 8.0 ,
666
+ bottom: 8.0 ,
667
+ left: parseContext.indentLevel * indentSize),
668
+ padding: EdgeInsets .all (2.0 ),
621
669
decoration: decoration,
622
670
child: RichText (
623
671
textAlign: textAlign,
@@ -631,6 +679,7 @@ class HtmlRichTextParser extends StatelessWidget {
631
679
parseContext.rootWidgetList.add (blockText);
632
680
nextContext.parentElement = blockText.child.text;
633
681
nextContext.spansOnly = true ;
682
+ nextContext.inBlock = true ;
634
683
}
635
684
}
636
685
0 commit comments