Skip to content

Commit

Permalink
Merge pull request #178 from dotneet/ruby
Browse files Browse the repository at this point in the history
[new-parser]Support ruby element.
  • Loading branch information
Sub6Resources authored Dec 12, 2019
2 parents 2931bce + cb2c2bf commit f52af25
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 13 deletions.
7 changes: 7 additions & 0 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ const htmlData = """
dog.<br />
The quick brown fox jumped over the lazy dog.
</p>
<p>
<ruby>
漢<rt>かん</rt>
字<rt>じ</rt>
</ruby>
&nbsp;is Japanese Kanji
</p>
<table>
<colgroup>
<col width="50%" />
Expand Down
2 changes: 1 addition & 1 deletion lib/html_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ class HtmlParser extends StatelessWidget {
return TextSpan(text: tree.text);
} else {
return WidgetSpan(
alignment: PlaceholderAlignment.aboveBaseline,
alignment: tree.alignment,
baseline: TextBaseline.alphabetic,
child: tree.toWidget(context),
);
Expand Down
6 changes: 3 additions & 3 deletions lib/src/html_elements.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ const STYLED_ELEMENTS = [
"kbd",
"mark",
"q",
"rp",
"rt",
"ruby",
"s",
"samp",
"small",
Expand Down Expand Up @@ -87,6 +84,9 @@ const REPLACED_ELEMENTS = [
"svg",
"template",
"video",
"rp",
"rt",
"ruby",
];

const LAYOUT_ELEMENTS = [
Expand Down
82 changes: 73 additions & 9 deletions lib/src/replaced_element.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:convert';
import 'dart:math';

import 'package:chewie/chewie.dart';
import 'package:chewie_audio/chewie_audio.dart';
Expand All @@ -19,14 +20,19 @@ import 'package:html/dom.dart' as dom;
/// A [ReplacedElement] may use its children nodes to determine relevant information
/// (e.g. <video>'s <source> tags), but the children nodes will not be saved as [children].
abstract class ReplacedElement extends StyledElement {
ReplacedElement({
String name,
Style style,
dom.Element node,
}) : super(name: name, children: null, style: style, node: node);
PlaceholderAlignment alignment;

ReplacedElement(
{String name,
Style style,
dom.Element node,
this.alignment = PlaceholderAlignment.aboveBaseline})
: super(name: name, children: null, style: style, node: node);

static List<String> parseMediaSources(List<dom.Element> elements) {
return elements.where((element) => element.localName == 'source').map((element) {
return elements
.where((element) => element.localName == 'source')
.map((element) {
return element.attributes['src'];
}).toList();
}
Expand Down Expand Up @@ -68,7 +74,8 @@ class ImageContentElement extends ReplacedElement {

@override
Widget toWidget(RenderContext context) {
if (src == null) return Text(alt ?? "", style: context.style.generateTextStyle());
if (src == null)
return Text(alt ?? "", style: context.style.generateTextStyle());
if (src.startsWith("data:image") && src.contains("base64,")) {
return Image.memory(base64.decode(src.split("base64,")[1].trim()));
} else {
Expand Down Expand Up @@ -110,7 +117,9 @@ class IframeContentElement extends ReplacedElement {
child: WebView(
initialUrl: src,
javascriptMode: JavascriptMode.unrestricted,
gestureRecognizers: {Factory(() => PlatformViewVerticalGestureRecognizer())},
gestureRecognizers: {
Factory(() => PlatformViewVerticalGestureRecognizer())
},
),
);
}
Expand Down Expand Up @@ -189,7 +198,9 @@ class VideoContentElement extends ReplacedElement {
videoPlayerController: VideoPlayerController.network(
src.first ?? "",
),
placeholder: poster != null ? Image.network(poster) : Container(color: Colors.black),
placeholder: poster != null
? Image.network(poster)
: Container(color: Colors.black),
autoPlay: autoplay,
looping: loop,
showControls: showControls,
Expand Down Expand Up @@ -229,6 +240,55 @@ class EmptyContentElement extends ReplacedElement {
Widget toWidget(_) => null;
}

class RubyElement extends ReplacedElement {
dom.Element element;

RubyElement({@required this.element, String name = "ruby"})
: super(name: name, alignment: PlaceholderAlignment.middle);

@override
Widget toWidget(RenderContext context) {
dom.Node textNode = null;
List<Widget> widgets = List<Widget>();
final rubySize = max(9.0, context.style.fontSize / 2);
final rubyYPos = rubySize + 2;
element.nodes.forEach((c) {
if (c.nodeType == dom.Node.TEXT_NODE) {
textNode = c;
}
if (c is dom.Element) {
if (c.localName == "rt" && textNode != null) {
final widget = Stack(
alignment: Alignment.center,
children: <Widget>[
Container(
alignment: Alignment.bottomCenter,
child: Center(
child: Transform(
transform:
Matrix4.translationValues(0, -(rubyYPos), 0),
child: Text(c.innerHtml,
style: context.style
.generateTextStyle()
.copyWith(fontSize: rubySize))))),
Container(
child: Text(textNode.text.trim(),
style: context.style.generateTextStyle())),
],
);
widgets.add(widget);
}
}
});
return Row(
crossAxisAlignment: CrossAxisAlignment.end,
textBaseline: TextBaseline.alphabetic,
mainAxisSize: MainAxisSize.min,
children: widgets,
);
}
}

ReplacedElement parseReplacedElement(dom.Element element) {
switch (element.localName) {
case "audio":
Expand Down Expand Up @@ -287,6 +347,10 @@ ReplacedElement parseReplacedElement(dom.Element element) {
width: double.tryParse(element.attributes['width'] ?? ""),
height: double.tryParse(element.attributes['height'] ?? ""),
);
case "ruby":
return RubyElement(
element: element,
);
default:
return EmptyContentElement(name: element.localName);
}
Expand Down

0 comments on commit f52af25

Please sign in to comment.