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 README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# HtmlWidget monorepo

[![Flutter](https://github.com/daohoangson/flutter_widget_from_html/actions/workflows/flutter.yml/badge.svg)](https://github.com/daohoangson/flutter_widget_from_html/actions/workflows/flutter.yml)
[![codecov](https://codecov.io/gh/daohoangson/flutter_widget_from_html/branch/master/graph/badge.svg)](https://codecov.io/gh/daohoangson/flutter_widget_from_html)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=daohoangson_flutter_widget_from_html&metric=coverage)](https://sonarcloud.io/summary/new_code?id=daohoangson_flutter_widget_from_html)

This repo contains the source code for everything `HtmlWidget`-related.

Expand Down
2 changes: 1 addition & 1 deletion packages/core/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Flutter Widget from HTML (core)

[![Flutter](https://github.com/daohoangson/flutter_widget_from_html/actions/workflows/flutter.yml/badge.svg)](https://github.com/daohoangson/flutter_widget_from_html/actions/workflows/flutter.yml)
[![codecov](https://codecov.io/gh/daohoangson/flutter_widget_from_html/branch/master/graph/badge.svg)](https://codecov.io/gh/daohoangson/flutter_widget_from_html)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=daohoangson_flutter_widget_from_html&metric=coverage)](https://sonarcloud.io/summary/new_code?id=daohoangson_flutter_widget_from_html)
[![Pub](https://img.shields.io/pub/v/flutter_widget_from_html_core.svg)](https://pub.dev/packages/flutter_widget_from_html_core)

Flutter package to render html as widgets that focuses on correctness and extensibility.
Expand Down
16 changes: 10 additions & 6 deletions packages/core/lib/src/core_helpers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,17 @@ Uint8List? bytesFromDataUri(String dataUri) {
final prefix = match[0]!;
final encoding = match[1];
final data = dataUri.substring(prefix.length);
final bytes = encoding == 'base64'
? base64.decode(data)
: encoding == 'utf8'
? Uint8List.fromList(data.codeUnits)
: null;

return bytes?.isNotEmpty == true ? bytes : null;
final Uint8List bytes;
if (encoding == 'base64') {
bytes = base64.decode(data);
} else if (encoding == 'utf8') {
bytes = Uint8List.fromList(data.codeUnits);
} else {
return null;
}

return bytes.isNotEmpty == true ? bytes : null;
}

/// Parses [key] from [map] as an double literal and return its value.
Expand Down
15 changes: 9 additions & 6 deletions packages/core/lib/src/core_html_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -261,12 +261,15 @@ class HtmlWidgetState extends State<HtmlWidget> {
return built;
}

Widget _sliverToBoxAdapterIfNeeded(Widget child) =>
widget.renderMode == RenderMode.sliverList
? child == widget0
? const SliverToBoxAdapter(child: widget0)
: SliverToBoxAdapter(child: child)
: child;
Widget _sliverToBoxAdapterIfNeeded(Widget child) {
if (widget.renderMode != RenderMode.sliverList) {
return child;
}

return child == widget0
? const SliverToBoxAdapter(child: widget0)
: SliverToBoxAdapter(child: child);
}

Widget _wrapper(Widget child) =>
_RootWidget(resolved: _rootProperties, child: child);
Expand Down
21 changes: 12 additions & 9 deletions packages/core/lib/src/data/css.dart
Original file line number Diff line number Diff line change
Expand Up @@ -217,15 +217,18 @@ class CssBorderSide {
}

static CssBorderSide? _copyWith(CssBorderSide? base, CssBorderSide? value) {
final copied = base == null || value == none
? value
: value == null
? base
: CssBorderSide(
color: value.color ?? base.color,
style: value.style ?? base.style,
width: value.width ?? base.width,
);
final CssBorderSide? copied;
if (base == null || value == none) {
copied = value;
} else if (value == null) {
copied = base;
} else {
copied = CssBorderSide(
color: value.color ?? base.color,
style: value.style ?? base.style,
width: value.width ?? base.width,
);
}

if (copied?.isNoOp == true) {
return none;
Expand Down
2 changes: 1 addition & 1 deletion packages/core/lib/src/internal/core_build_tree.dart
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ class CoreBuildTree extends BuildTree {
}

@override
void flatten(Flattened _) {
void flatten(Flattened f) {
final scopedBuildOps = _buildOps;
if (scopedBuildOps != null) {
for (final op in scopedBuildOps) {
Expand Down
7 changes: 5 additions & 2 deletions packages/core/lib/src/internal/margin_vertical.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:math';

import 'package:flutter/widgets.dart';

import '../core_data.dart';
Expand Down Expand Up @@ -65,8 +67,9 @@ extension SkipBuildHeightPlaceholder on BuildContext {
/// This type of placeholder has special merging logic so they need
/// to be preserved during column contents traversal.
set skipBuildHeightPlaceholder(bool newValue) {
final v = _skipBuildOrZero;
_skipBuild[this] = newValue ? (v + 1) : (v > 0 ? v - 1 : 0);
final delta = newValue ? 1 : -1;
final newCounter = _skipBuildOrZero + delta;
_skipBuild[this] = max(0, newCounter);
}

int get _skipBuildOrZero => _skipBuild[this] ?? 0;
Expand Down
25 changes: 17 additions & 8 deletions packages/core/lib/src/internal/ops/tag_li.dart
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,23 @@ class TagLi {
static StylesMap _defaultStyles(dom.Element element) {
final attrs = element.attributes;
final depth = element.elementDepth;
final listStyleType = element.localName == kTagOrderedList
? (_listStyleTypeFromAttributeType(attrs[kAttributeLiType] ?? '') ??
kCssListStyleTypeDecimal)
: depth == 0
? kCssListStyleTypeDisc
: depth == 1
? kCssListStyleTypeCircle
: kCssListStyleTypeSquare;

final String listStyleType;
if (element.localName == kTagOrderedList) {
listStyleType =
_listStyleTypeFromAttributeType(attrs[kAttributeLiType] ?? '') ??
kCssListStyleTypeDecimal;
} else {
switch (depth) {
case 0:
listStyleType = kCssListStyleTypeDisc;
case 1:
listStyleType = kCssListStyleTypeCircle;
default:
listStyleType = kCssListStyleTypeSquare;
}
}

return {
kCssDisplay: kCssDisplayBlock,
kCssListStyleType: listStyleType,
Expand Down
21 changes: 11 additions & 10 deletions packages/core/lib/src/internal/ops/tag_table.dart
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,10 @@ class TagTable {
}

final columnSpan = cell.columnSpan > 0 ? cell.columnSpan : 1;
final rowSpanDefault = cell.rowSpan == 0 ? group.rows.length : 1;
final rowSpan = min(
rowSpanMax,
cell.rowSpan > 0
? cell.rowSpan
: cell.rowSpan == 0
? group.rows.length
: 1,
cell.rowSpan > 0 ? cell.rowSpan : rowSpanDefault,
);

final builderIndex = data.builders.length;
Expand Down Expand Up @@ -310,11 +307,15 @@ class TagTable {
case kCssDisplayTableHeaderGroup:
case kCssDisplayTableRowGroup:
case kCssDisplayTableFooterGroup:
final group = which == kCssDisplayTableHeaderGroup
? data.header
: which == kCssDisplayTableRowGroup
? data.newBody()
: data.footer;
final _TagTableRowGroup group;
switch (which) {
case kCssDisplayTableHeaderGroup:
group = data.header;
case kCssDisplayTableRowGroup:
group = data.newBody();
default:
group = data.footer;
}
subTree.register(group._groupOp);
case kCssDisplayTableRow:
subTree.register(data.newBody().newRow()._rowOp);
Expand Down
34 changes: 23 additions & 11 deletions packages/core/lib/src/internal/parser/color.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,31 @@ CssColor? tryParseColor(css.Expression? expression) {
final params = expression.params;
if (params.length >= 3) {
final param0 = params[0];
final h = param0 is css.NumberTerm
? _parseColorHue(param0.number)
: param0 is css.AngleTerm
? _parseColorHue(param0.angle, param0.unit)
: null;
final double? h;
if (param0 is css.NumberTerm) {
h = _parseColorHue(param0.number);
} else if (param0 is css.AngleTerm) {
h = _parseColorHue(param0.angle, param0.unit);
} else {
h = null;
}

final param1 = params[1];
final s = param1 is css.PercentageTerm
? param1.valueAsDouble.clamp(0.0, 1.0)
: null;
final double? s;
if (param1 is css.PercentageTerm) {
s = param1.valueAsDouble.clamp(0.0, 1.0);
} else {
s = null;
}

final param2 = params[2];
final l = param2 is css.PercentageTerm
? param2.valueAsDouble.clamp(0.0, 1.0)
: null;
final double? l;
if (param2 is css.PercentageTerm) {
l = param2.valueAsDouble.clamp(0.0, 1.0);
} else {
l = null;
}

final hslA = params.length >= 4 ? _parseColorAlpha(params[3]) : 1.0;
if (h != null && s != null && l != null && hslA != null) {
final hslValue = HSLColor.fromAHSL(hslA, h, s, l).toColor();
Expand Down
2 changes: 1 addition & 1 deletion packages/enhanced/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Flutter Widget from HTML

[![Flutter](https://github.com/daohoangson/flutter_widget_from_html/actions/workflows/flutter.yml/badge.svg)](https://github.com/daohoangson/flutter_widget_from_html/actions/workflows/flutter.yml)
[![codecov](https://codecov.io/gh/daohoangson/flutter_widget_from_html/branch/master/graph/badge.svg)](https://codecov.io/gh/daohoangson/flutter_widget_from_html)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=daohoangson_flutter_widget_from_html&metric=coverage)](https://sonarcloud.io/summary/new_code?id=daohoangson_flutter_widget_from_html)
[![Pub](https://img.shields.io/pub/v/flutter_widget_from_html.svg)](https://pub.dev/packages/flutter_widget_from_html)

Flutter package to render html as widgets that supports hyperlink, image, audio, video, iframe
Expand Down
2 changes: 1 addition & 1 deletion packages/fwfh_cached_network_image/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# CachedNetworkImageFactory

[![Flutter](https://github.com/daohoangson/flutter_widget_from_html/actions/workflows/flutter.yml/badge.svg)](https://github.com/daohoangson/flutter_widget_from_html/actions/workflows/flutter.yml)
[![codecov](https://codecov.io/gh/daohoangson/flutter_widget_from_html/branch/master/graph/badge.svg)](https://codecov.io/gh/daohoangson/flutter_widget_from_html)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=daohoangson_flutter_widget_from_html&metric=coverage)](https://sonarcloud.io/summary/new_code?id=daohoangson_flutter_widget_from_html)
[![Pub](https://img.shields.io/pub/v/fwfh_cached_network_image.svg)](https://pub.dev/packages/fwfh_cached_network_image)

WidgetFactory extension to render IMG with [cached_network_image](https://pub.dev/packages/cached_network_image) plugin.
Expand Down
2 changes: 1 addition & 1 deletion packages/fwfh_chewie/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# ChewieFactory

[![Flutter](https://github.com/daohoangson/flutter_widget_from_html/actions/workflows/flutter.yml/badge.svg)](https://github.com/daohoangson/flutter_widget_from_html/actions/workflows/flutter.yml)
[![codecov](https://codecov.io/gh/daohoangson/flutter_widget_from_html/branch/master/graph/badge.svg)](https://codecov.io/gh/daohoangson/flutter_widget_from_html)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=daohoangson_flutter_widget_from_html&metric=coverage)](https://sonarcloud.io/summary/new_code?id=daohoangson_flutter_widget_from_html)
[![Pub](https://img.shields.io/pub/v/fwfh_chewie.svg)](https://pub.dev/packages/fwfh_chewie)

WidgetFactory extension to render VIDEO with the [chewie](https://pub.dev/packages/chewie) plugin.
Expand Down
2 changes: 1 addition & 1 deletion packages/fwfh_just_audio/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# JustAudioFactory

[![Flutter](https://github.com/daohoangson/flutter_widget_from_html/actions/workflows/flutter.yml/badge.svg)](https://github.com/daohoangson/flutter_widget_from_html/actions/workflows/flutter.yml)
[![codecov](https://codecov.io/gh/daohoangson/flutter_widget_from_html/branch/master/graph/badge.svg)](https://codecov.io/gh/daohoangson/flutter_widget_from_html)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=daohoangson_flutter_widget_from_html&metric=coverage)](https://sonarcloud.io/summary/new_code?id=daohoangson_flutter_widget_from_html)
[![Pub](https://img.shields.io/pub/v/fwfh_just_audio.svg)](https://pub.dev/packages/fwfh_just_audio)

WidgetFactory extension to render AUDIO with the [just_audio](https://pub.dev/packages/just_audio) plugin.
Expand Down
2 changes: 1 addition & 1 deletion packages/fwfh_svg/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# SvgFactory

[![Flutter](https://github.com/daohoangson/flutter_widget_from_html/actions/workflows/flutter.yml/badge.svg)](https://github.com/daohoangson/flutter_widget_from_html/actions/workflows/flutter.yml)
[![codecov](https://codecov.io/gh/daohoangson/flutter_widget_from_html/branch/master/graph/badge.svg)](https://codecov.io/gh/daohoangson/flutter_widget_from_html)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=daohoangson_flutter_widget_from_html&metric=coverage)](https://sonarcloud.io/summary/new_code?id=daohoangson_flutter_widget_from_html)
[![Pub](https://img.shields.io/pub/v/fwfh_svg.svg)](https://pub.dev/packages/fwfh_svg)

WidgetFactory extension to render SVG with [flutter_svg](https://pub.dev/packages/flutter_svg) plugin.
Expand Down
2 changes: 1 addition & 1 deletion packages/fwfh_url_launcher/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# UrlLauncherFactory

[![Flutter](https://github.com/daohoangson/flutter_widget_from_html/actions/workflows/flutter.yml/badge.svg)](https://github.com/daohoangson/flutter_widget_from_html/actions/workflows/flutter.yml)
[![codecov](https://codecov.io/gh/daohoangson/flutter_widget_from_html/branch/master/graph/badge.svg)](https://codecov.io/gh/daohoangson/flutter_widget_from_html)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=daohoangson_flutter_widget_from_html&metric=coverage)](https://sonarcloud.io/summary/new_code?id=daohoangson_flutter_widget_from_html)
[![Pub](https://img.shields.io/pub/v/fwfh_url_launcher.svg)](https://pub.dev/packages/fwfh_url_launcher)

WidgetFactory extension to launch A tag via [url_launcher](https://pub.dev/packages/url_launcher) plugin.
Expand Down
2 changes: 1 addition & 1 deletion packages/fwfh_webview/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# WebViewFactory

[![Flutter](https://github.com/daohoangson/flutter_widget_from_html/actions/workflows/flutter.yml/badge.svg)](https://github.com/daohoangson/flutter_widget_from_html/actions/workflows/flutter.yml)
[![codecov](https://codecov.io/gh/daohoangson/flutter_widget_from_html/branch/master/graph/badge.svg)](https://codecov.io/gh/daohoangson/flutter_widget_from_html)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=daohoangson_flutter_widget_from_html&metric=coverage)](https://sonarcloud.io/summary/new_code?id=daohoangson_flutter_widget_from_html)
[![Pub](https://img.shields.io/pub/v/fwfh_webview.svg)](https://pub.dev/packages/fwfh_webview)

WidgetFactory extension to render IFRAME with the official WebView plugin.
Expand Down