added support for iOS inline native WebView integrated in the flutter widget tree (#18, #45), fix #54 #38 #26 #32 #33 #29 #15
This commit is contained in:
parent
2b600fbb6c
commit
1dfa6323c6
|
@ -16,7 +16,19 @@
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="9b41f7a2-a71e-4923-91fb-249d7815b3e7" name="Default" comment="">
|
<list default="true" id="9b41f7a2-a71e-4923-91fb-249d7815b3e7" name="Default" comment="">
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/example/lib/main.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/lib/main.dart" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/CHANGELOG.md" beforeDir="false" afterPath="$PROJECT_DIR$/CHANGELOG.md" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/android/build.gradle" beforeDir="false" afterPath="$PROJECT_DIR$/android/build.gradle" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/android/gradle/wrapper/gradle-wrapper.properties" beforeDir="false" afterPath="$PROJECT_DIR$/android/gradle/wrapper/gradle-wrapper.properties" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebViewClient.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebViewClient.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/example/android/gradle/wrapper/gradle-wrapper.properties" beforeDir="false" afterPath="$PROJECT_DIR$/example/android/gradle/wrapper/gradle-wrapper.properties" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/example/ios/Runner.xcodeproj/project.pbxproj" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/Runner.xcodeproj/project.pbxproj" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/example/lib/webview_example.screen.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/lib/webview_example.screen.dart" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/flutter_inappbrowser.iml" beforeDir="false" afterPath="$PROJECT_DIR$/flutter_inappbrowser.iml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ios/Classes/InAppBrowserWebViewController.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/InAppBrowserWebViewController.swift" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ios/Classes/InAppWebView.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/InAppWebView.swift" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ios/Classes/SwiftFlutterPlugin.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/SwiftFlutterPlugin.swift" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/pubspec.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/pubspec.yaml" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<ignored path="$PROJECT_DIR$/.dart_tool/" />
|
<ignored path="$PROJECT_DIR$/.dart_tool/" />
|
||||||
<ignored path="$PROJECT_DIR$/.idea/" />
|
<ignored path="$PROJECT_DIR$/.idea/" />
|
||||||
|
@ -36,8 +48,8 @@
|
||||||
<file leaf-file-name="flutter_inappbrowser.dart" pinned="false" current-in-tab="false">
|
<file leaf-file-name="flutter_inappbrowser.dart" pinned="false" current-in-tab="false">
|
||||||
<entry file="file://$PROJECT_DIR$/lib/flutter_inappbrowser.dart">
|
<entry file="file://$PROJECT_DIR$/lib/flutter_inappbrowser.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="4380">
|
<state relative-caret-position="415">
|
||||||
<caret line="323" column="41" selection-start-line="323" selection-start-column="41" selection-end-line="323" selection-end-column="41" />
|
<caret line="698" column="22" selection-start-line="698" selection-start-column="13" selection-end-line="698" selection-end-column="22" />
|
||||||
<folding>
|
<folding>
|
||||||
<element signature="e#814#831#0" expanded="true" />
|
<element signature="e#814#831#0" expanded="true" />
|
||||||
</folding>
|
</folding>
|
||||||
|
@ -45,13 +57,31 @@
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
</file>
|
</file>
|
||||||
<file leaf-file-name="main.dart" pinned="false" current-in-tab="true">
|
<file leaf-file-name="CHANGELOG.md" pinned="false" current-in-tab="false">
|
||||||
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
|
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="405">
|
<state relative-caret-position="195">
|
||||||
<caret line="27" column="18" lean-forward="true" selection-start-line="27" selection-start-column="18" selection-end-line="27" selection-end-column="18" />
|
<caret line="13" column="21" selection-start-line="13" selection-start-column="21" selection-end-line="13" selection-end-column="21" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file leaf-file-name="pubspec.yaml" pinned="false" current-in-tab="true">
|
||||||
|
<entry file="file://$PROJECT_DIR$/pubspec.yaml">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="195">
|
||||||
|
<caret line="13" column="14" lean-forward="true" selection-start-line="13" selection-start-column="14" selection-end-line="13" selection-end-column="14" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file leaf-file-name="README.md" pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/README.md">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="589">
|
||||||
|
<caret line="72" column="7" lean-forward="true" selection-start-line="72" selection-start-column="7" selection-end-line="72" selection-end-column="7" />
|
||||||
<folding>
|
<folding>
|
||||||
<element signature="e#0#20#0" expanded="true" />
|
<element signature="e#0#39#0" expanded="true" />
|
||||||
</folding>
|
</folding>
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
|
@ -68,20 +98,6 @@
|
||||||
</component>
|
</component>
|
||||||
<component name="FindInProjectRecents">
|
<component name="FindInProjectRecents">
|
||||||
<findStrings>
|
<findStrings>
|
||||||
<find>assert(</find>
|
|
||||||
<find>sNotEmpty()</find>
|
|
||||||
<find>loadData</find>
|
|
||||||
<find>_valide</find>
|
|
||||||
<find>initialized</find>
|
|
||||||
<find>HashMap</find>
|
|
||||||
<find>headers</find>
|
|
||||||
<find>.cast</find>
|
|
||||||
<find>WebView</find>
|
|
||||||
<find>print</find>
|
|
||||||
<find>throw</find>
|
|
||||||
<find>InAppWeb</find>
|
|
||||||
<find>Boolean</find>
|
|
||||||
<find>[WebHistory.list]</find>
|
|
||||||
<find>open</find>
|
<find>open</find>
|
||||||
<find>Cannot laod</find>
|
<find>Cannot laod</find>
|
||||||
<find>_throwIsNotOpened</find>
|
<find>_throwIsNotOpened</find>
|
||||||
|
@ -98,6 +114,20 @@
|
||||||
<find>initialData</find>
|
<find>initialData</find>
|
||||||
<find>openData</find>
|
<find>openData</find>
|
||||||
<find>optionsType</find>
|
<find>optionsType</find>
|
||||||
|
<find>InAppWebView</find>
|
||||||
|
<find>fromInAppBrowser</find>
|
||||||
|
<find>InAppWebViewController</find>
|
||||||
|
<find>_handleMethod</find>
|
||||||
|
<find>InAppBrowser</find>
|
||||||
|
<find>handlerTest</find>
|
||||||
|
<find>onLoadStart</find>
|
||||||
|
<find>distributionUrl</find>
|
||||||
|
<find>args.putIfAbsent('isData', () => false);</find>
|
||||||
|
<find>VERSIONING_SYSTEM</find>
|
||||||
|
<find>config.build_settings['SWIFT_VERSION']</find>
|
||||||
|
<find>BUILD TARGET</find>
|
||||||
|
<find>InAppWebView {</find>
|
||||||
|
<find>AndroidView</find>
|
||||||
</findStrings>
|
</findStrings>
|
||||||
<replaceStrings>
|
<replaceStrings>
|
||||||
<replace>activity.getPreferences(0)</replace>
|
<replace>activity.getPreferences(0)</replace>
|
||||||
|
@ -132,26 +162,29 @@
|
||||||
<option value="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowser.java" />
|
<option value="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowser.java" />
|
||||||
<option value="$PROJECT_DIR$/ios/flutter_inappbrowser.podspec" />
|
<option value="$PROJECT_DIR$/ios/flutter_inappbrowser.podspec" />
|
||||||
<option value="$PROJECT_DIR$/example/ios/Podfile" />
|
<option value="$PROJECT_DIR$/example/ios/Podfile" />
|
||||||
<option value="$PROJECT_DIR$/android/build.gradle" />
|
|
||||||
<option value="$PROJECT_DIR$/example/html/css/style.css" />
|
<option value="$PROJECT_DIR$/example/html/css/style.css" />
|
||||||
<option value="$PROJECT_DIR$/example/html/index.html" />
|
<option value="$PROJECT_DIR$/example/html/index.html" />
|
||||||
<option value="$PROJECT_DIR$/example/assets/css/style.css" />
|
<option value="$PROJECT_DIR$/example/assets/css/style.css" />
|
||||||
<option value="$PROJECT_DIR$/example/assets/index.html" />
|
<option value="$PROJECT_DIR$/example/assets/index.html" />
|
||||||
<option value="$PROJECT_DIR$/example/ios/Flutter/Generated.xcconfig" />
|
<option value="$PROJECT_DIR$/example/ios/Flutter/Generated.xcconfig" />
|
||||||
<option value="$PROJECT_DIR$/example/pubspec.yaml" />
|
<option value="$PROJECT_DIR$/example/pubspec.yaml" />
|
||||||
|
<option value="$PROJECT_DIR$/example/ios/Runner/Info.plist" />
|
||||||
|
<option value="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" />
|
||||||
|
<option value="$PROJECT_DIR$/example/lib/webview_example.screen.dart" />
|
||||||
|
<option value="$PROJECT_DIR$/example/lib/test.dart" />
|
||||||
|
<option value="$PROJECT_DIR$/example/lib/main.dart" />
|
||||||
|
<option value="$PROJECT_DIR$/android/build.gradle" />
|
||||||
|
<option value="$PROJECT_DIR$/android/gradle/wrapper/gradle-wrapper.properties" />
|
||||||
|
<option value="$PROJECT_DIR$/CHANGELOG.md" />
|
||||||
<option value="$PROJECT_DIR$/README.md" />
|
<option value="$PROJECT_DIR$/README.md" />
|
||||||
<option value="$PROJECT_DIR$/pubspec.yaml" />
|
<option value="$PROJECT_DIR$/pubspec.yaml" />
|
||||||
<option value="$PROJECT_DIR$/CHANGELOG.md" />
|
|
||||||
<option value="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" />
|
|
||||||
<option value="$PROJECT_DIR$/example/ios/Runner/Info.plist" />
|
|
||||||
<option value="$PROJECT_DIR$/example/lib/main.dart" />
|
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectFrameBounds" extendedState="6">
|
<component name="ProjectFrameBounds">
|
||||||
<option name="y" value="23" />
|
<option name="y" value="23" />
|
||||||
<option name="width" value="1641" />
|
<option name="width" value="1920" />
|
||||||
<option name="height" value="1027" />
|
<option name="height" value="1057" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
|
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
|
||||||
<component name="ProjectView">
|
<component name="ProjectView">
|
||||||
|
@ -159,7 +192,35 @@
|
||||||
<foldersAlwaysOnTop value="true" />
|
<foldersAlwaysOnTop value="true" />
|
||||||
</navigator>
|
</navigator>
|
||||||
<panes>
|
<panes>
|
||||||
<pane id="AndroidView" />
|
<pane id="AndroidView">
|
||||||
|
<subPane>
|
||||||
|
<expand>
|
||||||
|
<path>
|
||||||
|
<item name="flutter_inappbrowser" type="1abcf292:AndroidViewProjectNode" />
|
||||||
|
<item name="flutter_inappbrowser_android" type="e9137016:NonAndroidModuleNode" />
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<item name="flutter_inappbrowser" type="1abcf292:AndroidViewProjectNode" />
|
||||||
|
<item name="flutter_inappbrowser_android" type="e9137016:NonAndroidModuleNode" />
|
||||||
|
<item name="java" type="f7eae187:NonAndroidSourceTypeNode" />
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<item name="flutter_inappbrowser" type="1abcf292:AndroidViewProjectNode" />
|
||||||
|
<item name="flutter_inappbrowser_android" type="e9137016:NonAndroidModuleNode" />
|
||||||
|
<item name="java" type="f7eae187:NonAndroidSourceTypeNode" />
|
||||||
|
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<item name="flutter_inappbrowser" type="1abcf292:AndroidViewProjectNode" />
|
||||||
|
<item name="flutter_inappbrowser_android" type="e9137016:NonAndroidModuleNode" />
|
||||||
|
<item name="java" type="f7eae187:NonAndroidSourceTypeNode" />
|
||||||
|
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||||
|
<item name="InAppWebView" type="462c0819:PsiDirectoryNode" />
|
||||||
|
</path>
|
||||||
|
</expand>
|
||||||
|
<select />
|
||||||
|
</subPane>
|
||||||
|
</pane>
|
||||||
<pane id="Scope">
|
<pane id="Scope">
|
||||||
<subPane subId="Project Files">
|
<subPane subId="Project Files">
|
||||||
<expand>
|
<expand>
|
||||||
|
@ -178,29 +239,6 @@
|
||||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||||
</path>
|
</path>
|
||||||
<path>
|
|
||||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
|
||||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
|
||||||
<item name="example" type="462c0819:PsiDirectoryNode" />
|
|
||||||
</path>
|
|
||||||
<path>
|
|
||||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
|
||||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
|
||||||
<item name="example" type="462c0819:PsiDirectoryNode" />
|
|
||||||
<item name="ios" type="462c0819:PsiDirectoryNode" />
|
|
||||||
</path>
|
|
||||||
<path>
|
|
||||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
|
||||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
|
||||||
<item name="example" type="462c0819:PsiDirectoryNode" />
|
|
||||||
<item name="ios" type="462c0819:PsiDirectoryNode" />
|
|
||||||
<item name="Runner" type="462c0819:PsiDirectoryNode" />
|
|
||||||
</path>
|
|
||||||
<path>
|
|
||||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
|
||||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
|
||||||
<item name="ios" type="462c0819:PsiDirectoryNode" />
|
|
||||||
</path>
|
|
||||||
<path>
|
<path>
|
||||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||||
|
@ -368,33 +406,33 @@
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
<component name="ToolWindowManager">
|
<component name="ToolWindowManager">
|
||||||
<frame x="0" y="23" width="1680" height="1027" extended-state="6" />
|
<frame x="0" y="23" width="1920" height="1057" extended-state="0" />
|
||||||
<editor active="true" />
|
<editor active="true" />
|
||||||
<layout>
|
<layout>
|
||||||
<window_info anchor="bottom" id="Android Profiler" order="7" show_stripe_button="false" />
|
<window_info anchor="bottom" id="Android Profiler" order="7" show_stripe_button="false" />
|
||||||
<window_info anchor="bottom" id="TODO" order="6" />
|
<window_info anchor="bottom" id="TODO" order="6" />
|
||||||
|
<window_info anchor="bottom" id="Messages" order="12" weight="0.23585913" />
|
||||||
<window_info anchor="right" id="Palette	" order="9" />
|
<window_info anchor="right" id="Palette	" order="9" />
|
||||||
<window_info id="Image Layers" order="7" />
|
<window_info id="Image Layers" order="7" />
|
||||||
<window_info id="Build Variants" order="3" side_tool="true" />
|
<window_info id="Build Variants" order="3" side_tool="true" />
|
||||||
<window_info anchor="right" id="Capture Analysis" order="4" />
|
<window_info anchor="right" id="Capture Analysis" order="4" />
|
||||||
<window_info anchor="bottom" id="Event Log" order="8" sideWeight="0.5052169" side_tool="true" weight="0.34068358" />
|
<window_info anchor="bottom" id="Event Log" order="8" sideWeight="0.5052169" side_tool="true" weight="0.34068358" />
|
||||||
<window_info anchor="bottom" id="Dart Analysis" order="14" weight="0.32745314" />
|
<window_info anchor="bottom" id="Dart Analysis" order="14" weight="0.32745314" />
|
||||||
<window_info anchor="bottom" id="Run" order="2" sideWeight="0.49478307" weight="0.29437706" />
|
<window_info anchor="bottom" id="Run" order="2" sideWeight="0.49478307" visible="true" weight="0.36926362" />
|
||||||
<window_info anchor="bottom" id="Version Control" order="9" />
|
<window_info anchor="bottom" id="Version Control" order="9" />
|
||||||
<window_info active="true" anchor="bottom" id="Terminal" order="10" sideWeight="0.49533224" visible="true" weight="0.24696803" />
|
<window_info anchor="bottom" id="Terminal" order="10" sideWeight="0.49533224" weight="0.24653149" />
|
||||||
<window_info anchor="right" id="Flutter Outline" order="6" weight="0.32922077" />
|
<window_info anchor="right" id="Flutter Outline" order="6" weight="0.32922077" />
|
||||||
<window_info anchor="bottom" id="Logcat" order="11" />
|
<window_info anchor="bottom" id="Logcat" order="11" />
|
||||||
<window_info id="Captures" order="4" weight="0.32936507" />
|
<window_info id="Captures" order="4" weight="0.32936507" />
|
||||||
<window_info id="Capture Tool" order="6" />
|
<window_info id="Capture Tool" order="6" />
|
||||||
<window_info id="Designer" order="2" />
|
<window_info id="Designer" order="2" />
|
||||||
<window_info content_ui="combo" id="Project" order="0" sideWeight="0.49341142" visible="true" weight="0.13125764" />
|
<window_info active="true" content_ui="combo" id="Project" order="0" sideWeight="0.6615905" visible="true" weight="0.18210863" />
|
||||||
<window_info id="Structure" order="1" sideWeight="0.5065886" side_tool="true" visible="true" weight="0.13125764" />
|
<window_info id="Structure" order="1" sideWeight="0.33840948" side_tool="true" visible="true" weight="0.18210863" />
|
||||||
<window_info anchor="right" id="Device File Explorer" order="5" side_tool="true" />
|
<window_info anchor="right" id="Device File Explorer" order="5" side_tool="true" />
|
||||||
<window_info anchor="right" id="Theme Preview" order="7" />
|
<window_info anchor="right" id="Theme Preview" order="7" />
|
||||||
<window_info anchor="bottom" id="Debug" order="3" weight="0.34288865" />
|
<window_info anchor="bottom" id="Debug" order="3" weight="0.34288865" />
|
||||||
<window_info id="Favorites" order="5" side_tool="true" />
|
<window_info id="Favorites" order="5" side_tool="true" />
|
||||||
<window_info anchor="right" id="Flutter Inspector" order="3" weight="0.32938388" />
|
<window_info anchor="right" id="Flutter Inspector" order="3" weight="0.32938388" />
|
||||||
<window_info anchor="bottom" id="Messages" order="12" visible="true" weight="0.23594266" />
|
|
||||||
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
||||||
<window_info anchor="right" id="Commander" order="0" weight="0.4" />
|
<window_info anchor="right" id="Commander" order="0" weight="0.4" />
|
||||||
<window_info anchor="right" id="Assistant" order="8" visible="true" weight="0.3295129" />
|
<window_info anchor="right" id="Assistant" order="8" visible="true" weight="0.3295129" />
|
||||||
|
@ -418,55 +456,6 @@
|
||||||
</breakpoint-manager>
|
</breakpoint-manager>
|
||||||
</component>
|
</component>
|
||||||
<component name="editorHistoryManager">
|
<component name="editorHistoryManager">
|
||||||
<entry file="file://$PROJECT_DIR$/ios/Classes/InAppBrowser.h" />
|
|
||||||
<entry file="file://$PROJECT_DIR$/ios/Classes/InAppBrowser.m" />
|
|
||||||
<entry file="file://$PROJECT_DIR$/LICENSE">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="15">
|
|
||||||
<caret line="1" column="31" selection-start-line="1" selection-start-column="31" selection-end-line="1" selection-end-column="31" />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/android/src/main/AndroidManifest.xml">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="90">
|
|
||||||
<caret line="6" lean-forward="true" selection-start-line="6" selection-end-line="6" />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserClient.java" />
|
|
||||||
<entry file="file://$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserDialog.java" />
|
|
||||||
<entry file="file://$PROJECT_DIR$/example/ios/Flutter/Release.xcconfig">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state />
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/example/ios/Flutter/Debug.xcconfig">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="30">
|
|
||||||
<caret line="2" selection-start-line="2" selection-end-line="2" selection-end-column="24" />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/example/android/app/src/main/AndroidManifest.xml">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state />
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/ios/Classes/InAppBrowserWebViewController.swift">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="180">
|
|
||||||
<caret line="12" selection-start-line="12" selection-end-line="12" />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/ios/Classes/SwiftFlutterPlugin.swift">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="191">
|
|
||||||
<caret line="107" column="9" selection-start-line="107" selection-start-column="9" selection-end-line="107" selection-end-column="9" />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/example/android/build.gradle">
|
<entry file="file://$PROJECT_DIR$/example/android/build.gradle">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state />
|
<state />
|
||||||
|
@ -510,23 +499,6 @@
|
||||||
<state relative-caret-position="-10645" />
|
<state relative-caret-position="-10645" />
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/android/settings.gradle">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state>
|
|
||||||
<caret column="20" selection-start-column="20" selection-end-column="20" />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/android/local.properties">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state />
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/android/gradle.properties">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state />
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$USER_HOME$/flutter/bin/cache/pkg/sky_engine/lib/core/string.dart">
|
<entry file="file://$USER_HOME$/flutter/bin/cache/pkg/sky_engine/lib/core/string.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="173">
|
<state relative-caret-position="173">
|
||||||
|
@ -534,20 +506,6 @@
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/ios/flutter_inappbrowser.podspec">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="330">
|
|
||||||
<caret line="22" lean-forward="true" selection-start-line="22" selection-end-line="22" />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/android/build.gradle">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="414">
|
|
||||||
<caret line="34" column="5" selection-start-line="34" selection-start-column="5" selection-end-line="34" selection-end-column="5" />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/example/assets/images/dart.svg">
|
<entry file="file://$PROJECT_DIR$/example/assets/images/dart.svg">
|
||||||
<provider selected="true" editor-type-id="images">
|
<provider selected="true" editor-type-id="images">
|
||||||
<state />
|
<state />
|
||||||
|
@ -572,13 +530,6 @@
|
||||||
<state />
|
<state />
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/example/ios/Podfile">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="975">
|
|
||||||
<caret line="65" column="52" selection-start-line="65" selection-start-column="52" selection-end-line="65" selection-end-column="52" />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/example/flutter_webview_example.iml">
|
<entry file="file://$PROJECT_DIR$/example/flutter_webview_example.iml">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state />
|
<state />
|
||||||
|
@ -643,54 +594,178 @@
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/pubspec.yaml">
|
<entry file="file://$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebView.java">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="15">
|
<state relative-caret-position="-1555">
|
||||||
<caret line="1" column="103" selection-start-line="1" selection-start-column="103" selection-end-line="1" selection-end-column="103" />
|
<caret line="2" selection-start-line="2" selection-end-line="2" />
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
|
<entry file="file://$PROJECT_DIR$/ios/flutter_inappbrowser.podspec">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state>
|
<state relative-caret-position="330">
|
||||||
<caret selection-end-line="3" selection-end-column="21" />
|
<caret line="22" selection-start-line="22" selection-end-line="22" />
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/README.md">
|
<entry file="file://$PROJECT_DIR$/example/lib/inline_example.screen.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="327">
|
<state relative-caret-position="52">
|
||||||
<caret line="601" column="21" selection-start-line="601" selection-start-column="21" selection-end-line="601" selection-end-column="21" />
|
<caret line="14" column="20" selection-start-line="14" selection-start-column="20" selection-end-line="14" selection-end-column="20" />
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/example/ios/Runner/Info.plist">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="735">
|
|
||||||
<caret line="49" column="4" selection-start-line="49" selection-start-column="4" selection-end-line="49" selection-end-column="4" />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/lib/flutter_inappbrowser.dart">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="4380">
|
|
||||||
<caret line="323" column="41" selection-start-line="323" selection-start-column="41" selection-end-line="323" selection-end-column="41" />
|
|
||||||
<folding>
|
<folding>
|
||||||
<element signature="e#814#831#0" expanded="true" />
|
<element signature="e#0#39#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/example/lib/webview_example.screen.dart">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="254">
|
||||||
|
<caret line="63" column="2" selection-start-line="63" selection-start-column="2" selection-end-line="63" selection-end-column="2" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#20#0" expanded="true" />
|
||||||
</folding>
|
</folding>
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
|
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="405">
|
<state relative-caret-position="24">
|
||||||
<caret line="27" column="18" lean-forward="true" selection-start-line="27" selection-start-column="18" selection-end-line="27" selection-end-column="18" />
|
<caret line="27" column="18" selection-end-line="63" />
|
||||||
<folding>
|
<folding>
|
||||||
<element signature="e#0#20#0" expanded="true" />
|
<element signature="e#0#20#0" expanded="true" />
|
||||||
</folding>
|
</folding>
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/example/lib/test.dart">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="590">
|
||||||
|
<caret line="475" selection-start-line="343" selection-end-line="475" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#16428#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/android/gradle.properties">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state />
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/android/local.properties">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state />
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/example/android/gradle/wrapper/gradle-wrapper.properties">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="75">
|
||||||
|
<caret line="5" selection-start-line="5" selection-end-line="5" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/android/settings.gradle">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="15">
|
||||||
|
<caret line="1" selection-start-line="1" selection-end-line="1" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/android/gradle/wrapper/gradle-wrapper.properties">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="75">
|
||||||
|
<caret line="5" selection-start-line="5" selection-end-line="5" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/example/lib/chrome_safari_example.screen.dart">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="317">
|
||||||
|
<caret line="24" column="80" selection-start-line="24" selection-start-column="68" selection-end-line="24" selection-end-column="80" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#20#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/android/build.gradle">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="110">
|
||||||
|
<caret line="10" column="55" selection-start-line="10" selection-start-column="55" selection-end-line="10" selection-end-column="55" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/example/ios/Flutter/App.framework/Info.plist">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state />
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/example/ios/Flutter/Flutter.framework/Info.plist">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state />
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/example/ios/Flutter/AppFrameworkInfo.plist">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state />
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/example/ios/Runner/Info.plist">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="511">
|
||||||
|
<caret line="49" column="4" selection-start-line="49" selection-start-column="4" selection-end-line="49" selection-end-column="4" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/example/ios/Runner.xcodeproj/project.pbxproj">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="211">
|
||||||
|
<caret line="453" column="10" selection-start-line="453" selection-start-column="10" selection-end-line="453" selection-end-column="10" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/example/ios/Podfile">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="614">
|
||||||
|
<caret line="66" column="44" selection-start-line="66" selection-start-column="6" selection-end-line="66" selection-end-column="44" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/lib/flutter_inappbrowser.dart">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="415">
|
||||||
|
<caret line="698" column="22" selection-start-line="698" selection-start-column="13" selection-end-line="698" selection-end-column="22" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#814#831#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/README.md">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="589">
|
||||||
|
<caret line="72" column="7" lean-forward="true" selection-start-line="72" selection-start-column="7" selection-end-line="72" selection-end-column="7" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#39#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="195">
|
||||||
|
<caret line="13" column="21" selection-start-line="13" selection-start-column="21" selection-end-line="13" selection-end-column="21" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/pubspec.yaml">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="195">
|
||||||
|
<caret line="13" column="14" lean-forward="true" selection-start-line="13" selection-start-column="14" selection-end-line="13" selection-end-column="14" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
</component>
|
</component>
|
||||||
<component name="masterDetails">
|
<component name="masterDetails">
|
||||||
<states>
|
<states>
|
||||||
|
|
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -1,3 +1,13 @@
|
||||||
|
## 0.6.0
|
||||||
|
|
||||||
|
- added support for **iOS** inline native WebView integrated in the flutter widget tree
|
||||||
|
- updated example folder (thanks to [marquesinijatinha](https://github.com/marquesinijatinha))
|
||||||
|
- Fixed bug where passing null to expiresDate failed (thanks to [Sense545](https://github.com/Sense545))
|
||||||
|
- Fixed iOS error: encode resourceURL (thanks to [igtm](https://github.com/igtm))
|
||||||
|
- Fixed iOS error: Double value cannot be converted to Int because the result would be greater than Int.max in 32-bit devices (thanks to [huzhiren](https://github.com/huzhiren))
|
||||||
|
- Fixed iOS error: problem in ChromeSafariBrowser (thanks to [marquesinijatinha](https://github.com/marquesinijatinha))
|
||||||
|
- Fixed Android build error caused by gradle and build gradle versions (thanks to [tje3d](https://github.com/tje3d))
|
||||||
|
|
||||||
## 0.5.51
|
## 0.5.51
|
||||||
|
|
||||||
- updated `pubspec.yaml`
|
- updated `pubspec.yaml`
|
||||||
|
|
33
README.md
33
README.md
|
@ -15,12 +15,30 @@ This plugin is inspired by the popular [cordova-plugin-inappbrowser](https://git
|
||||||
- Flutter: ">=0.10.1 <2.0.0"
|
- Flutter: ">=0.10.1 <2.0.0"
|
||||||
|
|
||||||
### IMPORTANT Note for iOS
|
### IMPORTANT Note for iOS
|
||||||
To be able to use this plugin on iOS, you need to create the Flutter App with `flutter create -i swift` (see [flutter/flutter#13422 (comment)](https://github.com/flutter/flutter/issues/13422#issuecomment-392133780)), otherwise, you will get this message:
|
If you are starting a new fresh app, you need to create the Flutter App with `flutter create -i swift` (see [flutter/flutter#13422 (comment)](https://github.com/flutter/flutter/issues/13422#issuecomment-392133780)), otherwise, you will get this message:
|
||||||
```
|
```
|
||||||
=== BUILD TARGET flutter_inappbrowser OF PROJECT Pods WITH CONFIGURATION Debug ===
|
=== BUILD TARGET flutter_inappbrowser OF PROJECT Pods WITH CONFIGURATION Debug ===
|
||||||
The “Swift Language Version” (SWIFT_VERSION) build setting must be set to a supported value for targets which use Swift. Supported values are: 3.0, 4.0, 4.2. This setting can be set in the build settings editor.
|
The “Swift Language Version” (SWIFT_VERSION) build setting must be set to a supported value for targets which use Swift. Supported values are: 3.0, 4.0, 4.2. This setting can be set in the build settings editor.
|
||||||
```
|
```
|
||||||
that is not true! The Swift version that I have used is already a supported value: 4.0.
|
|
||||||
|
If you still have this problem, try to edit iOS `Podfile` like this (see [#15](https://github.com/pichillilorenzo/flutter_inappbrowser/issues/15)):
|
||||||
|
```
|
||||||
|
target 'Runner' do
|
||||||
|
use_frameworks! # required by simple_permission
|
||||||
|
...
|
||||||
|
end
|
||||||
|
|
||||||
|
post_install do |installer|
|
||||||
|
installer.pods_project.targets.each do |target|
|
||||||
|
target.build_configurations.each do |config|
|
||||||
|
config.build_settings['SWIFT_VERSION'] = '4.0' # required by simple_permission
|
||||||
|
config.build_settings['ENABLE_BITCODE'] = 'NO'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Instead, if you have already a non-swift project, you can check this issue to solve the problem: [Friction adding swift plugin to objective-c project](https://github.com/flutter/flutter/issues/16049).
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
|
@ -34,7 +52,7 @@ First, add `flutter_inappbrowser` as a [dependency in your pubspec.yaml file](ht
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
Classes:
|
Classes:
|
||||||
- [InAppWebView](#inappwebview-class): Flutter Widget for adding an **inline native WebView** integrated in the flutter widget tree. [**Available only for Android** ([AndroidView](https://docs.flutter.io/flutter/widgets/AndroidView-class.html)) at this moment. For iOS, it will be available as soon as the Flutter team will release the corresponding dart class.].
|
- [InAppWebView](#inappwebview-class): Flutter Widget for adding an **inline native WebView** integrated in the flutter widget tree. To use `InAppWebView` class on iOS you need to opt-in for the embedded views preview by adding a boolean property to the app's `Info.plist` file, with the key `io.flutter.embedded_views_preview` and the value `YES`.
|
||||||
- [InAppBrowser](#inappbrowser-class): In-App Browser using native WebView.
|
- [InAppBrowser](#inappbrowser-class): In-App Browser using native WebView.
|
||||||
- [ChromeSafariBrowser](#chromesafaribrowser-class): In-App Browser using [Chrome Custom Tabs](https://developer.android.com/reference/android/support/customtabs/package-summary) on Android / [SFSafariViewController](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller) on iOS.
|
- [ChromeSafariBrowser](#chromesafaribrowser-class): In-App Browser using [Chrome Custom Tabs](https://developer.android.com/reference/android/support/customtabs/package-summary) on Android / [SFSafariViewController](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller) on iOS.
|
||||||
- [InAppLocalhostServer](#inapplocalhostserver-class): This class allows you to create a simple server on `http://localhost:[port]/`. The default `port` value is `8080`.
|
- [InAppLocalhostServer](#inapplocalhostserver-class): This class allows you to create a simple server on `http://localhost:[port]/`. The default `port` value is `8080`.
|
||||||
|
@ -45,11 +63,10 @@ See the online [docs](https://pub.dartlang.org/documentation/flutter_inappbrowse
|
||||||
### `InAppWebView` class
|
### `InAppWebView` class
|
||||||
Flutter Widget for adding an **inline native WebView** integrated in the flutter widget tree.
|
Flutter Widget for adding an **inline native WebView** integrated in the flutter widget tree.
|
||||||
|
|
||||||
[AndroidView](https://docs.flutter.io/flutter/widgets/AndroidView-class.html) is not officially stable yet!
|
[AndroidView](https://docs.flutter.io/flutter/widgets/AndroidView-class.html) and [UiKitView](https://docs.flutter.io/flutter/widgets/UiKitView-class.html) is not officially stable yet!
|
||||||
So, if you want use it, you can but you will have some limitation such as the inability to use the keyboard!
|
So, if you want use it, you can but you will have some limitation such as the inability to use the keyboard!
|
||||||
|
|
||||||
**Available only for Android** ([AndroidView](https://docs.flutter.io/flutter/widgets/AndroidView-class.html)) at this moment.
|
To use `InAppWebView` class on iOS you need to opt-in for the embedded views preview by adding a boolean property to the app's `Info.plist` file, with the key `io.flutter.embedded_views_preview` and the value `YES`.
|
||||||
For iOS, it will be available as soon as the Flutter team will release the corresponding dart class.
|
|
||||||
|
|
||||||
Use `InAppWebViewController` to control the WebView instance.
|
Use `InAppWebViewController` to control the WebView instance.
|
||||||
Example:
|
Example:
|
||||||
|
@ -189,6 +206,10 @@ Screenshots:
|
||||||
|
|
||||||
![android](https://user-images.githubusercontent.com/5956938/47271038-7aebda80-d574-11e8-98fd-41e6bbc9fe2d.gif)
|
![android](https://user-images.githubusercontent.com/5956938/47271038-7aebda80-d574-11e8-98fd-41e6bbc9fe2d.gif)
|
||||||
|
|
||||||
|
- iOS:
|
||||||
|
|
||||||
|
![ios](https://user-images.githubusercontent.com/5956938/54096363-e1e72000-43ab-11e9-85c2-983a830ab7a0.gif)
|
||||||
|
|
||||||
#### InAppWebView.initialUrl
|
#### InAppWebView.initialUrl
|
||||||
Initial url that will be loaded.
|
Initial url that will be loaded.
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ buildscript {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.1.2'
|
classpath 'com.android.tools.build:gradle:3.3.0'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|
|
@ -359,14 +359,15 @@ public class InAppWebViewClient extends WebViewClient {
|
||||||
|
|
||||||
getChannel().invokeMethod("onLoadResource", obj);
|
getChannel().invokeMethod("onLoadResource", obj);
|
||||||
|
|
||||||
return new WebResourceResponse(
|
// this return is not working (it blocks some resources), so return null
|
||||||
response.header("content-type", "text/plain").split(";")[0].trim(),
|
// return new WebResourceResponse(
|
||||||
response.header("content-encoding"),
|
// response.header("content-type", "text/plain").split(";")[0].trim(),
|
||||||
response.code(),
|
// response.header("content-encoding", "utf-8"),
|
||||||
reasonPhrase,
|
// response.code(),
|
||||||
headersResponse,
|
// reasonPhrase,
|
||||||
dataStream
|
// headersResponse,
|
||||||
);
|
// dataStream
|
||||||
|
// );
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Log.d(LOG_TAG, e.getMessage());
|
Log.d(LOG_TAG, e.getMessage());
|
||||||
|
|
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
|
||||||
|
|
|
@ -446,7 +446,7 @@
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||||
SWIFT_VERSION = 4.0;
|
SWIFT_VERSION = 4.0;
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
|
@ -474,7 +474,7 @@
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.pichillilorenzo.flutter_inappbrowserExample;
|
PRODUCT_BUNDLE_IDENTIFIER = com.pichillilorenzo.flutter_inappbrowserExample;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||||
SWIFT_VERSION = 4.0;
|
SWIFT_VERSION = 4.0;
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,8 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_inappbrowser/flutter_inappbrowser.dart';
|
import 'package:flutter_inappbrowser/flutter_inappbrowser.dart';
|
||||||
|
|
||||||
class MyInappBrowser extends InAppBrowser {
|
class MyInappBrowser extends InAppBrowser {
|
||||||
@override
|
|
||||||
|
@override
|
||||||
Future onBrowserCreated() async {
|
Future onBrowserCreated() async {
|
||||||
print("\n\nBrowser Ready!\n\n");
|
print("\n\nBrowser Ready!\n\n");
|
||||||
}
|
}
|
||||||
|
@ -64,7 +65,7 @@ class MyInappBrowser extends InAppBrowser {
|
||||||
}
|
}
|
||||||
|
|
||||||
class WebviewExampleScreen extends StatefulWidget {
|
class WebviewExampleScreen extends StatefulWidget {
|
||||||
final InAppBrowser browser = new InAppBrowser();
|
final InAppBrowser browser = new MyInappBrowser();
|
||||||
@override
|
@override
|
||||||
_WebviewExampleScreenState createState() => new _WebviewExampleScreenState();
|
_WebviewExampleScreenState createState() => new _WebviewExampleScreenState();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/.dart_tool" />
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/.dart_tool" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/.pub" />
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/.pub" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/build" />
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/build" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/ios/Flutter/flutter_assets/packages" />
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/Flutter/App.framework/flutter_assets/packages" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/Flutter/flutter_assets/packages" />
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/Flutter/flutter_assets/packages" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
|
|
@ -14,73 +14,6 @@ import AVFoundation
|
||||||
typealias OlderClosureType = @convention(c) (Any, Selector, UnsafeRawPointer, Bool, Bool, Any?) -> Void
|
typealias OlderClosureType = @convention(c) (Any, Selector, UnsafeRawPointer, Bool, Bool, Any?) -> Void
|
||||||
typealias NewerClosureType = @convention(c) (Any, Selector, UnsafeRawPointer, Bool, Bool, Bool, Any?) -> Void
|
typealias NewerClosureType = @convention(c) (Any, Selector, UnsafeRawPointer, Bool, Bool, Bool, Any?) -> Void
|
||||||
|
|
||||||
// the message needs to be concatenated with '' in order to have the same behavior like on Android
|
|
||||||
let consoleLogJS = """
|
|
||||||
(function() {
|
|
||||||
var oldLogs = {
|
|
||||||
'consoleLog': console.log,
|
|
||||||
'consoleDebug': console.debug,
|
|
||||||
'consoleError': console.error,
|
|
||||||
'consoleInfo': console.info,
|
|
||||||
'consoleWarn': console.warn
|
|
||||||
};
|
|
||||||
|
|
||||||
for (var k in oldLogs) {
|
|
||||||
(function(oldLog) {
|
|
||||||
console[oldLog.replace('console', '').toLowerCase()] = function() {
|
|
||||||
var message = '';
|
|
||||||
for (var i in arguments) {
|
|
||||||
if (message == '') {
|
|
||||||
message += arguments[i];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
message += ' ' + arguments[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
window.webkit.messageHandlers[oldLog].postMessage(message);
|
|
||||||
}
|
|
||||||
})(k);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
"""
|
|
||||||
|
|
||||||
let resourceObserverJS = """
|
|
||||||
(function() {
|
|
||||||
var observer = new PerformanceObserver(function(list) {
|
|
||||||
list.getEntries().forEach(function(entry) {
|
|
||||||
window.webkit.messageHandlers['resourceLoaded'].postMessage(JSON.stringify(entry));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
observer.observe({entryTypes: ['resource', 'mark', 'measure']});
|
|
||||||
})();
|
|
||||||
"""
|
|
||||||
|
|
||||||
let JAVASCRIPT_BRIDGE_NAME = "flutter_inappbrowser"
|
|
||||||
|
|
||||||
let javaScriptBridgeJS = """
|
|
||||||
window.\(JAVASCRIPT_BRIDGE_NAME) = {};
|
|
||||||
window.\(JAVASCRIPT_BRIDGE_NAME).callHandler = function(handlerName, ...args) {
|
|
||||||
window.webkit.messageHandlers['callHandler'].postMessage( {'handlerName': handlerName, 'args': JSON.stringify(args)} );
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|
|
||||||
func currentTimeInMilliSeconds() -> Int64 {
|
|
||||||
let currentDate = Date()
|
|
||||||
let since1970 = currentDate.timeIntervalSince1970
|
|
||||||
return Int64(since1970 * 1000)
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertToDictionary(text: String) -> [String: Any]? {
|
|
||||||
if let data = text.data(using: .utf8) {
|
|
||||||
do {
|
|
||||||
return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
|
|
||||||
} catch {
|
|
||||||
print(error.localizedDescription)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
//extension WKWebView{
|
//extension WKWebView{
|
||||||
//
|
//
|
||||||
// var keyboardDisplayRequiresUserAction: Bool? {
|
// var keyboardDisplayRequiresUserAction: Bool? {
|
||||||
|
@ -137,7 +70,7 @@ class InAppWebView_IBWrapper: InAppWebView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKUIDelegate, WKNavigationDelegate, UITextFieldDelegate, WKScriptMessageHandler {
|
class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKUIDelegate, UITextFieldDelegate {
|
||||||
|
|
||||||
@IBOutlet var webView: InAppWebView_IBWrapper!
|
@IBOutlet var webView: InAppWebView_IBWrapper!
|
||||||
@IBOutlet var closeButton: UIButton!
|
@IBOutlet var closeButton: UIButton!
|
||||||
|
@ -156,7 +89,7 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
|
||||||
@IBOutlet var webView_TopFullScreenConstraint: NSLayoutConstraint!
|
@IBOutlet var webView_TopFullScreenConstraint: NSLayoutConstraint!
|
||||||
|
|
||||||
weak var navigationDelegate: SwiftFlutterPlugin?
|
weak var navigationDelegate: SwiftFlutterPlugin?
|
||||||
var currentURL: URL?
|
var initURL: URL?
|
||||||
var tmpWindow: UIWindow?
|
var tmpWindow: UIWindow?
|
||||||
var browserOptions: InAppBrowserOptions?
|
var browserOptions: InAppBrowserOptions?
|
||||||
var webViewOptions: InAppWebViewOptions?
|
var webViewOptions: InAppWebViewOptions?
|
||||||
|
@ -189,12 +122,12 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
||||||
webView.uiDelegate = self
|
// webView.uiDelegate = self
|
||||||
webView.navigationDelegate = self
|
// webView.navigationDelegate = nil
|
||||||
webView.scrollView.delegate = self
|
// webView.scrollView.delegate = self
|
||||||
|
|
||||||
urlField.delegate = self
|
urlField.delegate = self
|
||||||
urlField.text = self.currentURL?.absoluteString
|
urlField.text = self.initURL?.absoluteString
|
||||||
|
|
||||||
closeButton.addTarget(self, action: #selector(self.close), for: .touchUpInside)
|
closeButton.addTarget(self, action: #selector(self.close), for: .touchUpInside)
|
||||||
|
|
||||||
|
@ -218,7 +151,7 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
|
||||||
spinner.stopAnimating()
|
spinner.stopAnimating()
|
||||||
|
|
||||||
if self.initData == nil {
|
if self.initData == nil {
|
||||||
loadUrl(url: self.currentURL!, headers: self.initHeaders)
|
loadUrl(url: self.initURL!, headers: self.initHeaders)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
loadData(data: initData!, mimeType: initMimeType!, encoding: initEncoding!, baseUrl: initBaseUrl!)
|
loadData(data: initData!, mimeType: initMimeType!, encoding: initEncoding!, baseUrl: initBaseUrl!)
|
||||||
|
@ -245,13 +178,8 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
|
||||||
func prepareWebView() {
|
func prepareWebView() {
|
||||||
//UIApplication.shared.statusBarStyle = preferredStatusBarStyle
|
//UIApplication.shared.statusBarStyle = preferredStatusBarStyle
|
||||||
|
|
||||||
self.webView.addObserver(self,
|
self.webView.options = webViewOptions
|
||||||
forKeyPath: #keyPath(WKWebView.estimatedProgress),
|
self.webView.prepare()
|
||||||
options: .new,
|
|
||||||
context: nil)
|
|
||||||
|
|
||||||
self.webView.configuration.userContentController = WKUserContentController()
|
|
||||||
self.webView.configuration.preferences = WKPreferences()
|
|
||||||
|
|
||||||
if (browserOptions?.hideUrlBar)! {
|
if (browserOptions?.hideUrlBar)! {
|
||||||
self.urlField.isHidden = true
|
self.urlField.isHidden = true
|
||||||
|
@ -290,133 +218,21 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
|
||||||
|
|
||||||
self.modalPresentationStyle = UIModalPresentationStyle(rawValue: (browserOptions?.presentationStyle)!)!
|
self.modalPresentationStyle = UIModalPresentationStyle(rawValue: (browserOptions?.presentationStyle)!)!
|
||||||
self.modalTransitionStyle = UIModalTransitionStyle(rawValue: (browserOptions?.transitionStyle)!)!
|
self.modalTransitionStyle = UIModalTransitionStyle(rawValue: (browserOptions?.transitionStyle)!)!
|
||||||
|
|
||||||
// prevent webView from bouncing
|
|
||||||
if (webViewOptions?.disallowOverScroll)! {
|
|
||||||
if self.webView.responds(to: #selector(getter: self.webView.scrollView)) {
|
|
||||||
self.webView.scrollView.bounces = false
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for subview: UIView in self.webView.subviews {
|
|
||||||
if subview is UIScrollView {
|
|
||||||
(subview as! UIScrollView).bounces = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (webViewOptions?.enableViewportScale)! {
|
|
||||||
let jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"
|
|
||||||
let userScript = WKUserScript(source: jscript, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
|
|
||||||
self.webView.configuration.userContentController.addUserScript(userScript)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prevents long press on links that cause WKWebView exit
|
|
||||||
let jscriptWebkitTouchCallout = WKUserScript(source: "document.body.style.webkitTouchCallout='none';", injectionTime: .atDocumentEnd, forMainFrameOnly: true)
|
|
||||||
self.webView.configuration.userContentController.addUserScript(jscriptWebkitTouchCallout)
|
|
||||||
|
|
||||||
|
|
||||||
let consoleLogJSScript = WKUserScript(source: consoleLogJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
|
||||||
self.webView.configuration.userContentController.addUserScript(consoleLogJSScript)
|
|
||||||
self.webView.configuration.userContentController.add(self, name: "consoleLog")
|
|
||||||
self.webView.configuration.userContentController.add(self, name: "consoleDebug")
|
|
||||||
self.webView.configuration.userContentController.add(self, name: "consoleError")
|
|
||||||
self.webView.configuration.userContentController.add(self, name: "consoleInfo")
|
|
||||||
self.webView.configuration.userContentController.add(self, name: "consoleWarn")
|
|
||||||
|
|
||||||
let javaScriptBridgeJSScript = WKUserScript(source: javaScriptBridgeJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
|
||||||
self.webView.configuration.userContentController.addUserScript(javaScriptBridgeJSScript)
|
|
||||||
self.webView.configuration.userContentController.add(self, name: "callHandler")
|
|
||||||
|
|
||||||
let resourceObserverJSScript = WKUserScript(source: resourceObserverJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
|
||||||
self.webView.configuration.userContentController.addUserScript(resourceObserverJSScript)
|
|
||||||
self.webView.configuration.userContentController.add(self, name: "resourceLoaded")
|
|
||||||
|
|
||||||
if #available(iOS 10.0, *) {
|
|
||||||
self.webView.configuration.mediaTypesRequiringUserActionForPlayback = ((webViewOptions?.mediaPlaybackRequiresUserGesture)!) ? .all : []
|
|
||||||
} else {
|
|
||||||
// Fallback on earlier versions
|
|
||||||
self.webView.configuration.mediaPlaybackRequiresUserAction = (webViewOptions?.mediaPlaybackRequiresUserGesture)!
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
self.webView.configuration.allowsInlineMediaPlayback = (webViewOptions?.allowsInlineMediaPlayback)!
|
|
||||||
|
|
||||||
//self.webView.keyboardDisplayRequiresUserAction = browserOptions?.keyboardDisplayRequiresUserAction
|
|
||||||
|
|
||||||
self.webView.configuration.suppressesIncrementalRendering = (webViewOptions?.suppressesIncrementalRendering)!
|
|
||||||
self.webView.allowsBackForwardNavigationGestures = (webViewOptions?.allowsBackForwardNavigationGestures)!
|
|
||||||
if #available(iOS 9.0, *) {
|
|
||||||
self.webView.allowsLinkPreview = (webViewOptions?.allowsLinkPreview)!
|
|
||||||
}
|
|
||||||
|
|
||||||
if #available(iOS 10.0, *) {
|
|
||||||
self.webView.configuration.ignoresViewportScaleLimits = (webViewOptions?.ignoresViewportScaleLimits)!
|
|
||||||
}
|
|
||||||
|
|
||||||
self.webView.configuration.allowsInlineMediaPlayback = (webViewOptions?.allowsInlineMediaPlayback)!
|
|
||||||
|
|
||||||
if #available(iOS 9.0, *) {
|
|
||||||
self.webView.configuration.allowsPictureInPictureMediaPlayback = (webViewOptions?.allowsPictureInPictureMediaPlayback)!
|
|
||||||
}
|
|
||||||
|
|
||||||
self.webView.configuration.preferences.javaScriptCanOpenWindowsAutomatically = (webViewOptions?.javaScriptCanOpenWindowsAutomatically)!
|
|
||||||
|
|
||||||
self.webView.configuration.preferences.javaScriptEnabled = (webViewOptions?.javaScriptEnabled)!
|
|
||||||
|
|
||||||
if ((webViewOptions?.userAgent)! != "") {
|
|
||||||
if #available(iOS 9.0, *) {
|
|
||||||
self.webView.customUserAgent = (webViewOptions?.userAgent)!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (webViewOptions?.clearCache)! {
|
|
||||||
clearCache()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadUrl(url: URL, headers: [String: String]?) {
|
func loadUrl(url: URL, headers: [String: String]?) {
|
||||||
var request = URLRequest(url: url)
|
webView.loadUrl(url: url, headers: headers)
|
||||||
currentURL = url
|
updateUrlTextField(url: (webView.currentURL?.absoluteString)!)
|
||||||
updateUrlTextField(url: (currentURL?.absoluteString)!)
|
|
||||||
|
|
||||||
if let mutableRequest = (request as NSURLRequest).mutableCopy() as? NSMutableURLRequest {
|
|
||||||
for (key, value) in headers! {
|
|
||||||
mutableRequest.setValue(value, forHTTPHeaderField: key)
|
|
||||||
}
|
|
||||||
request = mutableRequest as URLRequest
|
|
||||||
}
|
|
||||||
|
|
||||||
webView.load(request)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadData(data: String, mimeType: String, encoding: String, baseUrl: String) {
|
func loadData(data: String, mimeType: String, encoding: String, baseUrl: String) {
|
||||||
let url = URL(string: baseUrl)!
|
webView.loadData(data: data, mimeType: mimeType, encoding: encoding, baseUrl: baseUrl)
|
||||||
currentURL = url
|
|
||||||
if #available(iOS 9.0, *) {
|
|
||||||
webView.load(data.data(using: .utf8)!, mimeType: mimeType, characterEncodingName: encoding, baseURL: url)
|
|
||||||
} else {
|
|
||||||
webView.loadHTMLString(data, baseURL: url)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func postUrl(url: URL, postData: Data, result: @escaping FlutterResult) {
|
func postUrl(url: URL, postData: Data, result: @escaping FlutterResult) {
|
||||||
var request = URLRequest(url: url)
|
webView.postUrl(url: url, postData: postData, completionHandler: { () -> Void in
|
||||||
request.httpMethod = "POST"
|
result(true)
|
||||||
request.httpBody = postData
|
})
|
||||||
|
|
||||||
let task = URLSession.shared.dataTask(with: request) { (data : Data?, response : URLResponse?, error : Error?) in
|
|
||||||
var returnString = ""
|
|
||||||
if data != nil {
|
|
||||||
returnString = String(data: data!, encoding: .utf8) ?? ""
|
|
||||||
}
|
|
||||||
DispatchQueue.main.async(execute: {() -> Void in
|
|
||||||
self.webView.loadHTMLString(returnString, baseURL: url)
|
|
||||||
result(true)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
task.resume()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load user requested url
|
// Load user requested url
|
||||||
|
@ -428,9 +244,8 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
|
||||||
webView.load(request)
|
webView.load(request)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
updateUrlTextField(url: (currentURL?.absoluteString)!)
|
updateUrlTextField(url: (webView.currentURL?.absoluteString)!)
|
||||||
}
|
}
|
||||||
//var list : WKBackForwardList = self.webView.backForwardList
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,30 +254,12 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
|
||||||
webView.frame = frame
|
webView.frame = frame
|
||||||
}
|
}
|
||||||
|
|
||||||
func clearCache() {
|
|
||||||
if #available(iOS 9.0, *) {
|
|
||||||
//let websiteDataTypes = NSSet(array: [WKWebsiteDataTypeDiskCache, WKWebsiteDataTypeMemoryCache])
|
|
||||||
let date = NSDate(timeIntervalSince1970: 0)
|
|
||||||
WKWebsiteDataStore.default().removeData(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(), modifiedSince: date as Date, completionHandler:{ })
|
|
||||||
} else {
|
|
||||||
var libraryPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.libraryDirectory, FileManager.SearchPathDomainMask.userDomainMask, false).first!
|
|
||||||
libraryPath += "/Cookies"
|
|
||||||
|
|
||||||
do {
|
|
||||||
try FileManager.default.removeItem(atPath: libraryPath)
|
|
||||||
} catch {
|
|
||||||
print("can't clear cache")
|
|
||||||
}
|
|
||||||
URLCache.shared.removeAllCachedResponses()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc func reload () {
|
@objc func reload () {
|
||||||
webView.reload()
|
webView.reload()
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func share () {
|
@objc func share () {
|
||||||
let vc = UIActivityViewController(activityItems: [currentURL ?? ""], applicationActivities: [])
|
let vc = UIActivityViewController(activityItems: [webView.currentURL ?? ""], applicationActivities: [])
|
||||||
present(vc, animated: true, completion: nil)
|
present(vc, animated: true, completion: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -569,237 +366,12 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
|
||||||
scanner.scanHexInt32(&hexInt)
|
scanner.scanHexInt32(&hexInt)
|
||||||
return hexInt
|
return hexInt
|
||||||
}
|
}
|
||||||
|
|
||||||
func webView(_ webView: WKWebView,
|
|
||||||
decidePolicyFor navigationAction: WKNavigationAction,
|
|
||||||
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
|
|
||||||
|
|
||||||
if let url = navigationAction.request.url {
|
|
||||||
|
|
||||||
if url.absoluteString != self.currentURL?.absoluteString && (webViewOptions?.useOnLoadResource)! {
|
|
||||||
WKNavigationMap[url.absoluteString] = [
|
|
||||||
"startTime": currentTimeInMilliSeconds(),
|
|
||||||
"request": navigationAction.request
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
if navigationAction.navigationType == .linkActivated && (webViewOptions?.useShouldOverrideUrlLoading)! {
|
|
||||||
if navigationDelegate != nil {
|
|
||||||
navigationDelegate?.shouldOverrideUrlLoading(uuid: self.uuid, webView: webView, url: url)
|
|
||||||
}
|
|
||||||
decisionHandler(.cancel)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if navigationAction.navigationType == .linkActivated || navigationAction.navigationType == .backForward {
|
|
||||||
currentURL = url
|
|
||||||
updateUrlTextField(url: (url.absoluteString))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
decisionHandler(.allow)
|
|
||||||
}
|
|
||||||
|
|
||||||
func webView(_ webView: WKWebView,
|
|
||||||
decidePolicyFor navigationResponse: WKNavigationResponse,
|
|
||||||
decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
|
|
||||||
|
|
||||||
if (webViewOptions?.useOnLoadResource)! {
|
|
||||||
if let url = navigationResponse.response.url {
|
|
||||||
if WKNavigationMap[url.absoluteString] != nil {
|
|
||||||
let startResourceTime: Int64 = (WKNavigationMap[url.absoluteString]!["startTime"] as! Int64)
|
|
||||||
let startTime: Int64 = startResourceTime - startPageTime;
|
|
||||||
let duration: Int64 = currentTimeInMilliSeconds() - startResourceTime;
|
|
||||||
self.didReceiveResourceResponse(navigationResponse.response, fromRequest: WKNavigationMap[url.absoluteString]!["request"] as? URLRequest, withData: Data(), startTime: startTime, duration: duration)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
decisionHandler(.allow)
|
|
||||||
}
|
|
||||||
|
|
||||||
// func webView(_ webView: WKWebView,
|
|
||||||
// decidePolicyFor navigationResponse: WKNavigationResponse,
|
|
||||||
// decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
|
|
||||||
// let mimeType = navigationResponse.response.mimeType
|
|
||||||
// if mimeType != nil && !mimeType!.starts(with: "text/") {
|
|
||||||
// download(url: webView.url)
|
|
||||||
// decisionHandler(.cancel)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// decisionHandler(.allow)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// func download (url: URL?) {
|
|
||||||
// let filename = url?.lastPathComponent
|
|
||||||
//
|
|
||||||
// let destination: DownloadRequest.DownloadFileDestination = { _, _ in
|
|
||||||
// let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
|
|
||||||
// let fileURL = documentsURL.appendingPathComponent(filename!)
|
|
||||||
//
|
|
||||||
// return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Alamofire.download((url?.absoluteString)!, to: destination).downloadProgress { progress in
|
|
||||||
// print("Download Progress: \(progress.fractionCompleted)")
|
|
||||||
// }.response { response in
|
|
||||||
// if response.error == nil, let path = response.destinationURL?.path {
|
|
||||||
// UIAlertView(title: nil, message: "File saved to " + path, delegate: nil, cancelButtonTitle: nil).show()
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// UIAlertView(title: nil, message: "Cannot save " + filename!, delegate: nil, cancelButtonTitle: nil).show()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
|
|
||||||
|
|
||||||
self.startPageTime = currentTimeInMilliSeconds()
|
|
||||||
|
|
||||||
// loading url, start spinner, update back/forward
|
|
||||||
backButton.isEnabled = webView.canGoBack
|
|
||||||
forwardButton.isEnabled = webView.canGoForward
|
|
||||||
|
|
||||||
if (browserOptions?.spinner)! {
|
|
||||||
spinner.startAnimating()
|
|
||||||
}
|
|
||||||
|
|
||||||
if navigationDelegate != nil {
|
|
||||||
navigationDelegate?.onLoadStart(uuid: self.uuid, webView: webView)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
|
||||||
self.WKNavigationMap = [:]
|
|
||||||
// update url, stop spinner, update back/forward
|
|
||||||
currentURL = webView.url
|
|
||||||
updateUrlTextField(url: (currentURL?.absoluteString)!)
|
|
||||||
backButton.isEnabled = webView.canGoBack
|
|
||||||
forwardButton.isEnabled = webView.canGoForward
|
|
||||||
spinner.stopAnimating()
|
|
||||||
|
|
||||||
if navigationDelegate != nil {
|
|
||||||
navigationDelegate?.onLoadStop(uuid: self.uuid, webView: webView)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func webView(_ view: WKWebView,
|
|
||||||
didFailProvisionalNavigation navigation: WKNavigation!,
|
|
||||||
withError error: Error) {
|
|
||||||
webView(view, didFail: navigation, withError: error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
|
|
||||||
backButton.isEnabled = webView.canGoBack
|
|
||||||
forwardButton.isEnabled = webView.canGoForward
|
|
||||||
spinner.stopAnimating()
|
|
||||||
|
|
||||||
if navigationDelegate != nil {
|
|
||||||
navigationDelegate?.onLoadError(uuid: self.uuid, webView: webView, error: error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func didReceiveResourceResponse(_ response: URLResponse, fromRequest request: URLRequest?, withData data: Data, startTime: Int64, duration: Int64) {
|
|
||||||
if navigationDelegate != nil {
|
|
||||||
navigationDelegate?.onLoadResource(uuid: self.uuid, webView: webView, response: response, fromRequest: request, withData: data, startTime: startTime, duration: duration)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
|
||||||
if navigationDelegate != nil {
|
|
||||||
let x = Int(scrollView.contentOffset.x / scrollView.contentScaleFactor)
|
|
||||||
let y = Int(scrollView.contentOffset.y / scrollView.contentScaleFactor)
|
|
||||||
navigationDelegate?.onScrollChanged(uuid: self.uuid, webView: webView, x: x, y: y)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
|
||||||
if message.name.starts(with: "console") {
|
|
||||||
var messageLevel = "LOG"
|
|
||||||
switch (message.name) {
|
|
||||||
case "consoleLog":
|
|
||||||
messageLevel = "LOG"
|
|
||||||
break;
|
|
||||||
case "consoleDebug":
|
|
||||||
// on Android, console.debug is TIP
|
|
||||||
messageLevel = "TIP"
|
|
||||||
break;
|
|
||||||
case "consoleError":
|
|
||||||
messageLevel = "ERROR"
|
|
||||||
break;
|
|
||||||
case "consoleInfo":
|
|
||||||
// on Android, console.info is LOG
|
|
||||||
messageLevel = "LOG"
|
|
||||||
break;
|
|
||||||
case "consoleWarn":
|
|
||||||
messageLevel = "WARNING"
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
messageLevel = "LOG"
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if navigationDelegate != nil {
|
|
||||||
navigationDelegate?.onConsoleMessage(uuid: self.uuid, sourceURL: "", lineNumber: 1, message: message.body as! String, messageLevel: messageLevel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if message.name == "resourceLoaded" && (webViewOptions?.useOnLoadResource)! {
|
|
||||||
if let resource = convertToDictionary(text: message.body as! String) {
|
|
||||||
let rawUrl = resource["name"] as! String
|
|
||||||
let encodedUrl = rawUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
|
|
||||||
let url = URL(string: encodedUrl)!
|
|
||||||
if !UIApplication.shared.canOpenURL(url) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let startTime = Int64(resource["startTime"] as! Double)
|
|
||||||
let duration = Int64(resource["duration"] as! Double)
|
|
||||||
var urlRequest = URLRequest(url: url)
|
|
||||||
urlRequest.allHTTPHeaderFields = [:]
|
|
||||||
let config = URLSessionConfiguration.default
|
|
||||||
let session = URLSession(configuration: config)
|
|
||||||
let task = session.dataTask(with: urlRequest) { (data, response, error) in
|
|
||||||
if error != nil {
|
|
||||||
print(error)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var withData = data
|
|
||||||
if withData == nil {
|
|
||||||
withData = Data()
|
|
||||||
}
|
|
||||||
self.didReceiveResourceResponse(response!, fromRequest: urlRequest, withData: withData!, startTime: startTime, duration: duration)
|
|
||||||
}
|
|
||||||
task.resume()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if message.name == "callHandler" {
|
|
||||||
let body = message.body as! [String: Any]
|
|
||||||
let handlerName = body["handlerName"] as! String
|
|
||||||
let args = body["args"] as! String
|
|
||||||
if navigationDelegate != nil {
|
|
||||||
self.navigationDelegate?.onCallJsHandler(uuid: self.uuid, webView: webView, handlerName: handlerName, args: args)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func takeScreenshot (completionHandler: @escaping (_ screenshot: Data?) -> Void) {
|
|
||||||
if #available(iOS 11.0, *) {
|
|
||||||
self.webView.takeSnapshot(with: nil, completionHandler: {(image, error) -> Void in
|
|
||||||
var imageData: Data? = nil
|
|
||||||
if let screenshot = image {
|
|
||||||
imageData = UIImagePNGRepresentation(screenshot)!
|
|
||||||
}
|
|
||||||
completionHandler(imageData)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
completionHandler(nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func setOptions(newOptions: InAppBrowserOptions, newOptionsMap: [String: Any]) {
|
func setOptions(newOptions: InAppBrowserOptions, newOptionsMap: [String: Any]) {
|
||||||
|
|
||||||
let newInAppWebViewOptions = InAppWebViewOptions()
|
let newInAppWebViewOptions = InAppWebViewOptions()
|
||||||
newInAppWebViewOptions.parse(options: newOptionsMap)
|
newInAppWebViewOptions.parse(options: newOptionsMap)
|
||||||
|
self.webView.setOptions(newOptions: newInAppWebViewOptions, newOptionsMap: newOptionsMap)
|
||||||
|
|
||||||
if newOptionsMap["hidden"] != nil && browserOptions?.hidden != newOptions.hidden {
|
if newOptionsMap["hidden"] != nil && browserOptions?.hidden != newOptions.hidden {
|
||||||
if newOptions.hidden {
|
if newOptions.hidden {
|
||||||
|
@ -854,135 +426,18 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
|
||||||
if newOptionsMap["transitionStyle"] != nil && browserOptions?.transitionStyle != newOptions.transitionStyle {
|
if newOptionsMap["transitionStyle"] != nil && browserOptions?.transitionStyle != newOptions.transitionStyle {
|
||||||
self.modalTransitionStyle = UIModalTransitionStyle(rawValue: newOptions.transitionStyle)!
|
self.modalTransitionStyle = UIModalTransitionStyle(rawValue: newOptions.transitionStyle)!
|
||||||
}
|
}
|
||||||
|
|
||||||
if newOptionsMap["disallowOverScroll"] != nil && webViewOptions?.disallowOverScroll != newInAppWebViewOptions.disallowOverScroll {
|
|
||||||
if self.webView.responds(to: #selector(getter: self.webView.scrollView)) {
|
|
||||||
self.webView.scrollView.bounces = !newInAppWebViewOptions.disallowOverScroll
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for subview: UIView in self.webView.subviews {
|
|
||||||
if subview is UIScrollView {
|
|
||||||
(subview as! UIScrollView).bounces = !newInAppWebViewOptions.disallowOverScroll
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if newOptionsMap["enableViewportScale"] != nil && webViewOptions?.enableViewportScale != newInAppWebViewOptions.enableViewportScale && newInAppWebViewOptions.enableViewportScale {
|
|
||||||
let jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"
|
|
||||||
self.webView.evaluateJavaScript(jscript, completionHandler: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
if newOptionsMap["mediaPlaybackRequiresUserGesture"] != nil && webViewOptions?.mediaPlaybackRequiresUserGesture != newInAppWebViewOptions.mediaPlaybackRequiresUserGesture {
|
|
||||||
if #available(iOS 10.0, *) {
|
|
||||||
self.webView.configuration.mediaTypesRequiringUserActionForPlayback = (newInAppWebViewOptions.mediaPlaybackRequiresUserGesture) ? .all : []
|
|
||||||
} else {
|
|
||||||
// Fallback on earlier versions
|
|
||||||
self.webView.configuration.mediaPlaybackRequiresUserAction = newInAppWebViewOptions.mediaPlaybackRequiresUserGesture
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if newOptionsMap["allowsInlineMediaPlayback"] != nil && webViewOptions?.allowsInlineMediaPlayback != newInAppWebViewOptions.allowsInlineMediaPlayback {
|
|
||||||
self.webView.configuration.allowsInlineMediaPlayback = newInAppWebViewOptions.allowsInlineMediaPlayback
|
|
||||||
}
|
|
||||||
|
|
||||||
// if newOptionsMap["keyboardDisplayRequiresUserAction"] != nil && browserOptions?.keyboardDisplayRequiresUserAction != newOptions.keyboardDisplayRequiresUserAction {
|
|
||||||
// self.webView.keyboardDisplayRequiresUserAction = newOptions.keyboardDisplayRequiresUserAction
|
|
||||||
// }
|
|
||||||
|
|
||||||
if newOptionsMap["suppressesIncrementalRendering"] != nil && webViewOptions?.suppressesIncrementalRendering != newInAppWebViewOptions.suppressesIncrementalRendering {
|
|
||||||
self.webView.configuration.suppressesIncrementalRendering = newInAppWebViewOptions.suppressesIncrementalRendering
|
|
||||||
}
|
|
||||||
|
|
||||||
if newOptionsMap["allowsBackForwardNavigationGestures"] != nil && webViewOptions?.allowsBackForwardNavigationGestures != newInAppWebViewOptions.allowsBackForwardNavigationGestures {
|
|
||||||
self.webView.allowsBackForwardNavigationGestures = newInAppWebViewOptions.allowsBackForwardNavigationGestures
|
|
||||||
}
|
|
||||||
|
|
||||||
if newOptionsMap["allowsLinkPreview"] != nil && webViewOptions?.allowsLinkPreview != newInAppWebViewOptions.allowsLinkPreview {
|
|
||||||
if #available(iOS 9.0, *) {
|
|
||||||
self.webView.allowsLinkPreview = newInAppWebViewOptions.allowsLinkPreview
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if newOptionsMap["ignoresViewportScaleLimits"] != nil && webViewOptions?.ignoresViewportScaleLimits != newInAppWebViewOptions.ignoresViewportScaleLimits {
|
|
||||||
if #available(iOS 10.0, *) {
|
|
||||||
self.webView.configuration.ignoresViewportScaleLimits = newInAppWebViewOptions.ignoresViewportScaleLimits
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if newOptionsMap["allowsInlineMediaPlayback"] != nil && webViewOptions?.allowsInlineMediaPlayback != newInAppWebViewOptions.allowsInlineMediaPlayback {
|
|
||||||
self.webView.configuration.allowsInlineMediaPlayback = newInAppWebViewOptions.allowsInlineMediaPlayback
|
|
||||||
}
|
|
||||||
|
|
||||||
if newOptionsMap["allowsPictureInPictureMediaPlayback"] != nil && webViewOptions?.allowsPictureInPictureMediaPlayback != newInAppWebViewOptions.allowsPictureInPictureMediaPlayback {
|
|
||||||
if #available(iOS 9.0, *) {
|
|
||||||
self.webView.configuration.allowsPictureInPictureMediaPlayback = newInAppWebViewOptions.allowsPictureInPictureMediaPlayback
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if newOptionsMap["javaScriptCanOpenWindowsAutomatically"] != nil && webViewOptions?.javaScriptCanOpenWindowsAutomatically != newInAppWebViewOptions.javaScriptCanOpenWindowsAutomatically {
|
|
||||||
self.webView.configuration.preferences.javaScriptCanOpenWindowsAutomatically = newInAppWebViewOptions.javaScriptCanOpenWindowsAutomatically
|
|
||||||
}
|
|
||||||
|
|
||||||
if newOptionsMap["javaScriptEnabled"] != nil && webViewOptions?.javaScriptEnabled != newInAppWebViewOptions.javaScriptEnabled {
|
|
||||||
self.webView.configuration.preferences.javaScriptEnabled = newInAppWebViewOptions.javaScriptEnabled
|
|
||||||
}
|
|
||||||
|
|
||||||
if newOptionsMap["userAgent"] != nil && webViewOptions?.userAgent != newInAppWebViewOptions.userAgent && (newInAppWebViewOptions.userAgent != "") {
|
|
||||||
if #available(iOS 9.0, *) {
|
|
||||||
self.webView.customUserAgent = newInAppWebViewOptions.userAgent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if newOptionsMap["clearCache"] != nil && newInAppWebViewOptions.clearCache {
|
|
||||||
clearCache()
|
|
||||||
}
|
|
||||||
|
|
||||||
self.browserOptions = newOptions
|
self.browserOptions = newOptions
|
||||||
self.webViewOptions = newInAppWebViewOptions
|
self.webViewOptions = newInAppWebViewOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
func getOptions() -> [String: Any]? {
|
func getOptions() -> [String: Any]? {
|
||||||
if (self.browserOptions == nil || self.webViewOptions == nil) {
|
if (self.browserOptions == nil || self.webView.getOptions() == nil) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var optionsMap = self.browserOptions!.getHashMap()
|
var optionsMap = self.browserOptions!.getHashMap()
|
||||||
optionsMap.merge(self.webViewOptions!.getHashMap(), uniquingKeysWith: { (current, _) in current })
|
optionsMap.merge(self.webView.getOptions()!, uniquingKeysWith: { (current, _) in current })
|
||||||
return optionsMap
|
return optionsMap
|
||||||
}
|
}
|
||||||
|
|
||||||
override func observeValue(forKeyPath keyPath: String?, of object: Any?,
|
|
||||||
change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
|
|
||||||
if keyPath == "estimatedProgress" {
|
|
||||||
let progress = Int(webView.estimatedProgress * 100)
|
|
||||||
self.navigationDelegate?.onProgressChanged(uuid: self.uuid, webView: self.webView, progress: progress)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getCopyBackForwardList() -> [String: Any] {
|
|
||||||
let currentList = self.webView.backForwardList
|
|
||||||
let currentIndex = currentList.backList.count
|
|
||||||
var completeList = currentList.backList
|
|
||||||
if currentList.currentItem != nil {
|
|
||||||
completeList.append(currentList.currentItem!)
|
|
||||||
}
|
|
||||||
completeList.append(contentsOf: currentList.forwardList)
|
|
||||||
|
|
||||||
var history: [[String: String]] = []
|
|
||||||
|
|
||||||
for historyItem in completeList {
|
|
||||||
var historyItemMap: [String: String] = [:]
|
|
||||||
historyItemMap["originalUrl"] = historyItem.initialURL.absoluteString
|
|
||||||
historyItemMap["title"] = historyItem.title
|
|
||||||
historyItemMap["url"] = historyItem.url.absoluteString
|
|
||||||
history.append(historyItemMap)
|
|
||||||
}
|
|
||||||
|
|
||||||
var result: [String: Any] = [:]
|
|
||||||
result["history"] = history
|
|
||||||
result["currentIndex"] = currentIndex
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,73 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
import WebKit
|
import WebKit
|
||||||
|
|
||||||
|
func currentTimeInMilliSeconds() -> Int64 {
|
||||||
|
let currentDate = Date()
|
||||||
|
let since1970 = currentDate.timeIntervalSince1970
|
||||||
|
return Int64(since1970 * 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertToDictionary(text: String) -> [String: Any]? {
|
||||||
|
if let data = text.data(using: .utf8) {
|
||||||
|
do {
|
||||||
|
return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
|
||||||
|
} catch {
|
||||||
|
print(error.localizedDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// the message needs to be concatenated with '' in order to have the same behavior like on Android
|
||||||
|
let consoleLogJS = """
|
||||||
|
(function() {
|
||||||
|
var oldLogs = {
|
||||||
|
'consoleLog': console.log,
|
||||||
|
'consoleDebug': console.debug,
|
||||||
|
'consoleError': console.error,
|
||||||
|
'consoleInfo': console.info,
|
||||||
|
'consoleWarn': console.warn
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var k in oldLogs) {
|
||||||
|
(function(oldLog) {
|
||||||
|
console[oldLog.replace('console', '').toLowerCase()] = function() {
|
||||||
|
var message = '';
|
||||||
|
for (var i in arguments) {
|
||||||
|
if (message == '') {
|
||||||
|
message += arguments[i];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
message += ' ' + arguments[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.webkit.messageHandlers[oldLog].postMessage(message);
|
||||||
|
}
|
||||||
|
})(k);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
"""
|
||||||
|
|
||||||
|
let resourceObserverJS = """
|
||||||
|
(function() {
|
||||||
|
var observer = new PerformanceObserver(function(list) {
|
||||||
|
list.getEntries().forEach(function(entry) {
|
||||||
|
window.webkit.messageHandlers['resourceLoaded'].postMessage(JSON.stringify(entry));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
observer.observe({entryTypes: ['resource', 'mark', 'measure']});
|
||||||
|
})();
|
||||||
|
"""
|
||||||
|
|
||||||
|
let JAVASCRIPT_BRIDGE_NAME = "flutter_inappbrowser"
|
||||||
|
|
||||||
|
let javaScriptBridgeJS = """
|
||||||
|
window.\(JAVASCRIPT_BRIDGE_NAME) = {};
|
||||||
|
window.\(JAVASCRIPT_BRIDGE_NAME).callHandler = function(handlerName, ...args) {
|
||||||
|
window.webkit.messageHandlers['callHandler'].postMessage( {'handlerName': handlerName, 'args': JSON.stringify(args)} );
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler {
|
public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler {
|
||||||
|
|
||||||
var IABController: InAppBrowserWebViewController?
|
var IABController: InAppBrowserWebViewController?
|
||||||
|
@ -87,7 +154,6 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
configuration.mediaPlaybackRequiresUserAction = (options?.mediaPlaybackRequiresUserGesture)!
|
configuration.mediaPlaybackRequiresUserAction = (options?.mediaPlaybackRequiresUserGesture)!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
configuration.allowsInlineMediaPlayback = (options?.allowsInlineMediaPlayback)!
|
configuration.allowsInlineMediaPlayback = (options?.allowsInlineMediaPlayback)!
|
||||||
|
|
||||||
//keyboardDisplayRequiresUserAction = browserOptions?.keyboardDisplayRequiresUserAction
|
//keyboardDisplayRequiresUserAction = browserOptions?.keyboardDisplayRequiresUserAction
|
||||||
|
@ -436,6 +502,9 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
|
|
||||||
if navigationAction.navigationType == .linkActivated || navigationAction.navigationType == .backForward {
|
if navigationAction.navigationType == .linkActivated || navigationAction.navigationType == .backForward {
|
||||||
currentURL = url
|
currentURL = url
|
||||||
|
if IABController != nil {
|
||||||
|
IABController!.updateUrlTextField(url: (currentURL?.absoluteString)!)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,14 +529,66 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
decisionHandler(.allow)
|
decisionHandler(.allow)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func webView(_ webView: WKWebView,
|
||||||
|
// decidePolicyFor navigationResponse: WKNavigationResponse,
|
||||||
|
// decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
|
||||||
|
// let mimeType = navigationResponse.response.mimeType
|
||||||
|
// if mimeType != nil && !mimeType!.starts(with: "text/") {
|
||||||
|
// download(url: webView.url)
|
||||||
|
// decisionHandler(.cancel)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// decisionHandler(.allow)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// func download (url: URL?) {
|
||||||
|
// let filename = url?.lastPathComponent
|
||||||
|
//
|
||||||
|
// let destination: DownloadRequest.DownloadFileDestination = { _, _ in
|
||||||
|
// let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
|
||||||
|
// let fileURL = documentsURL.appendingPathComponent(filename!)
|
||||||
|
//
|
||||||
|
// return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Alamofire.download((url?.absoluteString)!, to: destination).downloadProgress { progress in
|
||||||
|
// print("Download Progress: \(progress.fractionCompleted)")
|
||||||
|
// }.response { response in
|
||||||
|
// if response.error == nil, let path = response.destinationURL?.path {
|
||||||
|
// UIAlertView(title: nil, message: "File saved to " + path, delegate: nil, cancelButtonTitle: nil).show()
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// UIAlertView(title: nil, message: "Cannot save " + filename!, delegate: nil, cancelButtonTitle: nil).show()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
public func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
|
public func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
|
||||||
self.startPageTime = currentTimeInMilliSeconds()
|
self.startPageTime = currentTimeInMilliSeconds()
|
||||||
onLoadStart(url: (currentURL?.absoluteString)!)
|
onLoadStart(url: (currentURL?.absoluteString)!)
|
||||||
|
|
||||||
|
if IABController != nil {
|
||||||
|
// loading url, start spinner, update back/forward
|
||||||
|
IABController!.backButton.isEnabled = canGoBack
|
||||||
|
IABController!.forwardButton.isEnabled = canGoForward
|
||||||
|
|
||||||
|
if (IABController!.browserOptions?.spinner)! {
|
||||||
|
IABController!.spinner.startAnimating()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
||||||
self.WKNavigationMap = [:]
|
self.WKNavigationMap = [:]
|
||||||
onLoadStop(url: (url?.absoluteString)!)
|
currentURL = url
|
||||||
|
onLoadStop(url: (currentURL?.absoluteString)!)
|
||||||
|
|
||||||
|
if IABController != nil {
|
||||||
|
IABController!.updateUrlTextField(url: (currentURL?.absoluteString)!)
|
||||||
|
IABController!.backButton.isEnabled = canGoBack
|
||||||
|
IABController!.forwardButton.isEnabled = canGoForward
|
||||||
|
IABController!.spinner.stopAnimating()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func webView(_ view: WKWebView,
|
public func webView(_ view: WKWebView,
|
||||||
|
@ -478,6 +599,12 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
|
|
||||||
public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
|
public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
|
||||||
onLoadError(url: (currentURL?.absoluteString)!, error: error)
|
onLoadError(url: (currentURL?.absoluteString)!, error: error)
|
||||||
|
|
||||||
|
if IABController != nil {
|
||||||
|
IABController!.backButton.isEnabled = canGoBack
|
||||||
|
IABController!.forwardButton.isEnabled = canGoForward
|
||||||
|
IABController!.spinner.stopAnimating()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||||
|
@ -609,7 +736,10 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
}
|
}
|
||||||
else if message.name == "resourceLoaded" && (options?.useOnLoadResource)! {
|
else if message.name == "resourceLoaded" && (options?.useOnLoadResource)! {
|
||||||
if let resource = convertToDictionary(text: message.body as! String) {
|
if let resource = convertToDictionary(text: message.body as! String) {
|
||||||
let url = URL(string: resource["name"] as! String)!
|
// escape special chars
|
||||||
|
let resourceName = (resource["name"] as! String).addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)
|
||||||
|
|
||||||
|
let url = URL(string: resourceName!)!
|
||||||
if !UIApplication.shared.canOpenURL(url) {
|
if !UIApplication.shared.canOpenURL(url) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,7 +211,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
||||||
break
|
break
|
||||||
case "takeScreenshot":
|
case "takeScreenshot":
|
||||||
if let webViewController = self.webViewControllers[uuid] {
|
if let webViewController = self.webViewControllers[uuid] {
|
||||||
webViewController!.takeScreenshot(completionHandler: { (screenshot) -> Void in
|
webViewController!.webView.takeScreenshot(completionHandler: { (screenshot) -> Void in
|
||||||
result(screenshot)
|
result(screenshot)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -420,7 +420,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
||||||
webViewController.webViewOptions = webViewOptions
|
webViewController.webViewOptions = webViewOptions
|
||||||
webViewController.isHidden = browserOptions.hidden
|
webViewController.isHidden = browserOptions.hidden
|
||||||
webViewController.tmpWindow = tmpWindow
|
webViewController.tmpWindow = tmpWindow
|
||||||
webViewController.currentURL = url
|
webViewController.initURL = url
|
||||||
webViewController.initHeaders = headers
|
webViewController.initHeaders = headers
|
||||||
webViewController.navigationDelegate = self
|
webViewController.navigationDelegate = self
|
||||||
|
|
||||||
|
@ -708,21 +708,21 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
||||||
|
|
||||||
func onLoadStart(uuid: String, webView: WKWebView) {
|
func onLoadStart(uuid: String, webView: WKWebView) {
|
||||||
if let webViewController = self.webViewControllers[uuid] {
|
if let webViewController = self.webViewControllers[uuid] {
|
||||||
let url: String = webViewController!.currentURL!.absoluteString
|
let url: String = webViewController!.webView.currentURL!.absoluteString
|
||||||
SwiftFlutterPlugin.channel!.invokeMethod("onLoadStart", arguments: ["uuid": uuid, "url": url])
|
SwiftFlutterPlugin.channel!.invokeMethod("onLoadStart", arguments: ["uuid": uuid, "url": url])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func onLoadStop(uuid: String, webView: WKWebView) {
|
func onLoadStop(uuid: String, webView: WKWebView) {
|
||||||
if let webViewController = self.webViewControllers[uuid] {
|
if let webViewController = self.webViewControllers[uuid] {
|
||||||
let url: String = webViewController!.currentURL!.absoluteString
|
let url: String = webViewController!.webView.currentURL!.absoluteString
|
||||||
SwiftFlutterPlugin.channel!.invokeMethod("onLoadStop", arguments: ["uuid": uuid, "url": url])
|
SwiftFlutterPlugin.channel!.invokeMethod("onLoadStop", arguments: ["uuid": uuid, "url": url])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func onLoadError(uuid: String, webView: WKWebView, error: Error) {
|
func onLoadError(uuid: String, webView: WKWebView, error: Error) {
|
||||||
if let webViewController = self.webViewControllers[uuid] {
|
if let webViewController = self.webViewControllers[uuid] {
|
||||||
let url: String = webViewController!.currentURL!.absoluteString
|
let url: String = webViewController!.webView.currentURL!.absoluteString
|
||||||
let arguments = ["uuid": uuid, "url": url, "code": error._code, "message": error.localizedDescription] as [String : Any]
|
let arguments = ["uuid": uuid, "url": url, "code": error._code, "message": error.localizedDescription] as [String : Any]
|
||||||
SwiftFlutterPlugin.channel!.invokeMethod("onLoadError", arguments: arguments)
|
SwiftFlutterPlugin.channel!.invokeMethod("onLoadError", arguments: arguments)
|
||||||
}
|
}
|
||||||
|
@ -846,7 +846,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
||||||
|
|
||||||
func getCopyBackForwardList(uuid: String) -> [String: Any]? {
|
func getCopyBackForwardList(uuid: String) -> [String: Any]? {
|
||||||
if let webViewController = self.webViewControllers[uuid] {
|
if let webViewController = self.webViewControllers[uuid] {
|
||||||
return webViewController!.getCopyBackForwardList()
|
return webViewController!.webView.getCopyBackForwardList()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name: flutter_inappbrowser
|
name: flutter_inappbrowser
|
||||||
description: A Flutter plugin that allows you to add an inline webview or open an in-app browser window (inspired by the popular cordova-plugin-inappbrowser).
|
description: A Flutter plugin that allows you to add an inline webview or open an in-app browser window (inspired by the popular cordova-plugin-inappbrowser).
|
||||||
version: 0.5.51
|
version: 0.6.0
|
||||||
author: Lorenzo Pichilli <pichillilorenzo@gmail.com>
|
author: Lorenzo Pichilli <pichillilorenzo@gmail.com>
|
||||||
homepage: https://github.com/pichillilorenzo/flutter_inappbrowser
|
homepage: https://github.com/pichillilorenzo/flutter_inappbrowser
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ environment:
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
uuid: ^1.0.3
|
uuid: ^2.0.0
|
||||||
mime: ^0.9.6+2
|
mime: ^0.9.6+2
|
||||||
|
|
||||||
# For information on the generic Dart part of this file, see the
|
# For information on the generic Dart part of this file, see the
|
||||||
|
|
Loading…
Reference in New Issue