Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[flutter_markdown] Added sizedImageBuilder to Markdown widget #6739

Open
wants to merge 40 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
22180cc
Added height and width to image builder
M97Chahboun May 15, 2024
c8b90a9
Updated CHANGELOG file
M97Chahboun May 15, 2024
025bf8f
format tests
M97Chahboun May 15, 2024
ce61fb5
Update pubspec.yaml
M97Chahboun May 18, 2024
a79a517
Merge branch 'main' into main
M97Chahboun May 18, 2024
d8192d1
Adds image builder height and width tests
M97Chahboun May 19, 2024
2ef0b8a
Added size to precacheImage tests
M97Chahboun May 19, 2024
af07d08
Merge branch 'main' into main
M97Chahboun May 27, 2024
efb8038
Removed unnecessary size for precacheImage test method
M97Chahboun Jun 5, 2024
a928995
Merge branch 'main' into main
M97Chahboun Sep 4, 2024
0357934
Revert custom image builder test changes
M97Chahboun Dec 4, 2024
6356ebf
Merge branch 'main' of https://github.com/flutter/packages
M97Chahboun Dec 4, 2024
a6ce01f
Added custom image builder test width and height
M97Chahboun Dec 4, 2024
e2729ce
Added golden test for image size with builder
M97Chahboun Dec 4, 2024
e56c5b4
Added custom image builder test width and height to image group test
M97Chahboun Dec 4, 2024
ade6d95
Make image configurations extensible by class parameter
M97Chahboun Dec 5, 2024
c4ddc92
Updated CHANGELOG
M97Chahboun Dec 5, 2024
2a341cb
Mark imageBuilder as Deprecated
M97Chahboun Dec 5, 2024
d20def3
Merge branch 'main' into main
M97Chahboun Dec 8, 2024
15193de
Updated MarkdownBody widget
M97Chahboun Dec 22, 2024
0ced948
Merge branch 'main' of https://github.com/flutter/packages
M97Chahboun Dec 22, 2024
b54c7bf
Merge branch 'main' into main
M97Chahboun Jan 5, 2025
b8efb0e
Merge branch 'main' of https://github.com/flutter/packages
M97Chahboun Feb 10, 2025
8a6497e
typo fix
M97Chahboun Feb 10, 2025
9f558c7
format builder.dart
M97Chahboun Feb 10, 2025
3b80f5b
format tests
M97Chahboun Feb 10, 2025
64a57a2
Merge branch 'main' into main
M97Chahboun Feb 10, 2025
df12f5a
Merge branch 'main' into main
M97Chahboun Feb 10, 2025
f6c518c
Merge branch 'flutter:main' into main
M97Chahboun Feb 11, 2025
0eea20f
Merge branch 'main' into main
M97Chahboun Feb 11, 2025
ac01be0
Merge branch 'main' into main
M97Chahboun Feb 12, 2025
672b44d
Merge branch 'main' into main
M97Chahboun Feb 13, 2025
86717f9
Solved fail test
M97Chahboun Feb 13, 2025
ef8b046
solve package version
M97Chahboun Feb 15, 2025
24b8297
updated imageBuilder & sizedImageBuilder docs
M97Chahboun Feb 18, 2025
e42ac4b
Improved _buildImage if statement
M97Chahboun Feb 18, 2025
ed8db58
Updated MarkdownSizedImageBuilder doc
M97Chahboun Feb 18, 2025
af00261
Adds assert that both aren't passed.
M97Chahboun Feb 18, 2025
99d08a9
format codes
M97Chahboun Feb 18, 2025
4f02de0
removed license comment
M97Chahboun Feb 19, 2025
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
6 changes: 6 additions & 0 deletions packages/flutter_markdown/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## NEXT

## 0.8.0

* Introduce `MarkdownImageConfig` for `sizedImageBuilder` builder.

## 0.7.5

* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4.
Expand Down
36 changes: 34 additions & 2 deletions packages/flutter_markdown/lib/src/builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,33 @@ class _TableElement {
final List<TableRow> rows = <TableRow>[];
}

/// Holds configuration data for an image in a Markdown document.
class MarkdownImageConfig {

/// Creates a new [MarkdownImageConfig] instance.
MarkdownImageConfig({
required this.uri,
this.title,
this.alt,
this.width,
this.height,
});
/// The URI of the image.
final Uri uri;

/// The title of the image, displayed on hover.
final String? title;

/// The alternative text for the image, displayed if the image cannot be loaded.
final String? alt;

/// The desired width of the image.
final double? width;

/// The desired height of the image.
final double? height;
}

