Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

[webview_flutter] Added basic support to load html data on both platform #1137

Closed
wants to merge 2 commits into from
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@ public class FlutterWebView implements PlatformView, MethodCallHandler {
@SuppressWarnings("unchecked")
FlutterWebView(Context context, BinaryMessenger messenger, int id, Map<String, Object> params) {
webView = new WebView(context);
if (params.containsKey("initialUrl")) {
String url = (String) params.get("initialUrl");
String url = (String) params.get("initialUrl");
String htmlData = (String) params.get("htmlData");
if (params.containsKey("initialUrl") && url != null) {
webView.loadUrl(url);
} else if (params.containsKey("htmlData") && htmlData != null){
// We might have to add more parameters on dart side to ask baseURL
webView.loadData(htmlData, "text/html", "UTF-8");
}
applySettings((Map<String, Object>) params.get("settings"));
methodChannel = new MethodChannel(messenger, "plugins.flutter.io/webview_" + id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
C1E6CAF49F4A1271A5C38490 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146E5B7D54A1F480CCA2D653 /* libPods-Runner.a */; };
/* End PBXBuildFile section */

/* Begin PBXCopyFilesBuildPhase section */
Expand All @@ -38,6 +39,7 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
146E5B7D54A1F480CCA2D653 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; };
Expand All @@ -64,12 +66,28 @@
files = (
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
C1E6CAF49F4A1271A5C38490 /* libPods-Runner.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
563DEEBCB75A795504F004FF /* Frameworks */ = {
isa = PBXGroup;
children = (
146E5B7D54A1F480CCA2D653 /* libPods-Runner.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
63EC36BF727938D8B21D4E7D /* Pods */ = {
isa = PBXGroup;
children = (
);
name = Pods;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
Expand All @@ -90,7 +108,8 @@
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
CF3B75C9A7D2FA2A4C99F110 /* Frameworks */,
63EC36BF727938D8B21D4E7D /* Pods */,
563DEEBCB75A795504F004FF /* Frameworks */,
);
sourceTree = "<group>";
};
Expand Down Expand Up @@ -133,12 +152,14 @@
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
3E0E965F102EF561521AD1DB /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
92680763791C92D94C8D82BA /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
Expand Down Expand Up @@ -212,6 +233,50 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
};
3E0E965F102EF561521AD1DB /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
92680763791C92D94C8D82BA /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
);
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildSystemType</key>
<string>Original</string>
</dict>
</plist>
1 change: 1 addition & 0 deletions packages/webview_flutter/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class WebViewExample extends StatelessWidget {
),
body: WebView(
initialUrl: 'https://flutter.io',
htmlData: "<h1>Dispayed a custom html text here.</h1>",
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
Expand Down
8 changes: 8 additions & 0 deletions packages/webview_flutter/ios/Classes/FlutterWebView.m
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,11 @@ - (instancetype)initWithFrame:(CGRect)frame
NSDictionary<NSString*, id>* settings = args[@"settings"];
[self applySettings:settings];
NSString* initialUrl = args[@"initialUrl"];
NSString* htmlData = args[@"htmlData"];
if (initialUrl && ![initialUrl isKindOfClass:[NSNull class]]) {
[self loadUrl:initialUrl];
} else if(htmlData && ![htmlData isKindOfClass:[NSNull class]]){
[self loadHTMLString:htmlData];
}
}
return self;
Expand Down Expand Up @@ -189,4 +192,9 @@ - (bool)loadUrl:(NSString*)url {
return true;
}

- (void)loadHTMLString:(NSString*)htmlData {
// We might have to add more parameters on dart side to ask baseURL
[_webView loadHTMLString:htmlData baseURL: nil];
}

@end
9 changes: 8 additions & 1 deletion packages/webview_flutter/lib/webview_flutter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class WebView extends StatefulWidget {
Key key,
this.onWebViewCreated,
this.initialUrl,
this.htmlData,
this.javascriptMode = JavascriptMode.disabled,
this.gestureRecognizers,
}) : assert(javascriptMode != null),
Expand All @@ -53,6 +54,9 @@ class WebView extends StatefulWidget {
/// The initial URL to load.
final String initialUrl;

/// Html data that should be loaded once the web view is created.
final String htmlData;

/// Whether Javascript execution is enabled.
final JavascriptMode javascriptMode;

Expand Down Expand Up @@ -126,21 +130,24 @@ class _WebViewState extends State<WebView> {
}

class _CreationParams {
_CreationParams({this.initialUrl, this.settings});
_CreationParams({this.initialUrl, this.htmlData, this.settings});

static _CreationParams fromWidget(WebView widget) {
return _CreationParams(
initialUrl: widget.initialUrl,
htmlData: widget.htmlData,
settings: _WebSettings.fromWidget(widget),
);
}

final String initialUrl;
final String htmlData;
final _WebSettings settings;

Map<String, dynamic> toMap() {
return <String, dynamic>{
'initialUrl': initialUrl,
'htmlData': htmlData,
'settings': settings.toMap(),
};
}
Expand Down
14 changes: 14 additions & 0 deletions packages/webview_flutter/test/webview_flutter_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,20 @@ void main() {
expect(await controller.currentUrl(), 'https://youtube.com');
});

testWidgets('Load HTML Data', (WidgetTester tester) async {
WebViewController controller;
await tester.pumpWidget(
WebView(
htmlData: "<h1>Hello</h1>",
onWebViewCreated: (WebViewController webViewController) {
controller = webViewController;
},
),
);
//todo dont know what to expect here.
expect(await controller.currentUrl(), 'https://youtube.com');
});

testWidgets('Javascript mode', (WidgetTester tester) async {
await tester.pumpWidget(const WebView(
initialUrl: 'https://youtube.com',
Expand Down