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,'));
});
});