feat: offer a non-Mews web page as a simplified view or in the browser

This commit is contained in:
randogoth 2026-10-12 11:13:34 +03:00
parent cea66fbb42
commit 00e42c925c
24 changed files with 863 additions and 152 deletions

View file

@ -82,6 +82,107 @@ void main() {
expect(opened, 'https://example.com/next.html');
});
testWidgets('two forms with one action stay apart', (tester) async {
// A web page often carries its search box twice, once per header, both
// submitting to the same address.
const search = FormBlock(
action: 'https://example.com/w/index.php',
method: 'get',
fields: [MewsTextField(name: 'search', password: false, label: 'Search')],
submitLabel: 'Go',
);
final page = MewsPage(
url: 'https://example.com/article',
lang: 'en',
direction: TextDirection.ltr,
variant: MewsVariant.plain,
specVersion: '0.1',
entries: const [],
body: const [search, ParagraphBlock([MewsText('Between them.')]), search],
);
await tester.pumpWidget(
MaterialApp(
// A form's fields are Material widgets and need a sheet to sit on.
home: Scaffold(
body: StringsScope(
strings: await _strings(),
child: MewsPageView(
page: page,
palette: paletteFor(
pageVariant: MewsVariant.plain, readerVariant: 'site', dark: false),
fontFamily: 'Atkinson Hyperlegible',
fontScale: 1.0,
visitedUrls: const {},
onLinkTap: (_) {},
onFormSubmit: (_, _) {},
),
),
),
),
);
await tester.pumpAndSettle();
expect(tester.takeException(), isNull);
expect(find.byType(TextField), findsNWidgets(2));
});
testWidgets('a table with ragged rows renders without holes', (tester) async {
// A web page's rows rarely match: here a header row of two, a row of
// three, and one spanning cell. Flutter's Table would assert on these.
final page = MewsPage(
url: 'https://example.com/table.html',
lang: 'en',
direction: TextDirection.ltr,
variant: MewsVariant.plain,
specVersion: '0.1',
entries: const [],
body: const [
TableBlock(
rows: [
MewsTableRow([
MewsTableCell(header: true, inline: [MewsText('Model')]),
MewsTableCell(header: true, inline: [MewsText('Price')]),
]),
MewsTableRow([
MewsTableCell(header: false, inline: [MewsText('3310')]),
MewsTableCell(header: false, inline: [MewsText('Ten')]),
MewsTableCell(header: false, inline: [MewsText('Spare')]),
]),
MewsTableRow([
MewsTableCell(header: false, inline: [MewsText('Only one')]),
]),
MewsTableRow([]),
],
),
],
);
await tester.pumpWidget(
MaterialApp(
home: StringsScope(
strings: await _strings(),
child: MewsPageView(
page: page,
palette: paletteFor(
pageVariant: MewsVariant.plain, readerVariant: 'site', dark: false),
fontFamily: 'Atkinson Hyperlegible',
fontScale: 1.0,
visitedUrls: const {},
onLinkTap: (_) {},
onFormSubmit: (_, _) {},
),
),
),
);
await tester.pumpAndSettle();
expect(tester.takeException(), isNull);
expect(find.text('Model'), findsOneWidget);
expect(find.text('Spare'), findsOneWidget);
expect(find.text('Only one'), findsOneWidget);
});
testWidgets('Tab walks the links on a page', (tester) async {
final page = MewsPage(
url: 'https://example.com/index.html',