From d8c0fee90425daa0ab933de6ba4d9efea7712174 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 26 Aug 2025 14:49:10 +0000 Subject: [PATCH 1/5] Initial plan From 181123ce6f88bd0a1dbbc13f71fc5c8b588d6c68 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 26 Aug 2025 14:57:50 +0000 Subject: [PATCH 2/5] Add data-src attribute support for IFRAME elements Co-authored-by: daohoangson <239336+daohoangson@users.noreply.github.com> --- packages/fwfh_webview/lib/src/internal.dart | 1 + .../lib/src/web_view_factory.dart | 2 +- .../test/web_view_factory_test.dart | 61 +++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/packages/fwfh_webview/lib/src/internal.dart b/packages/fwfh_webview/lib/src/internal.dart index 0c8fada47..e48c81802 100644 --- a/packages/fwfh_webview/lib/src/internal.dart +++ b/packages/fwfh_webview/lib/src/internal.dart @@ -1,4 +1,5 @@ const kTagIframe = 'iframe'; +const kAttributeIframeDataSrc = 'data-src'; const kAttributeIframeHeight = 'height'; const kAttributeIframeSandbox = 'sandbox'; const kAttributeIframeSandboxAllowScripts = 'allow-scripts'; diff --git a/packages/fwfh_webview/lib/src/web_view_factory.dart b/packages/fwfh_webview/lib/src/web_view_factory.dart index 3302b54fa..0ba362fed 100644 --- a/packages/fwfh_webview/lib/src/web_view_factory.dart +++ b/packages/fwfh_webview/lib/src/web_view_factory.dart @@ -132,7 +132,7 @@ mixin WebViewFactory on WidgetFactory { } final a = meta.element.attributes; - final src = urlFull(a[kAttributeIframeSrc] ?? ''); + final src = urlFull(a[kAttributeIframeDataSrc] ?? a[kAttributeIframeSrc] ?? ''); if (src == null) { return widgets; } diff --git a/packages/fwfh_webview/test/web_view_factory_test.dart b/packages/fwfh_webview/test/web_view_factory_test.dart index 26fba6773..c62315cfa 100644 --- a/packages/fwfh_webview/test/web_view_factory_test.dart +++ b/packages/fwfh_webview/test/web_view_factory_test.dart @@ -318,6 +318,61 @@ void main() { }); }); + group('data-src attribute', () { + testWidgets('renders with data-src', (tester) async { + const html = ''; + final explained = await explain(tester, html); + expect( + explained, + equals( + '[CssSizing:$sizingConstraints,child=' + '[WebView:url=$src,aspectRatio=$defaultAspectRatio,js=true,gestureRecognizers={}]' + ']', + ), + ); + }); + + testWidgets('data-src takes priority over src', (tester) async { + const dataSrcUrl = 'http://data-src.com'; + const html = ''; + final explained = await explain(tester, html); + expect( + explained, + equals( + '[CssSizing:$sizingConstraints,child=' + '[WebView:url=$dataSrcUrl,aspectRatio=$defaultAspectRatio,js=true,gestureRecognizers={}]' + ']', + ), + ); + }); + + testWidgets('falls back to src when data-src is empty', (tester) async { + const html = ''; + final explained = await explain(tester, html); + expect( + explained, + equals( + '[CssSizing:$sizingConstraints,child=' + '[WebView:url=$src,aspectRatio=$defaultAspectRatio,js=true,gestureRecognizers={}]' + ']', + ), + ); + }); + + testWidgets('falls back to src when data-src is missing', (tester) async { + const html = ''; + final explained = await explain(tester, html); + expect( + explained, + equals( + '[CssSizing:$sizingConstraints,child=' + '[WebView:url=$src,aspectRatio=$defaultAspectRatio,js=true,gestureRecognizers={}]' + ']', + ), + ); + }); + }); + group('errors', () { testWidgets('no src', (tester) async { const html = ''; @@ -330,6 +385,12 @@ void main() { final explained = await explain(tester, html); expect(explained, equals('[widget0]')); }); + + testWidgets('bad data-src (cannot build full url)', (tester) async { + const html = ''; + final explained = await explain(tester, html); + expect(explained, equals('[widget0]')); + }); }); } From 37fd2c7b54515d55ce2ce049f76d3dad7e38859b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 26 Aug 2025 15:04:26 +0000 Subject: [PATCH 3/5] Fix data-src attribute fallback logic for empty values Co-authored-by: daohoangson <239336+daohoangson@users.noreply.github.com> --- packages/fwfh_webview/lib/src/web_view_factory.dart | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/fwfh_webview/lib/src/web_view_factory.dart b/packages/fwfh_webview/lib/src/web_view_factory.dart index 0ba362fed..e55663dcb 100644 --- a/packages/fwfh_webview/lib/src/web_view_factory.dart +++ b/packages/fwfh_webview/lib/src/web_view_factory.dart @@ -132,7 +132,11 @@ mixin WebViewFactory on WidgetFactory { } final a = meta.element.attributes; - final src = urlFull(a[kAttributeIframeDataSrc] ?? a[kAttributeIframeSrc] ?? ''); + final dataSrc = a[kAttributeIframeDataSrc]; + final srcAttr = a[kAttributeIframeSrc]; + final src = urlFull( + (dataSrc?.isNotEmpty == true) ? dataSrc! : (srcAttr ?? '') + ); if (src == null) { return widgets; } From a9315e83ec356347a161256ee76f12f6a79e5ca3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 26 Aug 2025 17:35:02 +0000 Subject: [PATCH 4/5] Fix iframe src/data-src priority: src now takes priority over data-src Co-authored-by: daohoangson <239336+daohoangson@users.noreply.github.com> --- packages/fwfh_webview/lib/src/web_view_factory.dart | 2 +- packages/fwfh_webview/test/web_view_factory_test.dart | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/fwfh_webview/lib/src/web_view_factory.dart b/packages/fwfh_webview/lib/src/web_view_factory.dart index e55663dcb..f66691752 100644 --- a/packages/fwfh_webview/lib/src/web_view_factory.dart +++ b/packages/fwfh_webview/lib/src/web_view_factory.dart @@ -135,7 +135,7 @@ mixin WebViewFactory on WidgetFactory { final dataSrc = a[kAttributeIframeDataSrc]; final srcAttr = a[kAttributeIframeSrc]; final src = urlFull( - (dataSrc?.isNotEmpty == true) ? dataSrc! : (srcAttr ?? '') + (srcAttr?.isNotEmpty == true) ? srcAttr! : (dataSrc ?? '') ); if (src == null) { return widgets; diff --git a/packages/fwfh_webview/test/web_view_factory_test.dart b/packages/fwfh_webview/test/web_view_factory_test.dart index c62315cfa..ca739f196 100644 --- a/packages/fwfh_webview/test/web_view_factory_test.dart +++ b/packages/fwfh_webview/test/web_view_factory_test.dart @@ -332,7 +332,7 @@ void main() { ); }); - testWidgets('data-src takes priority over src', (tester) async { + testWidgets('src takes priority over data-src', (tester) async { const dataSrcUrl = 'http://data-src.com'; const html = ''; final explained = await explain(tester, html); @@ -340,14 +340,14 @@ void main() { explained, equals( '[CssSizing:$sizingConstraints,child=' - '[WebView:url=$dataSrcUrl,aspectRatio=$defaultAspectRatio,js=true,gestureRecognizers={}]' + '[WebView:url=$src,aspectRatio=$defaultAspectRatio,js=true,gestureRecognizers={}]' ']', ), ); }); - testWidgets('falls back to src when data-src is empty', (tester) async { - const html = ''; + testWidgets('falls back to data-src when src is empty', (tester) async { + const html = ''; final explained = await explain(tester, html); expect( explained, @@ -359,7 +359,7 @@ void main() { ); }); - testWidgets('falls back to src when data-src is missing', (tester) async { + testWidgets('uses src when data-src is missing', (tester) async { const html = ''; final explained = await explain(tester, html); expect( From 2f5dbf04f76ad9d81113f8ed83b8a6ecfc367196 Mon Sep 17 00:00:00 2001 From: Cirrus CI Date: Sat, 30 Aug 2025 16:05:12 +0000 Subject: [PATCH 5/5] Fix tests --- .../test/web_view_factory_test.dart | 39 +++---------------- 1 file changed, 5 insertions(+), 34 deletions(-) diff --git a/packages/fwfh_webview/test/web_view_factory_test.dart b/packages/fwfh_webview/test/web_view_factory_test.dart index ca739f196..4ed5d5e77 100644 --- a/packages/fwfh_webview/test/web_view_factory_test.dart +++ b/packages/fwfh_webview/test/web_view_factory_test.dart @@ -322,54 +322,25 @@ void main() { testWidgets('renders with data-src', (tester) async { const html = ''; final explained = await explain(tester, html); - expect( - explained, - equals( - '[CssSizing:$sizingConstraints,child=' - '[WebView:url=$src,aspectRatio=$defaultAspectRatio,js=true,gestureRecognizers={}]' - ']', - ), - ); + expect(explained, contains('url=$src,')); }); testWidgets('src takes priority over data-src', (tester) async { - const dataSrcUrl = 'http://data-src.com'; - const html = ''; + const html = ''; final explained = await explain(tester, html); - expect( - explained, - equals( - '[CssSizing:$sizingConstraints,child=' - '[WebView:url=$src,aspectRatio=$defaultAspectRatio,js=true,gestureRecognizers={}]' - ']', - ), - ); + expect(explained, contains('url=$src/2,')); }); testWidgets('falls back to data-src when src is empty', (tester) async { const html = ''; final explained = await explain(tester, html); - expect( - explained, - equals( - '[CssSizing:$sizingConstraints,child=' - '[WebView:url=$src,aspectRatio=$defaultAspectRatio,js=true,gestureRecognizers={}]' - ']', - ), - ); + expect(explained, contains('url=$src,')); }); testWidgets('uses src when data-src is missing', (tester) async { const html = ''; final explained = await explain(tester, html); - expect( - explained, - equals( - '[CssSizing:$sizingConstraints,child=' - '[WebView:url=$src,aspectRatio=$defaultAspectRatio,js=true,gestureRecognizers={}]' - ']', - ), - ); + expect(explained, contains('url=$src,')); }); });