/// A collection of widgets that should be placed adjacent to (inline with)
/// other inline elements in the same parent block.
///
Expand Down Expand Up @@ -106,6 +133,7 @@ class MarkdownBuilder implements md.NodeVisitor {
required this.styleSheet,
required this.imageDirectory,
required this.imageBuilder,
required this.sizedImageBuilder,
required this.checkboxBuilder,
required this.bulletBuilder,
required this.builders,
Expand Down Expand Up @@ -134,6 +162,9 @@ class MarkdownBuilder implements md.NodeVisitor {
/// Call when build an image widget.
final MarkdownImageBuilder? imageBuilder;

/// Call when build an image widget.
final MarkdownSizedImageBuilder? sizedImageBuilder;

/// Call when build a checkbox widget.
final MarkdownCheckboxBuilder? checkboxBuilder;

Expand Down Expand Up @@ -617,8 +648,9 @@ class MarkdownBuilder implements md.NodeVisitor {
}

Widget child;
if (imageBuilder != null) {
child = imageBuilder!(uri, title, alt);
if (imageBuilder != null || sizedImageBuilder != null) {
final MarkdownImageConfig config = MarkdownImageConfig(uri: uri, alt: alt, title: title, height: height, width: width);
child = sizedImageBuilder != null ? sizedImageBuilder!(config) : imageBuilder!(uri, alt, title);
} else {
child = kDefaultImageBuilder(uri, imageDirectory, width, height);
}
Expand Down
19 changes: 16 additions & 3 deletions packages/flutter_markdown/lib/src/widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ typedef MarkdownOnSelectionChangedCallback = void Function(
typedef MarkdownTapLinkCallback = void Function(
String text, String? href, String title);

/// Signature for custom image widget.
///
/// Used by [MarkdownWidget.sizedImageBuilder]
typedef MarkdownSizedImageBuilder = Widget Function(MarkdownImageConfig config);

/// Signature for custom image widget.
///
/// Used by [MarkdownWidget.imageBuilder]
Expand Down Expand Up @@ -220,7 +225,8 @@ abstract class MarkdownWidget extends StatefulWidget {
this.blockSyntaxes,
this.inlineSyntaxes,
this.extensionSet,
this.imageBuilder,
@Deprecated('Use sizedImageBuilder instead') this.imageBuilder,
this.sizedImageBuilder,
this.checkboxBuilder,
this.bulletBuilder,
this.builders = const <String, MarkdownElementBuilder>{},
Expand Down Expand Up @@ -278,8 +284,12 @@ abstract class MarkdownWidget extends StatefulWidget {
final md.ExtensionSet? extensionSet;

/// Call when build an image widget.
@Deprecated('Use sizedImageBuilder instead')
final MarkdownImageBuilder? imageBuilder;

/// Call when build an image widget.
final MarkdownSizedImageBuilder? sizedImageBuilder;

/// Call when build a checkbox widget.
final MarkdownCheckboxBuilder? checkboxBuilder;

Expand Down Expand Up @@ -391,6 +401,7 @@ class _MarkdownWidgetState extends State<MarkdownWidget>
styleSheet: styleSheet,
imageDirectory: widget.imageDirectory,
imageBuilder: widget.imageBuilder,
sizedImageBuilder: widget.sizedImageBuilder,
checkboxBuilder: widget.checkboxBuilder,
bulletBuilder: widget.bulletBuilder,
builders: widget.builders,
Expand Down Expand Up @@ -467,7 +478,8 @@ class MarkdownBody extends MarkdownWidget {
super.blockSyntaxes,
super.inlineSyntaxes,
super.extensionSet,
super.imageBuilder,
@Deprecated('Use sizedImageBuilder instead.') super.imageBuilder,
super.sizedImageBuilder,
super.checkboxBuilder,
super.bulletBuilder,
super.builders,
Expand Down Expand Up @@ -522,7 +534,8 @@ class Markdown extends MarkdownWidget {
super.blockSyntaxes,
super.inlineSyntaxes,
super.extensionSet,
super.imageBuilder,
@Deprecated('Use sizedImageBuilder instead.') super.imageBuilder,
super.sizedImageBuilder,
super.checkboxBuilder,
super.bulletBuilder,
super.builders,
Expand Down
2 changes: 1 addition & 1 deletion packages/flutter_markdown/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: A Markdown renderer for Flutter. Create rich text output,
formatted with simple Markdown tags.
repository: https://github.com/flutter/packages/tree/main/packages/flutter_markdown
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_markdown%22
version: 0.7.5
version: 0.8.0

environment:
sdk: ^3.4.0
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
53 changes: 53 additions & 0 deletions packages/flutter_markdown/test/image_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -459,5 +459,58 @@ void defineTests() {
},
skip: kIsWeb, // Goldens are platform-specific.
);

testWidgets(
'custom image builder test width and height',
(WidgetTester tester) async {
const double height = 200;
const double width = 100;
const String data = '![alt](https://img.png#${width}x$height)';
Widget builder(MarkdownImageConfig config) =>
Image.asset('assets/logo.png', width: config.width, height: config.height);

await tester.pumpWidget(
boilerplate(
MaterialApp(
home: DefaultAssetBundle(
bundle: TestAssetBundle(),
child: Center(
child: Container(
color: Colors.white,
width: 500,
child: Markdown(
data: data,
sizedImageBuilder: builder,
),
),
),
),
),
),
);

final Iterable<Widget> widgets = tester.allWidgets;
final Image image =
widgets.firstWhere((Widget widget) => widget is Image) as Image;

expect(image.image.runtimeType, AssetImage);
expect((image.image as AssetImage).assetName, 'assets/logo.png');
expect(image.width, width);
expect(image.height, height);

await tester.runAsync(() async {
final Element element = tester.element(find.byType(Markdown));
await precacheImage(image.image, element);
});

await tester.pumpAndSettle();

await expectLater(
find.byType(Container),
matchesGoldenFile(
'assets/images/golden/image_test/custom_image_builder_test.png'));
},
skip: kIsWeb,
);
});
}
Loading