Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/html_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ class HtmlParser extends StatelessWidget {
List<StyledElement> toRemove = new List<StyledElement>();
bool lastChildBlock = true;
tree.children?.forEach((child) {
if (child is EmptyContentElement) {
if (child is EmptyContentElement || child is EmptyLayoutElement) {
toRemove.add(child);
} else if (child is TextContentElement && (child.text.isEmpty)) {
toRemove.add(child);
Expand Down
2 changes: 2 additions & 0 deletions lib/src/html_elements.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ const STYLED_ELEMENTS = [
"p",
"pre",
"section",
"summary",
"ul",
];

Expand All @@ -88,6 +89,7 @@ const REPLACED_ELEMENTS = [
];

const LAYOUT_ELEMENTS = [
"details",
"table",
"tr",
"tbody",
Expand Down
2 changes: 1 addition & 1 deletion lib/src/interactable_element.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ InteractableElement parseInteractableElement(
}

return interactableElement;
}
}
77 changes: 75 additions & 2 deletions lib/src/layout_element.dart
Original file line number Diff line number Diff line change
Expand Up @@ -251,11 +251,84 @@ TableStyleElement parseTableDefinitionElement(
}
}

class DetailsContentElement extends LayoutElement {
List<dom.Element> elementList;

DetailsContentElement({
String name,
List<StyledElement> children,
dom.Element node,
this.elementList,
}) : super(name: name, node: node, children: children);

@override
Widget toWidget(RenderContext context) {
List<InlineSpan> childrenList = children?.map((tree) => context.parser.parseTree(context, tree))?.toList();
List<InlineSpan> toRemove = [];
if (childrenList != null) {
for (InlineSpan child in childrenList) {
if (child is TextSpan && child.text != null && child.text.trim().isEmpty) {
toRemove.add(child);
}
}
for (InlineSpan child in toRemove) {
childrenList.remove(child);
}
}
InlineSpan firstChild = childrenList?.isNotEmpty == true ? childrenList.first : null;
return ExpansionTile(
expandedAlignment: Alignment.centerLeft,
title: elementList?.isNotEmpty == true && elementList?.first?.localName == "summary" ? StyledText(
textSpan: TextSpan(
style: style.generateTextStyle(),
children: [firstChild] ?? [],
),
style: style,
) : Text("Details"),
children: [
StyledText(
textSpan: TextSpan(
style: style.generateTextStyle(),
children: getChildren(childrenList, context, elementList?.isNotEmpty == true && elementList?.first?.localName == "summary" ? firstChild : null)
),
style: style,
),
]
);
}

List<InlineSpan> getChildren(List<InlineSpan> children, RenderContext context, InlineSpan firstChild) {
if (children == null) {
return [];
} else {
if (firstChild != null) children.removeAt(0);
return children;
}
}
}

class EmptyLayoutElement extends LayoutElement {
EmptyLayoutElement({String name = "empty"}) : super(name: name);

@override
Widget toWidget(_) => null;
}

LayoutElement parseLayoutElement(
dom.Element element,
List<StyledElement> children,
dom.Element element,
List<StyledElement> children,
) {
switch (element.localName) {
case "details":
if (children?.isEmpty ?? false) {
return EmptyLayoutElement();
}
return DetailsContentElement(
node: element,
name: element.localName,
children: children,
elementList: element.children
);
case "table":
return TableLayoutElement(
name: element.localName,
Expand Down