|
1 | 1 | import 'dart:math'; |
2 | 2 |
|
| 3 | +import 'package:collection/collection.dart'; |
3 | 4 | import 'package:flutter/material.dart'; |
4 | 5 | import 'package:flutter/widgets.dart'; |
5 | 6 | import 'package:flutter_html/html_parser.dart'; |
@@ -74,55 +75,70 @@ class RubyElement extends ReplacedElement { |
74 | 75 |
|
75 | 76 | @override |
76 | 77 | Widget toWidget(RenderContext context) { |
77 | | - String? textNode; |
| 78 | + StyledElement? node; |
78 | 79 | List<Widget> widgets = <Widget>[]; |
79 | | - final rubySize = max(9.0, context.style.fontSize!.size! / 2); |
| 80 | + final rubySize = context.parser.style['rt']?.fontSize?.size ?? max(9.0, context.style.fontSize!.size! / 2); |
80 | 81 | final rubyYPos = rubySize + rubySize / 2; |
81 | | - context.tree.children.forEach((c) { |
82 | | - if (c is TextContentElement) { |
83 | | - textNode = c.text; |
| 82 | + List<StyledElement> children = []; |
| 83 | + context.tree.children.forEachIndexed((index, element) { |
| 84 | + if (!((element is TextContentElement) |
| 85 | + && (element.text ?? "").trim().isEmpty |
| 86 | + && index > 0 |
| 87 | + && index + 1 < context.tree.children.length |
| 88 | + && !(context.tree.children[index - 1] is TextContentElement) |
| 89 | + && !(context.tree.children[index + 1] is TextContentElement))) { |
| 90 | + children.add(element); |
84 | 91 | } |
85 | | - if (!(c is TextContentElement)) { |
86 | | - if (c.name == "rt" && textNode != null) { |
87 | | - final widget = Stack( |
88 | | - alignment: Alignment.center, |
89 | | - children: <Widget>[ |
90 | | - Container( |
91 | | - alignment: Alignment.bottomCenter, |
92 | | - child: Center( |
93 | | - child: Transform( |
94 | | - transform: |
95 | | - Matrix4.translationValues(0, -(rubyYPos), 0), |
96 | | - child: ContainerSpan( |
97 | | - newContext: RenderContext( |
98 | | - buildContext: context.buildContext, |
99 | | - parser: context.parser, |
100 | | - style: c.style, |
101 | | - tree: c, |
102 | | - ), |
| 92 | + }); |
| 93 | + children.forEach((c) { |
| 94 | + if (c.name == "rt" && node != null) { |
| 95 | + final widget = Stack( |
| 96 | + alignment: Alignment.center, |
| 97 | + children: <Widget>[ |
| 98 | + Container( |
| 99 | + alignment: Alignment.bottomCenter, |
| 100 | + child: Center( |
| 101 | + child: Transform( |
| 102 | + transform: |
| 103 | + Matrix4.translationValues(0, -(rubyYPos), 0), |
| 104 | + child: ContainerSpan( |
| 105 | + newContext: RenderContext( |
| 106 | + buildContext: context.buildContext, |
| 107 | + parser: context.parser, |
103 | 108 | style: c.style, |
104 | | - child: Text(c.element!.innerHtml, |
105 | | - style: c.style |
106 | | - .generateTextStyle() |
107 | | - .copyWith(fontSize: rubySize)), |
108 | | - )))), |
109 | | - ContainerSpan( |
110 | | - newContext: context, |
111 | | - style: context.style, |
112 | | - child: Text(textNode!.trim(), |
113 | | - style: context.style.generateTextStyle())), |
114 | | - ], |
115 | | - ); |
116 | | - widgets.add(widget); |
117 | | - } |
| 109 | + tree: c, |
| 110 | + ), |
| 111 | + style: c.style, |
| 112 | + child: Text(c.element!.innerHtml, |
| 113 | + style: c.style |
| 114 | + .generateTextStyle() |
| 115 | + .copyWith(fontSize: rubySize)), |
| 116 | + )))), |
| 117 | + ContainerSpan( |
| 118 | + newContext: context, |
| 119 | + style: context.style, |
| 120 | + child: node is TextContentElement ? Text((node as TextContentElement).text?.trim() ?? "", |
| 121 | + style: context.style.generateTextStyle()) : null, |
| 122 | + children: node is TextContentElement ? null : [context.parser.parseTree(context, node!)]), |
| 123 | + ], |
| 124 | + ); |
| 125 | + widgets.add(widget); |
| 126 | + } else { |
| 127 | + node = c; |
118 | 128 | } |
119 | 129 | }); |
120 | | - return Row( |
121 | | - key: AnchorKey.of(context.parser.key, this), |
122 | | - crossAxisAlignment: CrossAxisAlignment.end, |
123 | | - textBaseline: TextBaseline.alphabetic, |
124 | | - mainAxisSize: MainAxisSize.min, |
125 | | - children: widgets, |
| 130 | + return Padding( |
| 131 | + padding: EdgeInsets.only(top: rubySize), |
| 132 | + child: Wrap( |
| 133 | + key: AnchorKey.of(context.parser.key, this), |
| 134 | + runSpacing: rubySize, |
| 135 | + children: widgets.map((e) => Row( |
| 136 | + crossAxisAlignment: CrossAxisAlignment.end, |
| 137 | + textBaseline: TextBaseline.alphabetic, |
| 138 | + mainAxisSize: MainAxisSize.min, |
| 139 | + children: [e], |
| 140 | + )).toList(), |
| 141 | + ), |
126 | 142 | ); |
127 | 143 | } |
128 | 144 | } |
|
0 commit comments