Merge branch 'master' into master
This commit is contained in:
commit
971ac889f9
|
@ -1,6 +1,5 @@
|
||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="example/lib/main.dart" type="FlutterRunConfigurationType" factoryName="Flutter" singleton="false">
|
<configuration default="false" name="example/lib/main.dart" type="FlutterRunConfigurationType" factoryName="Flutter" singleton="false">
|
||||||
<option name="additionalArgs" value="--debug" />
|
|
||||||
<option name="filePath" value="$PROJECT_DIR$/example/lib/main.dart" />
|
<option name="filePath" value="$PROJECT_DIR$/example/lib/main.dart" />
|
||||||
<method v="2" />
|
<method v="2" />
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
|
@ -15,35 +15,16 @@
|
||||||
</component>
|
</component>
|
||||||
<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 afterPath="$PROJECT_DIR$/.idea/codeStyles/codeStyleConfig.xml" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/lib/t_rex_runner/t-rex.css" afterDir="false" />
|
|
||||||
<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$/CHANGELOG.md" beforeDir="false" afterPath="$PROJECT_DIR$/CHANGELOG.md" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/CHANGELOG.md" beforeDir="false" afterPath="$PROJECT_DIR$/CHANGELOG.md" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/ContentBlocker/ContentBlockerHandler.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/ContentBlocker/ContentBlockerHandler.java" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebView.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebView.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebView.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebView.java" 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$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebViewOptions.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebViewOptions.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/example/assets/index.html" beforeDir="false" afterPath="$PROJECT_DIR$/example/assets/index.html" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/example/ios/Podfile" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/Podfile" 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/chrome_safari_example.screen.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/lib/chrome_safari_example.screen.dart" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/example/lib/inline_example.screen.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/lib/inline_example.screen.dart" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/example/lib/inline_example.screen.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/lib/inline_example.screen.dart" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/example/lib/test.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/lib/test.dart" 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$/example/pubspec.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/example/pubspec.yaml" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/ios/Classes/CustomeSchemeHandler.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/CustomeSchemeHandler.swift" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/ios/Classes/FlutterWebViewController.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/FlutterWebViewController.swift" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/ios/Classes/FlutterWebViewController.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/FlutterWebViewController.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/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$/ios/Classes/InAppWebViewOptions.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/InAppWebViewOptions.swift" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/ios/flutter_inappbrowser.podspec" beforeDir="false" afterPath="$PROJECT_DIR$/ios/flutter_inappbrowser.podspec" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/lib/src/chrome_safari_browser.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/src/chrome_safari_browser.dart" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/lib/src/content_blocker.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/src/content_blocker.dart" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/lib/src/in_app_browser.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/src/in_app_browser.dart" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/lib/src/in_app_localhost_server.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/src/in_app_localhost_server.dart" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/lib/src/in_app_webview.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/src/in_app_webview.dart" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/lib/src/in_app_webview.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/src/in_app_webview.dart" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/lib/src/types.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/src/types.dart" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/lib/src/webview_options.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/src/webview_options.dart" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/lib/src/webview_options.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/src/webview_options.dart" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/nodejs_server_test_auth_basic_and_ssl/index.js" beforeDir="false" afterPath="$PROJECT_DIR$/nodejs_server_test_auth_basic_and_ssl/index.js" 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/" />
|
||||||
|
@ -66,8 +47,8 @@
|
||||||
<file pinned="false" current-in-tab="false">
|
<file pinned="false" current-in-tab="false">
|
||||||
<entry file="file://$PROJECT_DIR$/lib/src/in_app_webview.dart">
|
<entry file="file://$PROJECT_DIR$/lib/src/in_app_webview.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="251">
|
<state relative-caret-position="143">
|
||||||
<caret line="265" column="89" selection-start-line="261" selection-start-column="4" selection-end-line="265" selection-end-column="89" />
|
<caret line="336" column="42" selection-start-line="336" selection-start-column="42" selection-end-line="336" selection-end-column="42" />
|
||||||
<folding>
|
<folding>
|
||||||
<element signature="e#0#17#0" expanded="true" />
|
<element signature="e#0#17#0" expanded="true" />
|
||||||
</folding>
|
</folding>
|
||||||
|
@ -76,10 +57,10 @@
|
||||||
</entry>
|
</entry>
|
||||||
</file>
|
</file>
|
||||||
<file pinned="false" current-in-tab="false">
|
<file pinned="false" current-in-tab="false">
|
||||||
<entry file="file://$PROJECT_DIR$/example/lib/inline_example.screen.dart">
|
<entry file="file://$PROJECT_DIR$/lib/src/in_app_browser.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="28">
|
<state relative-caret-position="520">
|
||||||
<caret line="94" column="32" selection-start-line="94" selection-start-column="16" selection-end-line="94" selection-end-column="32" />
|
<caret line="511" column="30" selection-start-line="511" selection-start-column="7" selection-end-line="511" selection-end-column="30" />
|
||||||
<folding>
|
<folding>
|
||||||
<element signature="e#0#20#0" expanded="true" />
|
<element signature="e#0#20#0" expanded="true" />
|
||||||
</folding>
|
</folding>
|
||||||
|
@ -88,10 +69,13 @@
|
||||||
</entry>
|
</entry>
|
||||||
</file>
|
</file>
|
||||||
<file pinned="false" current-in-tab="false">
|
<file pinned="false" current-in-tab="false">
|
||||||
<entry file="file://$PROJECT_DIR$/example/pubspec.yaml">
|
<entry file="file://$PROJECT_DIR$/lib/src/types.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="131">
|
<state relative-caret-position="332">
|
||||||
<caret line="24" column="27" selection-start-line="24" selection-start-column="27" selection-end-line="24" selection-end-column="27" />
|
<caret line="482" column="6" selection-start-line="482" selection-start-column="6" selection-end-line="482" selection-end-column="6" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#20#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
|
@ -99,8 +83,8 @@
|
||||||
<file pinned="false" current-in-tab="true">
|
<file pinned="false" current-in-tab="true">
|
||||||
<entry file="file://$PROJECT_DIR$/lib/src/webview_options.dart">
|
<entry file="file://$PROJECT_DIR$/lib/src/webview_options.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="364">
|
<state relative-caret-position="-250">
|
||||||
<caret line="81" column="43" selection-start-line="81" selection-start-column="43" selection-end-line="81" selection-end-column="43" />
|
<caret line="347" column="93" selection-start-line="347" selection-start-column="93" selection-end-line="347" selection-end-column="93" />
|
||||||
<folding>
|
<folding>
|
||||||
<element signature="e#0#17#0" expanded="true" />
|
<element signature="e#0#17#0" expanded="true" />
|
||||||
</folding>
|
</folding>
|
||||||
|
@ -108,6 +92,45 @@
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
</file>
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/example/assets/index.html">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="1005">
|
||||||
|
<caret line="67" column="37" selection-start-line="67" selection-start-column="37" selection-end-line="67" selection-end-column="37" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/nodejs_server_test_auth_basic_and_ssl/index.js">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="1905">
|
||||||
|
<caret line="127" column="25" selection-start-line="127" selection-start-column="10" selection-end-line="127" selection-end-column="25" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/example/lib/inline_example.screen.dart">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="207">
|
||||||
|
<caret line="295" column="18" selection-start-line="295" selection-start-column="18" selection-end-line="295" selection-end-column="18" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#20#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="173">
|
||||||
|
<caret line="16" column="681" selection-start-line="16" selection-start-column="661" selection-end-line="16" selection-end-column="681" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
</leaf>
|
</leaf>
|
||||||
</component>
|
</component>
|
||||||
<component name="FileTemplateManagerImpl">
|
<component name="FileTemplateManagerImpl">
|
||||||
|
@ -120,36 +143,36 @@
|
||||||
</component>
|
</component>
|
||||||
<component name="FindInProjectRecents">
|
<component name="FindInProjectRecents">
|
||||||
<findStrings>
|
<findStrings>
|
||||||
<find>toggleErrorInformationPopup</find>
|
<find>injectScriptUrlFile</find>
|
||||||
<find>error-information-popup-container</find>
|
<find>[InAppWebView] window</find>
|
||||||
<find>offline-spri</find>
|
<find>javaScriptEnabled</find>
|
||||||
<find>sprite</find>
|
<find>onLoadRes</find>
|
||||||
<find>icon-offline</find>
|
<find>onLoadResource</find>
|
||||||
<find>ICON</find>
|
<find>onLoadResource"</find>
|
||||||
<find>loadImages</find>
|
<find>javaScriptHandlersMap</find>
|
||||||
<find>RESOURCE_TEMPLATE_ID</find>
|
<find>javaScriptHandlers</find>
|
||||||
<find>adjustDimensions</find>
|
<find>onAjaxSend</find>
|
||||||
<find>outerContainerEl</find>
|
<find>Action</find>
|
||||||
<find>ontouch</find>
|
<find>AjaxRequestEventType</find>
|
||||||
<find>fromVa</find>
|
<find>onAjax</find>
|
||||||
<find>ContentBlockerActionType</find>
|
<find>onAjaxReadyStateChange</find>
|
||||||
<find>getOptions</find>
|
<find>onAjaxEvent</find>
|
||||||
<find>iOS</find>
|
<find>shouldInterceptAjaxRequest</find>
|
||||||
<find>Ios</find>
|
<find>onAjaxProgress</find>
|
||||||
<find>initialOptions</find>
|
<find>onAjaxReady</find>
|
||||||
<find>initialOpti</find>
|
<find>NAVIGATION</find>
|
||||||
<find>Platform</find>
|
<find>onNavigationStateChange</find>
|
||||||
<find>Platform.i</find>
|
<find>shouldInterceptFetchRequest</find>
|
||||||
<find>getOption</find>
|
<find>scheme</find>
|
||||||
<find>.toValue</find>
|
<find>applicationNameForUserAgent</find>
|
||||||
<find>fromValue(</find>
|
<find>cacheMOde</find>
|
||||||
<find>?.toMap());</find>
|
<find>inco</find>
|
||||||
<find>fromMap</find>
|
<find>cacheEna</find>
|
||||||
<find>setOptions</find>
|
<find>appCacheEnabled</find>
|
||||||
<find>fromValue</find>
|
<find>appC</find>
|
||||||
<find>List<</find>
|
<find>cache</find>
|
||||||
<find>debuggingEnabled</find>
|
<find>customScheme</find>
|
||||||
<find>initialOp</find>
|
<find>transparentBackground</find>
|
||||||
</findStrings>
|
</findStrings>
|
||||||
<replaceStrings>
|
<replaceStrings>
|
||||||
<replace>activity.getPreferences(0)</replace>
|
<replace>activity.getPreferences(0)</replace>
|
||||||
|
@ -160,6 +183,8 @@
|
||||||
<replace>ChannelManager</replace>
|
<replace>ChannelManager</replace>
|
||||||
<replace>Function</replace>
|
<replace>Function</replace>
|
||||||
<replace>?.toMap() ?? {});</replace>
|
<replace>?.toMap() ?? {});</replace>
|
||||||
|
<replace>javascriptEnabled</replace>
|
||||||
|
<replace>[InAppWebView]\</replace>
|
||||||
</replaceStrings>
|
</replaceStrings>
|
||||||
<dirStrings>
|
<dirStrings>
|
||||||
<dir>$PROJECT_DIR$/example/android</dir>
|
<dir>$PROJECT_DIR$/example/android</dir>
|
||||||
|
@ -199,35 +224,35 @@
|
||||||
<option value="$PROJECT_DIR$/example/lib/main.dart" />
|
<option value="$PROJECT_DIR$/example/lib/main.dart" />
|
||||||
<option value="$PROJECT_DIR$/lib/src/credentials_database.dart" />
|
<option value="$PROJECT_DIR$/lib/src/credentials_database.dart" />
|
||||||
<option value="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" />
|
<option value="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" />
|
||||||
<option value="$PROJECT_DIR$/ios/flutter_inappbrowser.podspec" />
|
|
||||||
<option value="$PROJECT_DIR$/lib/src/channel_manager.dart" />
|
<option value="$PROJECT_DIR$/lib/src/channel_manager.dart" />
|
||||||
<option value="$PROJECT_DIR$/lib/src/cookie_manager.dart" />
|
<option value="$PROJECT_DIR$/lib/src/cookie_manager.dart" />
|
||||||
<option value="$PROJECT_DIR$/lib/src/http_auth_credentials_database.dart" />
|
<option value="$PROJECT_DIR$/lib/src/http_auth_credentials_database.dart" />
|
||||||
<option value="$PROJECT_DIR$/android/build.gradle" />
|
<option value="$PROJECT_DIR$/android/build.gradle" />
|
||||||
<option value="$PROJECT_DIR$/nodejs_server_test_auth_basic_and_ssl/index.js" />
|
|
||||||
<option value="$PROJECT_DIR$/example/assets/index.html" />
|
|
||||||
<option value="$PROJECT_DIR$/lib/t_rex_runner/index.js" />
|
<option value="$PROJECT_DIR$/lib/t_rex_runner/index.js" />
|
||||||
<option value="$PROJECT_DIR$/lib/t_rex_runner/index.css" />
|
<option value="$PROJECT_DIR$/lib/t_rex_runner/index.css" />
|
||||||
<option value="$PROJECT_DIR$/lib/t_rex_runner/index.html" />
|
<option value="$PROJECT_DIR$/lib/t_rex_runner/index.html" />
|
||||||
<option value="$PROJECT_DIR$/lib/t_rex_runner/t-rex.html" />
|
<option value="$PROJECT_DIR$/lib/t_rex_runner/t-rex.html" />
|
||||||
<option value="$PROJECT_DIR$/pubspec.yaml" />
|
<option value="$PROJECT_DIR$/pubspec.yaml" />
|
||||||
<option value="$PROJECT_DIR$/lib/t_rex_runner/t-rex.css" />
|
<option value="$PROJECT_DIR$/lib/t_rex_runner/t-rex.css" />
|
||||||
<option value="$PROJECT_DIR$/CHANGELOG.md" />
|
|
||||||
<option value="$PROJECT_DIR$/example/lib/test.dart" />
|
<option value="$PROJECT_DIR$/example/lib/test.dart" />
|
||||||
<option value="$PROJECT_DIR$/example/lib/webview_example.screen.dart" />
|
<option value="$PROJECT_DIR$/example/lib/webview_example.screen.dart" />
|
||||||
<option value="$PROJECT_DIR$/lib/src/content_blocker.dart" />
|
<option value="$PROJECT_DIR$/lib/src/content_blocker.dart" />
|
||||||
<option value="$PROJECT_DIR$/lib/src/types.dart" />
|
|
||||||
<option value="$PROJECT_DIR$/lib/src/in_app_webview.dart" />
|
|
||||||
<option value="$PROJECT_DIR$/lib/src/in_app_browser.dart" />
|
|
||||||
<option value="$PROJECT_DIR$/lib/src/chrome_safari_browser.dart" />
|
<option value="$PROJECT_DIR$/lib/src/chrome_safari_browser.dart" />
|
||||||
<option value="$PROJECT_DIR$/example/lib/chrome_safari_example.screen.dart" />
|
<option value="$PROJECT_DIR$/example/lib/chrome_safari_example.screen.dart" />
|
||||||
<option value="$PROJECT_DIR$/example/pubspec.yaml" />
|
<option value="$PROJECT_DIR$/example/pubspec.yaml" />
|
||||||
|
<option value="$PROJECT_DIR$/ios/flutter_inappbrowser.podspec" />
|
||||||
|
<option value="$PROJECT_DIR$/nodejs_server_test_auth_basic_and_ssl/index.js" />
|
||||||
|
<option value="$PROJECT_DIR$/lib/src/in_app_browser.dart" />
|
||||||
|
<option value="$PROJECT_DIR$/lib/src/types.dart" />
|
||||||
|
<option value="$PROJECT_DIR$/example/assets/index.html" />
|
||||||
|
<option value="$PROJECT_DIR$/CHANGELOG.md" />
|
||||||
<option value="$PROJECT_DIR$/example/lib/inline_example.screen.dart" />
|
<option value="$PROJECT_DIR$/example/lib/inline_example.screen.dart" />
|
||||||
|
<option value="$PROJECT_DIR$/lib/src/in_app_webview.dart" />
|
||||||
<option value="$PROJECT_DIR$/lib/src/webview_options.dart" />
|
<option value="$PROJECT_DIR$/lib/src/webview_options.dart" />
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectFrameBounds">
|
<component name="ProjectFrameBounds" extendedState="6">
|
||||||
<option name="y" value="23" />
|
<option name="y" value="23" />
|
||||||
<option name="width" value="1920" />
|
<option name="width" value="1920" />
|
||||||
<option name="height" value="1057" />
|
<option name="height" value="1057" />
|
||||||
|
@ -238,6 +263,55 @@
|
||||||
<foldersAlwaysOnTop value="true" />
|
<foldersAlwaysOnTop value="true" />
|
||||||
</navigator>
|
</navigator>
|
||||||
<panes>
|
<panes>
|
||||||
|
<pane id="Scope">
|
||||||
|
<subPane subId="Project Files">
|
||||||
|
<expand>
|
||||||
|
<path>
|
||||||
|
<item name="Root" type="cbb8eebc:String" user="Root" />
|
||||||
|
<item name="flutter_inappbrowser" type="cbb8eebc:String" user="flutter_inappbrowser" />
|
||||||
|
</path>
|
||||||
|
</expand>
|
||||||
|
<select />
|
||||||
|
</subPane>
|
||||||
|
</pane>
|
||||||
|
<pane id="ProjectPane">
|
||||||
|
<subPane>
|
||||||
|
<expand>
|
||||||
|
<path>
|
||||||
|
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||||
|
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||||
|
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||||
|
<item name="lib" type="462c0819:PsiDirectoryNode" />
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||||
|
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||||
|
<item name="lib" type="462c0819:PsiDirectoryNode" />
|
||||||
|
<item name="src" type="462c0819:PsiDirectoryNode" />
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||||
|
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||||
|
<item name="lib" type="462c0819:PsiDirectoryNode" />
|
||||||
|
<item name="t_rex_runner" type="462c0819:PsiDirectoryNode" />
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||||
|
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||||
|
<item name="nodejs_server_test_auth_basic_and_ssl" type="462c0819:PsiDirectoryNode" />
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||||
|
<item name="External Libraries" type="cb654da1:ExternalLibrariesNode" />
|
||||||
|
</path>
|
||||||
|
</expand>
|
||||||
|
<select />
|
||||||
|
</subPane>
|
||||||
|
</pane>
|
||||||
|
<pane id="PackagesPane" />
|
||||||
<pane id="AndroidView">
|
<pane id="AndroidView">
|
||||||
<subPane>
|
<subPane>
|
||||||
<expand>
|
<expand>
|
||||||
|
@ -267,61 +341,6 @@
|
||||||
<select />
|
<select />
|
||||||
</subPane>
|
</subPane>
|
||||||
</pane>
|
</pane>
|
||||||
<pane id="PackagesPane" />
|
|
||||||
<pane id="ProjectPane">
|
|
||||||
<subPane>
|
|
||||||
<expand>
|
|
||||||
<path>
|
|
||||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
|
||||||
<item name="flutter_inappbrowser" 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" />
|
|
||||||
</path>
|
|
||||||
<path>
|
|
||||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
|
||||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
|
||||||
<item name="example" type="462c0819:PsiDirectoryNode" />
|
|
||||||
<item name="lib" type="462c0819:PsiDirectoryNode" />
|
|
||||||
</path>
|
|
||||||
<path>
|
|
||||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
|
||||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
|
||||||
<item name="lib" type="462c0819:PsiDirectoryNode" />
|
|
||||||
</path>
|
|
||||||
<path>
|
|
||||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
|
||||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
|
||||||
<item name="lib" type="462c0819:PsiDirectoryNode" />
|
|
||||||
<item name="src" type="462c0819:PsiDirectoryNode" />
|
|
||||||
</path>
|
|
||||||
<path>
|
|
||||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
|
||||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
|
||||||
<item name="lib" type="462c0819:PsiDirectoryNode" />
|
|
||||||
<item name="t_rex_runner" type="462c0819:PsiDirectoryNode" />
|
|
||||||
</path>
|
|
||||||
<path>
|
|
||||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
|
||||||
<item name="External Libraries" type="cb654da1:ExternalLibrariesNode" />
|
|
||||||
</path>
|
|
||||||
</expand>
|
|
||||||
<select />
|
|
||||||
</subPane>
|
|
||||||
</pane>
|
|
||||||
<pane id="Scope">
|
|
||||||
<subPane subId="Project Files">
|
|
||||||
<expand>
|
|
||||||
<path>
|
|
||||||
<item name="Root" type="cbb8eebc:String" user="Root" />
|
|
||||||
<item name="flutter_inappbrowser" type="cbb8eebc:String" user="flutter_inappbrowser" />
|
|
||||||
</path>
|
|
||||||
</expand>
|
|
||||||
<select />
|
|
||||||
</subPane>
|
|
||||||
</pane>
|
|
||||||
</panes>
|
</panes>
|
||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent">
|
<component name="PropertiesComponent">
|
||||||
|
@ -341,13 +360,6 @@
|
||||||
<property name="show.migrate.to.gradle.popup" value="false" />
|
<property name="show.migrate.to.gradle.popup" value="false" />
|
||||||
</component>
|
</component>
|
||||||
<component name="RecentsManager">
|
<component name="RecentsManager">
|
||||||
<key name="MoveFile.RECENT_KEYS">
|
|
||||||
<recent name="$PROJECT_DIR$/lib" />
|
|
||||||
<recent name="$PROJECT_DIR$/example/assets" />
|
|
||||||
<recent name="$PROJECT_DIR$/lib/src" />
|
|
||||||
<recent name="$PROJECT_DIR$/lib/in_app_browser.dart" />
|
|
||||||
<recent name="$PROJECT_DIR$/example/assets/images" />
|
|
||||||
</key>
|
|
||||||
<key name="CopyFile.RECENT_KEYS">
|
<key name="CopyFile.RECENT_KEYS">
|
||||||
<recent name="$PROJECT_DIR$/example/assets" />
|
<recent name="$PROJECT_DIR$/example/assets" />
|
||||||
<recent name="$PROJECT_DIR$" />
|
<recent name="$PROJECT_DIR$" />
|
||||||
|
@ -355,6 +367,13 @@
|
||||||
<recent name="$PROJECT_DIR$/example/assets/images" />
|
<recent name="$PROJECT_DIR$/example/assets/images" />
|
||||||
<recent name="$PROJECT_DIR$/android/libs" />
|
<recent name="$PROJECT_DIR$/android/libs" />
|
||||||
</key>
|
</key>
|
||||||
|
<key name="MoveFile.RECENT_KEYS">
|
||||||
|
<recent name="$PROJECT_DIR$/nodejs_server_test_auth_basic_and_ssl/assets" />
|
||||||
|
<recent name="$PROJECT_DIR$/lib" />
|
||||||
|
<recent name="$PROJECT_DIR$/example/assets" />
|
||||||
|
<recent name="$PROJECT_DIR$/lib/src" />
|
||||||
|
<recent name="$PROJECT_DIR$/lib/in_app_browser.dart" />
|
||||||
|
</key>
|
||||||
</component>
|
</component>
|
||||||
<component name="RunDashboard">
|
<component name="RunDashboard">
|
||||||
<option name="ruleStates">
|
<option name="ruleStates">
|
||||||
|
@ -472,7 +491,7 @@
|
||||||
</todo-panel>
|
</todo-panel>
|
||||||
</component>
|
</component>
|
||||||
<component name="ToolWindowManager">
|
<component name="ToolWindowManager">
|
||||||
<frame x="0" y="23" width="1920" height="1057" extended-state="0" />
|
<frame x="0" y="23" width="1920" height="1057" extended-state="6" />
|
||||||
<editor active="true" />
|
<editor active="true" />
|
||||||
<layout>
|
<layout>
|
||||||
<window_info content_ui="combo" id="Project" order="0" sideWeight="0.6529745" visible="true" weight="0.15867944" />
|
<window_info content_ui="combo" id="Project" order="0" sideWeight="0.6529745" visible="true" weight="0.15867944" />
|
||||||
|
@ -486,7 +505,7 @@
|
||||||
<window_info id="Resources Explorer" order="8" />
|
<window_info id="Resources Explorer" order="8" />
|
||||||
<window_info anchor="bottom" id="Message" order="0" />
|
<window_info anchor="bottom" id="Message" order="0" />
|
||||||
<window_info anchor="bottom" id="Find" order="1" weight="0.32642487" />
|
<window_info anchor="bottom" id="Find" order="1" weight="0.32642487" />
|
||||||
<window_info active="true" anchor="bottom" id="Run" order="2" sideWeight="0.49574015" visible="true" weight="0.5160622" />
|
<window_info active="true" anchor="bottom" id="Run" order="2" sideWeight="0.49574015" visible="true" weight="0.29326424" />
|
||||||
<window_info anchor="bottom" id="Debug" order="3" weight="0.34196892" />
|
<window_info anchor="bottom" id="Debug" order="3" weight="0.34196892" />
|
||||||
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
|
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
|
||||||
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
||||||
|
@ -494,10 +513,10 @@
|
||||||
<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="Event Log" order="8" sideWeight="0.50692225" side_tool="true" weight="0.38445595" />
|
<window_info anchor="bottom" id="Event Log" order="8" sideWeight="0.50692225" side_tool="true" weight="0.38445595" />
|
||||||
<window_info anchor="bottom" id="Version Control" order="9" weight="0.32953367" />
|
<window_info anchor="bottom" id="Version Control" order="9" weight="0.32953367" />
|
||||||
<window_info anchor="bottom" id="Terminal" order="10" sideWeight="0.49533224" weight="0.34507772" />
|
<window_info anchor="bottom" id="Terminal" order="10" sideWeight="0.49533224" weight="0.3896373" />
|
||||||
<window_info anchor="bottom" id="Logcat" order="11" weight="0.32953367" />
|
<window_info anchor="bottom" id="Messages" order="11" weight="0.3253886" />
|
||||||
<window_info anchor="bottom" id="Messages" order="12" weight="0.3253886" />
|
<window_info anchor="bottom" id="Dependency Viewer" order="12" weight="0.32800853" />
|
||||||
<window_info anchor="bottom" id="Dependency Viewer" order="13" weight="0.32800853" />
|
<window_info anchor="bottom" id="Logcat" order="13" weight="0.32953367" />
|
||||||
<window_info anchor="bottom" id="Dart Analysis" order="14" sideWeight="0.4968051" weight="0.3253886" />
|
<window_info anchor="bottom" id="Dart Analysis" order="14" sideWeight="0.4968051" weight="0.3253886" />
|
||||||
<window_info anchor="bottom" id="Flutter Performance" order="15" sideWeight="0.5042598" side_tool="true" weight="0.5160622" />
|
<window_info anchor="bottom" id="Flutter Performance" order="15" sideWeight="0.5042598" side_tool="true" weight="0.5160622" />
|
||||||
<window_info anchor="bottom" id="Build" order="16" />
|
<window_info anchor="bottom" id="Build" order="16" />
|
||||||
|
@ -524,25 +543,11 @@
|
||||||
</ignored-roots>
|
</ignored-roots>
|
||||||
</component>
|
</component>
|
||||||
<component name="editorHistoryManager">
|
<component name="editorHistoryManager">
|
||||||
<entry file="file://$PROJECT_DIR$/lib/flutter_inappbrowser.dart">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="195">
|
|
||||||
<caret line="32" column="47" selection-start-line="32" selection-start-column="47" selection-end-line="32" selection-end-column="47" />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/example/assets/client1-crt.pem" />
|
<entry file="file://$PROJECT_DIR$/example/assets/client1-crt.pem" />
|
||||||
<entry file="file://$PROJECT_DIR$/example/assets/client1-crt.crt" />
|
<entry file="file://$PROJECT_DIR$/example/assets/client1-crt.crt" />
|
||||||
<entry file="file://$PROJECT_DIR$/pubspec.lock">
|
<entry file="file://$PROJECT_DIR$/pubspec.lock">
|
||||||
<provider selected="true" editor-type-id="text-editor" />
|
<provider selected="true" editor-type-id="text-editor" />
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/ios/flutter_inappbrowser.podspec">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="315">
|
|
||||||
<caret line="21" column="25" selection-start-line="21" selection-start-column="25" selection-end-line="21" selection-end-column="25" />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/.gitignore">
|
<entry file="file://$PROJECT_DIR$/.gitignore">
|
||||||
<provider selected="true" editor-type-id="text-editor" />
|
<provider selected="true" editor-type-id="text-editor" />
|
||||||
</entry>
|
</entry>
|
||||||
|
@ -607,13 +612,6 @@
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/nodejs_server_test_auth_basic_and_ssl/index.js">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="733">
|
|
||||||
<caret line="111" column="34" selection-start-line="111" selection-start-column="34" selection-end-line="111" selection-end-column="34" />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$USER_HOME$/flutter/bin/cache/pkg/sky_engine/lib/io/file.dart">
|
<entry file="file://$USER_HOME$/flutter/bin/cache/pkg/sky_engine/lib/io/file.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="-1206">
|
<state relative-caret-position="-1206">
|
||||||
|
@ -638,13 +636,6 @@
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/example/assets/index.html">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="240">
|
|
||||||
<caret line="34" column="87" selection-start-line="34" selection-start-column="87" selection-end-line="34" selection-end-column="87" />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/lib/t_rex_runner/assets/novas-coisas.gif" />
|
<entry file="file://$PROJECT_DIR$/lib/t_rex_runner/assets/novas-coisas.gif" />
|
||||||
<entry file="file://$PROJECT_DIR$/lib/t_rex_runner/assets/t-rex-runner-19janil.gif" />
|
<entry file="file://$PROJECT_DIR$/lib/t_rex_runner/assets/t-rex-runner-19janil.gif" />
|
||||||
<entry file="file://$PROJECT_DIR$/lib/t_rex_runner/assets/t-rex-runner-bot.gif" />
|
<entry file="file://$PROJECT_DIR$/lib/t_rex_runner/assets/t-rex-runner-bot.gif" />
|
||||||
|
@ -679,23 +670,6 @@
|
||||||
</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="827">
|
|
||||||
<caret line="402" column="63" selection-start-line="402" selection-start-column="63" selection-end-line="402" selection-end-column="63" />
|
|
||||||
<folding>
|
|
||||||
<element signature="e#0#16406#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="408">
|
|
||||||
<caret line="29" column="8" selection-start-line="29" selection-start-column="8" selection-end-line="29" selection-end-column="8" />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/collection/linked_hash_map.dart">
|
<entry file="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/collection/linked_hash_map.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="137">
|
<state relative-caret-position="137">
|
||||||
|
@ -740,40 +714,71 @@
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/lib/src/in_app_browser.dart">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="239">
|
|
||||||
<caret line="287" column="5" selection-start-line="276" selection-start-column="4" selection-end-line="287" selection-end-column="5" />
|
|
||||||
<folding>
|
|
||||||
<element signature="e#0#20#0" expanded="true" />
|
|
||||||
</folding>
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/lib/src/types.dart">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="215">
|
|
||||||
<caret line="658" column="30" selection-start-line="658" selection-start-column="6" selection-end-line="658" selection-end-column="30" />
|
|
||||||
<folding>
|
|
||||||
<element signature="e#0#20#0" expanded="true" />
|
|
||||||
</folding>
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/example/build/app/outputs/apk/debug/output.json">
|
<entry file="file://$PROJECT_DIR$/example/build/app/outputs/apk/debug/output.json">
|
||||||
<provider selected="true" editor-type-id="text-editor" />
|
<provider selected="true" editor-type-id="text-editor" />
|
||||||
</entry>
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/flutter_inappbrowser.iml">
|
||||||
|
<provider selected="true" editor-type-id="text-editor" />
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/example/lib/test.dart">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="298">
|
||||||
|
<caret line="127" column="53" selection-start-line="127" selection-start-column="37" selection-end-line="127" selection-end-column="53" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#12489#12509#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/ios/flutter_inappbrowser.podspec">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="300">
|
||||||
|
<caret line="20" column="25" selection-start-line="20" selection-start-column="25" selection-end-line="20" selection-end-column="25" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/example/pubspec.yaml">
|
<entry file="file://$PROJECT_DIR$/example/pubspec.yaml">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="131">
|
<state relative-caret-position="116">
|
||||||
<caret line="24" column="27" selection-start-line="24" selection-start-column="27" selection-end-line="24" selection-end-column="27" />
|
<caret line="23" column="28" selection-start-line="23" selection-start-column="28" selection-end-line="23" selection-end-column="28" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/example/assets/index.html">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="1005">
|
||||||
|
<caret line="67" column="37" selection-start-line="67" selection-start-column="37" selection-end-line="67" selection-end-column="37" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/nodejs_server_test_auth_basic_and_ssl/index.js">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="1905">
|
||||||
|
<caret line="127" column="25" selection-start-line="127" selection-start-column="10" selection-end-line="127" selection-end-column="25" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="173">
|
||||||
|
<caret line="16" column="681" selection-start-line="16" selection-start-column="661" selection-end-line="16" selection-end-column="681" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/lib/src/in_app_browser.dart">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="520">
|
||||||
|
<caret line="511" column="30" selection-start-line="511" selection-start-column="7" selection-end-line="511" selection-end-column="30" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#20#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/example/lib/inline_example.screen.dart">
|
<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="28">
|
<state relative-caret-position="207">
|
||||||
<caret line="94" column="32" selection-start-line="94" selection-start-column="16" selection-end-line="94" selection-end-column="32" />
|
<caret line="295" column="18" selection-start-line="295" selection-start-column="18" selection-end-line="295" selection-end-column="18" />
|
||||||
<folding>
|
<folding>
|
||||||
<element signature="e#0#20#0" expanded="true" />
|
<element signature="e#0#20#0" expanded="true" />
|
||||||
</folding>
|
</folding>
|
||||||
|
@ -782,18 +787,28 @@
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/lib/src/in_app_webview.dart">
|
<entry file="file://$PROJECT_DIR$/lib/src/in_app_webview.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="251">
|
<state relative-caret-position="143">
|
||||||
<caret line="265" column="89" selection-start-line="261" selection-start-column="4" selection-end-line="265" selection-end-column="89" />
|
<caret line="336" column="42" selection-start-line="336" selection-start-column="42" selection-end-line="336" selection-end-column="42" />
|
||||||
<folding>
|
<folding>
|
||||||
<element signature="e#0#17#0" expanded="true" />
|
<element signature="e#0#17#0" expanded="true" />
|
||||||
</folding>
|
</folding>
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/lib/src/types.dart">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="332">
|
||||||
|
<caret line="482" column="6" selection-start-line="482" selection-start-column="6" selection-end-line="482" selection-end-column="6" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#20#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/lib/src/webview_options.dart">
|
<entry file="file://$PROJECT_DIR$/lib/src/webview_options.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="364">
|
<state relative-caret-position="-250">
|
||||||
<caret line="81" column="43" selection-start-line="81" selection-start-column="43" selection-end-line="81" selection-end-column="43" />
|
<caret line="347" column="93" selection-start-line="347" selection-start-column="93" selection-end-line="347" selection-end-column="93" />
|
||||||
<folding>
|
<folding>
|
||||||
<element signature="e#0#17#0" expanded="true" />
|
<element signature="e#0#17#0" expanded="true" />
|
||||||
</folding>
|
</folding>
|
||||||
|
|
14
CHANGELOG.md
14
CHANGELOG.md
|
@ -13,9 +13,9 @@
|
||||||
- Added `onLoadResourceCustomScheme` event and `resourceCustomSchemes` option to set custom schemes that WebView must handle to load resources
|
- Added `onLoadResourceCustomScheme` event and `resourceCustomSchemes` option to set custom schemes that WebView must handle to load resources
|
||||||
- Added `onTargetBlank` event and `useOnTargetBlank` option to manage links with `target="_blank"`
|
- Added `onTargetBlank` event and `useOnTargetBlank` option to manage links with `target="_blank"`
|
||||||
- Added `ContentBlocker`, `ContentBlockerTrigger` and `ContentBlockerAction` classes and the `contentBlockers` option that allows to define a set of rules to use to block content in the WebView
|
- Added `ContentBlocker`, `ContentBlockerTrigger` and `ContentBlockerAction` classes and the `contentBlockers` option that allows to define a set of rules to use to block content in the WebView
|
||||||
- Added new WebView options: `minimumFontSize`, `debuggingEnabled`, `preferredContentMode`
|
- Added new WebView options: `minimumFontSize`, `debuggingEnabled`, `preferredContentMode`, `applicationNameForUserAgent`, `incognito`, `cacheEnabled`
|
||||||
- Added new Android WebView options: `allowContentAccess`, `allowFileAccess`, `allowFileAccessFromFileURLs`, `allowUniversalAccessFromFileURLs`, `appCacheEnabled`, `appCachePath`, `blockNetworkImage`, `blockNetworkLoads`, `cacheMode`, `cursiveFontFamily`, `defaultFixedFontSize`, `defaultFontSize`, `defaultTextEncodingName`, `disabledActionModeMenuItems`, `fantasyFontFamily`, `fixedFontFamily`, `forceDark`, `geolocationEnabled`, `layoutAlgorithm`, `loadWithOverviewMode`, `loadsImagesAutomatically`, `minimumLogicalFontSize`, `needInitialFocus`, `offscreenPreRaster`, `sansSerifFontFamily`, `serifFontFamily`, `standardFontFamily`
|
- Added new Android WebView options: `allowContentAccess`, `allowFileAccess`, `allowFileAccessFromFileURLs`, `allowUniversalAccessFromFileURLs`, `appCachePath`, `blockNetworkImage`, `blockNetworkLoads`, `cacheMode`, `cursiveFontFamily`, `defaultFixedFontSize`, `defaultFontSize`, `defaultTextEncodingName`, `disabledActionModeMenuItems`, `fantasyFontFamily`, `fixedFontFamily`, `forceDark`, `geolocationEnabled`, `layoutAlgorithm`, `loadWithOverviewMode`, `loadsImagesAutomatically`, `minimumLogicalFontSize`, `needInitialFocus`, `offscreenPreRaster`, `sansSerifFontFamily`, `serifFontFamily`, `standardFontFamily`, `saveFormData`, `thirdPartyCookiesEnabled`, `hardwareAcceleration`
|
||||||
- Added new iOS WebView options: `applicationNameForUserAgent`, `isFraudulentWebsiteWarningEnabled`, `selectionGranularity`, `dataDetectorTypes`
|
- Added new iOS WebView options: `isFraudulentWebsiteWarningEnabled`, `selectionGranularity`, `dataDetectorTypes`, `sharedCookiesEnabled`
|
||||||
- Added `onGeolocationPermissionsShowPrompt` event and `GeolocationPermissionShowPromptResponse` class (available only for Android)
|
- Added `onGeolocationPermissionsShowPrompt` event and `GeolocationPermissionShowPromptResponse` class (available only for Android)
|
||||||
- Added `startSafeBrowsing`, `setSafeBrowsingWhitelist` and `getSafeBrowsingPrivacyPolicyUrl` methods (available only for Android)
|
- Added `startSafeBrowsing`, `setSafeBrowsingWhitelist` and `getSafeBrowsingPrivacyPolicyUrl` methods (available only for Android)
|
||||||
- Added `clearSslPreferences` and `clearClientCertPreferences` methods (available only for Android)
|
- Added `clearSslPreferences` and `clearClientCertPreferences` methods (available only for Android)
|
||||||
|
@ -26,7 +26,9 @@
|
||||||
- Added `HttpAuthCredentialDatabase` class
|
- Added `HttpAuthCredentialDatabase` class
|
||||||
- Added `onReceivedServerTrustAuthRequest` and `onReceivedClientCertRequest` events to manage SSL requests
|
- Added `onReceivedServerTrustAuthRequest` and `onReceivedClientCertRequest` events to manage SSL requests
|
||||||
- Added `onFindResultReceived` event, `findAllAsync`, `findNext` and `clearMatches` methods
|
- Added `onFindResultReceived` event, `findAllAsync`, `findNext` and `clearMatches` methods
|
||||||
- Added `getHtml` method
|
- Added `getHtml`, `injectJavascriptFileFromAsset` and `injectCSSFileFromAsset` methods
|
||||||
|
- Added `shouldInterceptAjaxRequest`, `onAjaxReadyStateChange`, `onAjaxProgress` and `shouldInterceptFetchRequest` events with `useShouldInterceptAjaxRequest` and `useShouldInterceptFetchRequest` webview options
|
||||||
|
- Added `onNavigationStateChange` event
|
||||||
- Fun: added `getTRexRunnerHtml` and `getTRexRunnerCss` methods to get html (with javascript) and css to recreate the Chromium's t-rex runner game
|
- Fun: added `getTRexRunnerHtml` and `getTRexRunnerCss` methods to get html (with javascript) and css to recreate the Chromium's t-rex runner game
|
||||||
|
|
||||||
### BREAKING CHANGES
|
### BREAKING CHANGES
|
||||||
|
@ -37,6 +39,10 @@
|
||||||
- Updated `CookieManager` class
|
- Updated `CookieManager` class
|
||||||
- WebView options are now available with the new corresponding classes: `InAppWebViewOptions`, `AndroidInAppWebViewOptions`, `iOSInAppWebViewOptions`, `InAppBrowserOptions`, `AndroidInAppBrowserOptions`, `iOSInAppBrowserOptions`, `AndroidChromeCustomTabsOptions` and `iOSSafariOptions`
|
- WebView options are now available with the new corresponding classes: `InAppWebViewOptions`, `AndroidInAppWebViewOptions`, `iOSInAppWebViewOptions`, `InAppBrowserOptions`, `AndroidInAppBrowserOptions`, `iOSInAppBrowserOptions`, `AndroidChromeCustomTabsOptions` and `iOSSafariOptions`
|
||||||
- Renamed `getFavicon` to `getFavicons`, now it returns a list of all favicons (`List<Favicon>`) found
|
- Renamed `getFavicon` to `getFavicons`, now it returns a list of all favicons (`List<Favicon>`) found
|
||||||
|
- Renamed `injectScriptFile` to `injectJavascriptFileFromUrl`
|
||||||
|
- Renamed `injectScriptCode` to `evaluateJavascript`
|
||||||
|
- Renamed `injectStyleCode` to `injectCSSCode`
|
||||||
|
- Renamed `injectStyleFile` to `injectCSSFileFromUrl`
|
||||||
|
|
||||||
## 1.2.1
|
## 1.2.1
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
import io.flutter.plugin.common.MethodChannel;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
|
|
||||||
|
@ -145,7 +146,7 @@ public class ContentBlockerHandler {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
webView.evaluateJavascript(jsScript, null);
|
webView.evaluateJavascript(jsScript, (MethodChannel.Result) null);
|
||||||
} else {
|
} else {
|
||||||
webView.loadUrl("javascript:" + jsScript);
|
webView.loadUrl("javascript:" + jsScript);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
package com.pichillilorenzo.flutter_inappbrowser;
|
package com.pichillilorenzo.flutter_inappbrowser;
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.hardware.display.DisplayManager;
|
import android.hardware.display.DisplayManager;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Handler;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.webkit.WebChromeClient;
|
import android.webkit.WebChromeClient;
|
||||||
|
@ -15,21 +13,20 @@ import android.webkit.WebViewClient;
|
||||||
import com.pichillilorenzo.flutter_inappbrowser.InAppWebView.DisplayListenerProxy;
|
import com.pichillilorenzo.flutter_inappbrowser.InAppWebView.DisplayListenerProxy;
|
||||||
import com.pichillilorenzo.flutter_inappbrowser.InAppWebView.InAppWebView;
|
import com.pichillilorenzo.flutter_inappbrowser.InAppWebView.InAppWebView;
|
||||||
import com.pichillilorenzo.flutter_inappbrowser.InAppWebView.InAppWebViewOptions;
|
import com.pichillilorenzo.flutter_inappbrowser.InAppWebView.InAppWebViewOptions;
|
||||||
import com.pichillilorenzo.flutter_inappbrowser.InAppWebView.InputAwareWebView;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import io.flutter.plugin.common.BinaryMessenger;
|
|
||||||
import io.flutter.plugin.common.MethodCall;
|
import io.flutter.plugin.common.MethodCall;
|
||||||
import io.flutter.plugin.common.MethodChannel;
|
import io.flutter.plugin.common.MethodChannel;
|
||||||
import static io.flutter.plugin.common.MethodChannel.MethodCallHandler;
|
|
||||||
import static io.flutter.plugin.common.MethodChannel.Result;
|
|
||||||
import io.flutter.plugin.common.PluginRegistry.Registrar;
|
import io.flutter.plugin.common.PluginRegistry.Registrar;
|
||||||
import io.flutter.plugin.platform.PlatformView;
|
import io.flutter.plugin.platform.PlatformView;
|
||||||
|
|
||||||
|
import static io.flutter.plugin.common.MethodChannel.MethodCallHandler;
|
||||||
|
import static io.flutter.plugin.common.MethodChannel.Result;
|
||||||
|
|
||||||
public class FlutterWebView implements PlatformView, MethodCallHandler {
|
public class FlutterWebView implements PlatformView, MethodCallHandler {
|
||||||
|
|
||||||
static final String LOG_TAG = "FlutterWebView";
|
static final String LOG_TAG = "FlutterWebView";
|
||||||
|
@ -135,33 +132,33 @@ public class FlutterWebView implements PlatformView, MethodCallHandler {
|
||||||
else
|
else
|
||||||
result.success(false);
|
result.success(false);
|
||||||
break;
|
break;
|
||||||
case "injectScriptCode":
|
case "evaluateJavascript":
|
||||||
if (webView != null) {
|
if (webView != null) {
|
||||||
String source = (String) call.argument("source");
|
String source = (String) call.argument("source");
|
||||||
webView.injectScriptCode(source, result);
|
webView.evaluateJavascript(source, result);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result.success("");
|
result.success("");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "injectScriptFile":
|
case "injectJavascriptFileFromUrl":
|
||||||
if (webView != null) {
|
if (webView != null) {
|
||||||
String urlFile = (String) call.argument("urlFile");
|
String urlFile = (String) call.argument("urlFile");
|
||||||
webView.injectScriptFile(urlFile);
|
webView.injectJavascriptFileFromUrl(urlFile);
|
||||||
}
|
}
|
||||||
result.success(true);
|
result.success(true);
|
||||||
break;
|
break;
|
||||||
case "injectStyleCode":
|
case "injectCSSCode":
|
||||||
if (webView != null) {
|
if (webView != null) {
|
||||||
String source = (String) call.argument("source");
|
String source = (String) call.argument("source");
|
||||||
webView.injectStyleCode(source);
|
webView.injectCSSCode(source);
|
||||||
}
|
}
|
||||||
result.success(true);
|
result.success(true);
|
||||||
break;
|
break;
|
||||||
case "injectStyleFile":
|
case "injectCSSFileFromUrl":
|
||||||
if (webView != null) {
|
if (webView != null) {
|
||||||
String urlFile = (String) call.argument("urlFile");
|
String urlFile = (String) call.argument("urlFile");
|
||||||
webView.injectStyleFile(urlFile);
|
webView.injectCSSFileFromUrl(urlFile);
|
||||||
}
|
}
|
||||||
result.success(true);
|
result.success(true);
|
||||||
break;
|
break;
|
||||||
|
@ -312,13 +309,13 @@ public class FlutterWebView implements PlatformView, MethodCallHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInputConnectionLocked() {
|
public void onInputConnectionLocked() {
|
||||||
if (webView.inAppBrowserActivity == null)
|
if (webView != null && webView.inAppBrowserActivity == null)
|
||||||
webView.lockInputConnection();
|
webView.lockInputConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInputConnectionUnlocked() {
|
public void onInputConnectionUnlocked() {
|
||||||
if (webView.inAppBrowserActivity == null)
|
if (webView != null && webView.inAppBrowserActivity == null)
|
||||||
webView.unlockInputConnection();
|
webView.unlockInputConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -192,23 +192,23 @@ public class InAppBrowser implements MethodChannel.MethodCallHandler {
|
||||||
case "close":
|
case "close":
|
||||||
close(activity, uuid, result);
|
close(activity, uuid, result);
|
||||||
break;
|
break;
|
||||||
case "injectScriptCode":
|
case "evaluateJavascript":
|
||||||
source = (String) call.argument("source");
|
source = (String) call.argument("source");
|
||||||
injectScriptCode(uuid, source, result);
|
evaluateJavascript(uuid, source, result);
|
||||||
break;
|
break;
|
||||||
case "injectScriptFile":
|
case "injectJavascriptFileFromUrl":
|
||||||
urlFile = (String) call.argument("urlFile");
|
urlFile = (String) call.argument("urlFile");
|
||||||
injectScriptFile(uuid, urlFile);
|
injectJavascriptFileFromUrl(uuid, urlFile);
|
||||||
result.success(true);
|
result.success(true);
|
||||||
break;
|
break;
|
||||||
case "injectStyleCode":
|
case "injectCSSCode":
|
||||||
source = (String) call.argument("source");
|
source = (String) call.argument("source");
|
||||||
injectStyleCode(uuid, source);
|
injectCSSCode(uuid, source);
|
||||||
result.success(true);
|
result.success(true);
|
||||||
break;
|
break;
|
||||||
case "injectStyleFile":
|
case "injectCSSFileFromUrl":
|
||||||
urlFile = (String) call.argument("urlFile");
|
urlFile = (String) call.argument("urlFile");
|
||||||
injectStyleFile(uuid, urlFile);
|
injectCSSFileFromUrl(uuid, urlFile);
|
||||||
result.success(true);
|
result.success(true);
|
||||||
break;
|
break;
|
||||||
case "show":
|
case "show":
|
||||||
|
@ -314,33 +314,33 @@ public class InAppBrowser implements MethodChannel.MethodCallHandler {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void injectScriptCode(String uuid, String source, final Result result) {
|
private void evaluateJavascript(String uuid, String source, final Result result) {
|
||||||
final InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
final InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||||
if (inAppBrowserActivity != null) {
|
if (inAppBrowserActivity != null) {
|
||||||
inAppBrowserActivity.injectScriptCode(source, result);
|
inAppBrowserActivity.evaluateJavascript(source, result);
|
||||||
} else {
|
} else {
|
||||||
Log.d(LOG_TAG, "webView is null");
|
Log.d(LOG_TAG, "webView is null");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void injectScriptFile(String uuid, String urlFile) {
|
private void injectJavascriptFileFromUrl(String uuid, String urlFile) {
|
||||||
final InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
final InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||||
if (inAppBrowserActivity != null) {
|
if (inAppBrowserActivity != null) {
|
||||||
inAppBrowserActivity.injectScriptFile(urlFile);
|
inAppBrowserActivity.injectJavascriptFileFromUrl(urlFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void injectStyleCode(String uuid, String source) {
|
private void injectCSSCode(String uuid, String source) {
|
||||||
final InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
final InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||||
if (inAppBrowserActivity != null) {
|
if (inAppBrowserActivity != null) {
|
||||||
inAppBrowserActivity.injectStyleCode(source);
|
inAppBrowserActivity.injectCSSCode(source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void injectStyleFile(String uuid, String urlFile) {
|
private void injectCSSFileFromUrl(String uuid, String urlFile) {
|
||||||
final InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
final InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||||
if (inAppBrowserActivity != null) {
|
if (inAppBrowserActivity != null) {
|
||||||
inAppBrowserActivity.injectStyleFile(urlFile);
|
inAppBrowserActivity.injectCSSFileFromUrl(urlFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -434,26 +434,26 @@ public class InAppBrowserActivity extends AppCompatActivity {
|
||||||
return optionsMap;
|
return optionsMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void injectScriptCode(String source, MethodChannel.Result result) {
|
public void evaluateJavascript(String source, MethodChannel.Result result) {
|
||||||
if (webView != null)
|
if (webView != null)
|
||||||
webView.injectScriptCode(source, result);
|
webView.evaluateJavascript(source, result);
|
||||||
else
|
else
|
||||||
result.success("");
|
result.success("");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void injectScriptFile(String urlFile) {
|
public void injectJavascriptFileFromUrl(String urlFile) {
|
||||||
if (webView != null)
|
if (webView != null)
|
||||||
webView.injectScriptFile(urlFile);
|
webView.injectJavascriptFileFromUrl(urlFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void injectStyleCode(String source) {
|
public void injectCSSCode(String source) {
|
||||||
if (webView != null)
|
if (webView != null)
|
||||||
webView.injectStyleCode(source);
|
webView.injectCSSCode(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void injectStyleFile(String urlFile) {
|
public void injectCSSFileFromUrl(String urlFile) {
|
||||||
if (webView != null)
|
if (webView != null)
|
||||||
webView.injectStyleFile(urlFile);
|
webView.injectCSSFileFromUrl(urlFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashMap<String, Object> getCopyBackForwardList() {
|
public HashMap<String, Object> getCopyBackForwardList() {
|
||||||
|
|
|
@ -59,7 +59,7 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
int okHttpClientCacheSize = 10 * 1024 * 1024; // 10MB
|
int okHttpClientCacheSize = 10 * 1024 * 1024; // 10MB
|
||||||
public ContentBlockerHandler contentBlockerHandler = new ContentBlockerHandler();
|
public ContentBlockerHandler contentBlockerHandler = new ContentBlockerHandler();
|
||||||
|
|
||||||
static final String consoleLogJS = "(function() {" +
|
static final String consoleLogJS = "(function(console) {" +
|
||||||
" var oldLogs = {" +
|
" var oldLogs = {" +
|
||||||
" 'log': console.log," +
|
" 'log': console.log," +
|
||||||
" 'debug': console.debug," +
|
" 'debug': console.debug," +
|
||||||
|
@ -83,18 +83,354 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
" }" +
|
" }" +
|
||||||
" })(k);" +
|
" })(k);" +
|
||||||
" }" +
|
" }" +
|
||||||
"})();";
|
"})(window.console);";
|
||||||
|
|
||||||
|
static final String platformReadyJS = "window.dispatchEvent(new Event('flutterInAppBrowserPlatformReady'));";
|
||||||
|
|
||||||
|
static final String variableForOnLoadResourceJS = "window._flutter_inappbrowser_useOnLoadResource";
|
||||||
|
static final String enableVariableForOnLoadResourceJS = variableForOnLoadResourceJS + " = $PLACEHOLDER_VALUE;";
|
||||||
|
|
||||||
static final String resourceObserverJS = "(function() {" +
|
static final String resourceObserverJS = "(function() {" +
|
||||||
" var observer = new PerformanceObserver(function(list) {" +
|
" var observer = new PerformanceObserver(function(list) {" +
|
||||||
" list.getEntries().forEach(function(entry) {" +
|
" list.getEntries().forEach(function(entry) {" +
|
||||||
" window." + JavaScriptBridgeInterface.name + "._resourceLoaded(JSON.stringify(entry));" +
|
" if (window." + variableForOnLoadResourceJS + " == null || window." + variableForOnLoadResourceJS + " == true) {" +
|
||||||
|
" window." + JavaScriptBridgeInterface.name + ".callHandler('onLoadResource', entry);" +
|
||||||
|
" }" +
|
||||||
" });" +
|
" });" +
|
||||||
" });" +
|
" });" +
|
||||||
" observer.observe({entryTypes: ['resource']});" +
|
" observer.observe({entryTypes: ['resource']});" +
|
||||||
"})();";
|
"})();";
|
||||||
|
|
||||||
static final String platformReadyJS = "window.dispatchEvent(new Event('flutterInAppBrowserPlatformReady'));";
|
static final String variableForShouldInterceptAjaxRequestJS = "window._flutter_inappbrowser_useShouldInterceptAjaxRequest";
|
||||||
|
static final String enableVariableForShouldInterceptAjaxRequestJS = variableForShouldInterceptAjaxRequestJS + " = $PLACEHOLDER_VALUE;";
|
||||||
|
|
||||||
|
static final String interceptAjaxRequestsJS = "(function(ajax) {" +
|
||||||
|
" var send = ajax.prototype.send;" +
|
||||||
|
" var open = ajax.prototype.open;" +
|
||||||
|
" var setRequestHeader = ajax.prototype.setRequestHeader;" +
|
||||||
|
" ajax.prototype._flutter_inappbrowser_url = null;" +
|
||||||
|
" ajax.prototype._flutter_inappbrowser_method = null;" +
|
||||||
|
" ajax.prototype._flutter_inappbrowser_isAsync = null;" +
|
||||||
|
" ajax.prototype._flutter_inappbrowser_user = null;" +
|
||||||
|
" ajax.prototype._flutter_inappbrowser_password = null;" +
|
||||||
|
" ajax.prototype._flutter_inappbrowser_password = null;" +
|
||||||
|
" ajax.prototype._flutter_inappbrowser_already_onreadystatechange_wrapped = false;" +
|
||||||
|
" ajax.prototype._flutter_inappbrowser_request_headers = {};" +
|
||||||
|
" ajax.prototype.open = function(method, url, isAsync, user, password) {" +
|
||||||
|
" isAsync = (isAsync != null) ? isAsync : true;" +
|
||||||
|
" this._flutter_inappbrowser_url = url;" +
|
||||||
|
" this._flutter_inappbrowser_method = method;" +
|
||||||
|
" this._flutter_inappbrowser_isAsync = isAsync;" +
|
||||||
|
" this._flutter_inappbrowser_user = user;" +
|
||||||
|
" this._flutter_inappbrowser_password = password;" +
|
||||||
|
" open.call(this, method, url, isAsync, user, password);" +
|
||||||
|
" };" +
|
||||||
|
" ajax.prototype.setRequestHeader = function(header, value) {" +
|
||||||
|
" this._flutter_inappbrowser_request_headers[header] = value;" +
|
||||||
|
" setRequestHeader.call(this, header, value);" +
|
||||||
|
" };" +
|
||||||
|
" function handleEvent(e) {" +
|
||||||
|
" var self = this;" +
|
||||||
|
" if (window." + variableForShouldInterceptAjaxRequestJS + " == null || window." + variableForShouldInterceptAjaxRequestJS + " == true) {" +
|
||||||
|
" var headers = this.getAllResponseHeaders();" +
|
||||||
|
" var responseHeaders = {};" +
|
||||||
|
" if (headers != null) {" +
|
||||||
|
" var arr = headers.trim().split(/[\\r\\n]+/);" +
|
||||||
|
" arr.forEach(function (line) {" +
|
||||||
|
" var parts = line.split(': ');" +
|
||||||
|
" var header = parts.shift();" +
|
||||||
|
" var value = parts.join(': ');" +
|
||||||
|
" responseHeaders[header] = value;" +
|
||||||
|
" });" +
|
||||||
|
" }" +
|
||||||
|
" var ajaxRequest = {" +
|
||||||
|
" method: this._flutter_inappbrowser_method," +
|
||||||
|
" url: this._flutter_inappbrowser_url," +
|
||||||
|
" isAsync: this._flutter_inappbrowser_isAsync," +
|
||||||
|
" user: this._flutter_inappbrowser_user," +
|
||||||
|
" password: this._flutter_inappbrowser_password," +
|
||||||
|
" withCredentials: this.withCredentials," +
|
||||||
|
" headers: this._flutter_inappbrowser_request_headers," +
|
||||||
|
" readyState: this.readyState," +
|
||||||
|
" status: this.status," +
|
||||||
|
" responseURL: this.responseURL," +
|
||||||
|
" responseType: this.responseType," +
|
||||||
|
" responseText: this.responseText," +
|
||||||
|
" statusText: this.statusText," +
|
||||||
|
" responseHeaders, responseHeaders," +
|
||||||
|
" event: {" +
|
||||||
|
" type: e.type," +
|
||||||
|
" loaded: e.loaded," +
|
||||||
|
" lengthComputable: e.lengthComputable" +
|
||||||
|
" }" +
|
||||||
|
" };" +
|
||||||
|
" window." + JavaScriptBridgeInterface.name + ".callHandler('onAjaxProgress', ajaxRequest).then(function(result) {" +
|
||||||
|
" if (result != null) {" +
|
||||||
|
" switch (result) {" +
|
||||||
|
" case 0:" +
|
||||||
|
" self.abort();" +
|
||||||
|
" return;" +
|
||||||
|
" };" +
|
||||||
|
" }" +
|
||||||
|
" });" +
|
||||||
|
" }" +
|
||||||
|
" };" +
|
||||||
|
" ajax.prototype.send = function(data) {" +
|
||||||
|
" var self = this;" +
|
||||||
|
" if (window." + variableForShouldInterceptAjaxRequestJS + " == null || window." + variableForShouldInterceptAjaxRequestJS + " == true) {" +
|
||||||
|
" if (!this._flutter_inappbrowser_already_onreadystatechange_wrapped) {" +
|
||||||
|
" this._flutter_inappbrowser_already_onreadystatechange_wrapped = true;" +
|
||||||
|
" var onreadystatechange = this.onreadystatechange;" +
|
||||||
|
" this.onreadystatechange = function() {" +
|
||||||
|
" if (window." + variableForShouldInterceptAjaxRequestJS + " == null || window." + variableForShouldInterceptAjaxRequestJS + " == true) {" +
|
||||||
|
" var headers = this.getAllResponseHeaders();" +
|
||||||
|
" var responseHeaders = {};" +
|
||||||
|
" if (headers != null) {" +
|
||||||
|
" var arr = headers.trim().split(/[\\r\\n]+/);" +
|
||||||
|
" arr.forEach(function (line) {" +
|
||||||
|
" var parts = line.split(': ');" +
|
||||||
|
" var header = parts.shift();" +
|
||||||
|
" var value = parts.join(': ');" +
|
||||||
|
" responseHeaders[header] = value;" +
|
||||||
|
" });" +
|
||||||
|
" }" +
|
||||||
|
" var ajaxRequest = {" +
|
||||||
|
" method: this._flutter_inappbrowser_method," +
|
||||||
|
" url: this._flutter_inappbrowser_url," +
|
||||||
|
" isAsync: this._flutter_inappbrowser_isAsync," +
|
||||||
|
" user: this._flutter_inappbrowser_user," +
|
||||||
|
" password: this._flutter_inappbrowser_password," +
|
||||||
|
" withCredentials: this.withCredentials," +
|
||||||
|
" headers: this._flutter_inappbrowser_request_headers," +
|
||||||
|
" readyState: this.readyState," +
|
||||||
|
" status: this.status," +
|
||||||
|
" responseURL: this.responseURL," +
|
||||||
|
" responseType: this.responseType," +
|
||||||
|
" responseText: this.responseText," +
|
||||||
|
" statusText: this.statusText," +
|
||||||
|
" responseHeaders: responseHeaders" +
|
||||||
|
" };" +
|
||||||
|
" window." + JavaScriptBridgeInterface.name + ".callHandler('onAjaxReadyStateChange', ajaxRequest).then(function(result) {" +
|
||||||
|
" if (result != null) {" +
|
||||||
|
" switch (result) {" +
|
||||||
|
" case 0:" +
|
||||||
|
" self.abort();" +
|
||||||
|
" return;" +
|
||||||
|
" };" +
|
||||||
|
" }" +
|
||||||
|
" if (onreadystatechange != null) {" +
|
||||||
|
" onreadystatechange();" +
|
||||||
|
" }" +
|
||||||
|
" });" +
|
||||||
|
" } else if (onreadystatechange != null) {" +
|
||||||
|
" onreadystatechange();" +
|
||||||
|
" }" +
|
||||||
|
" };" +
|
||||||
|
" }" +
|
||||||
|
" this.addEventListener('loadstart', handleEvent);" +
|
||||||
|
" this.addEventListener('load', handleEvent);" +
|
||||||
|
" this.addEventListener('loadend', handleEvent);" +
|
||||||
|
" this.addEventListener('progress', handleEvent);" +
|
||||||
|
" this.addEventListener('error', handleEvent);" +
|
||||||
|
" this.addEventListener('abort', handleEvent);" +
|
||||||
|
" var ajaxRequest = {" +
|
||||||
|
" data: data," +
|
||||||
|
" method: this._flutter_inappbrowser_method," +
|
||||||
|
" url: this._flutter_inappbrowser_url," +
|
||||||
|
" isAsync: this._flutter_inappbrowser_isAsync," +
|
||||||
|
" user: this._flutter_inappbrowser_user," +
|
||||||
|
" password: this._flutter_inappbrowser_password," +
|
||||||
|
" withCredentials: this.withCredentials," +
|
||||||
|
" headers: this._flutter_inappbrowser_request_headers" +
|
||||||
|
" };" +
|
||||||
|
" window." + JavaScriptBridgeInterface.name + ".callHandler('shouldInterceptAjaxRequest', ajaxRequest).then(function(result) {" +
|
||||||
|
" if (result != null) {" +
|
||||||
|
" switch (result.action) {" +
|
||||||
|
" case 0:" +
|
||||||
|
" self.abort();" +
|
||||||
|
" return;" +
|
||||||
|
" };" +
|
||||||
|
" data = result.data;" +
|
||||||
|
" self.withCredentials = result.withCredentials;" +
|
||||||
|
" for (var header in result.headers) {" +
|
||||||
|
" var value = result.headers[header];" +
|
||||||
|
" self.setRequestHeader(header, value);" +
|
||||||
|
" };" +
|
||||||
|
" if ((self._flutter_inappbrowser_method != result.method && result.method != null) || (self._flutter_inappbrowser_url != result.url && result.url != null)) {" +
|
||||||
|
" self.abort();" +
|
||||||
|
" self.open(result.method, result.url, result.isAsync, result.user, result.password);" +
|
||||||
|
" return;" +
|
||||||
|
" }" +
|
||||||
|
" }" +
|
||||||
|
" send.call(self, data);" +
|
||||||
|
" });" +
|
||||||
|
" } else {" +
|
||||||
|
" send.call(this, data);" +
|
||||||
|
" }" +
|
||||||
|
" };" +
|
||||||
|
"})(window.XMLHttpRequest);";
|
||||||
|
|
||||||
|
static final String variableForShouldInterceptFetchRequestsJS = "window._flutter_inappbrowser_useShouldInterceptFetchRequest";
|
||||||
|
static final String enableVariableForShouldInterceptFetchRequestsJS = variableForShouldInterceptFetchRequestsJS + " = $PLACEHOLDER_VALUE;";
|
||||||
|
|
||||||
|
static final String interceptFetchRequestsJS = "(function(fetch) {" +
|
||||||
|
" if (fetch == null) {" +
|
||||||
|
" return;" +
|
||||||
|
" }" +
|
||||||
|
" function convertHeadersToJson(headers) {" +
|
||||||
|
" var headersObj = {};" +
|
||||||
|
" for (var header of headers.keys()) {" +
|
||||||
|
" var value = headers.get(header);" +
|
||||||
|
" headersObj[header] = value;" +
|
||||||
|
" }" +
|
||||||
|
" return headersObj;" +
|
||||||
|
" }" +
|
||||||
|
" function convertJsonToHeaders(headersJson) {" +
|
||||||
|
" return new Headers(headersJson);" +
|
||||||
|
" }" +
|
||||||
|
" function convertBodyToArray(body) {" +
|
||||||
|
" return new Response(body).arrayBuffer().then(function(arrayBuffer) {" +
|
||||||
|
" var arr = Array.from(new Uint8Array(arrayBuffer));" +
|
||||||
|
" return arr;" +
|
||||||
|
" })" +
|
||||||
|
" }" +
|
||||||
|
" function convertArrayIntBodyToUint8Array(arrayIntBody) {" +
|
||||||
|
" return new Uint8Array(arrayIntBody);" +
|
||||||
|
" }" +
|
||||||
|
" function convertCredentialsToJson(credentials) {" +
|
||||||
|
" var credentialsObj = {};" +
|
||||||
|
" if (window.FederatedCredential != null && credentials instanceof FederatedCredential) {" +
|
||||||
|
" credentialsObj.type = credentials.type;" +
|
||||||
|
" credentialsObj.id = credentials.id;" +
|
||||||
|
" credentialsObj.name = credentials.name;" +
|
||||||
|
" credentialsObj.protocol = credentials.protocol;" +
|
||||||
|
" credentialsObj.provider = credentials.provider;" +
|
||||||
|
" credentialsObj.iconURL = credentials.iconURL;" +
|
||||||
|
" } else if (window.PasswordCredential != null && credentials instanceof PasswordCredential) {" +
|
||||||
|
" credentialsObj.type = credentials.type;" +
|
||||||
|
" credentialsObj.id = credentials.id;" +
|
||||||
|
" credentialsObj.name = credentials.name;" +
|
||||||
|
" credentialsObj.password = credentials.password;" +
|
||||||
|
" credentialsObj.iconURL = credentials.iconURL;" +
|
||||||
|
" } else {" +
|
||||||
|
" credentialsObj.type = 'default';" +
|
||||||
|
" credentialsObj.value = credentials;" +
|
||||||
|
" }" +
|
||||||
|
" }" +
|
||||||
|
" function convertJsonToCredential(credentialsJson) {" +
|
||||||
|
" var credentials;" +
|
||||||
|
" if (window.FederatedCredential != null && credentialsJson.type === 'federated') {" +
|
||||||
|
" credentials = new FederatedCredential({" +
|
||||||
|
" id: credentialsJson.id," +
|
||||||
|
" name: credentialsJson.name," +
|
||||||
|
" protocol: credentialsJson.protocol," +
|
||||||
|
" provider: credentialsJson.provider," +
|
||||||
|
" iconURL: credentialsJson.iconURL" +
|
||||||
|
" });" +
|
||||||
|
" } else if (window.PasswordCredential != null && credentialsJson.type === 'password') {" +
|
||||||
|
" credentials = new PasswordCredential({" +
|
||||||
|
" id: credentialsJson.id," +
|
||||||
|
" name: credentialsJson.name," +
|
||||||
|
" password: credentialsJson.password," +
|
||||||
|
" iconURL: credentialsJson.iconURL" +
|
||||||
|
" });" +
|
||||||
|
" } else {" +
|
||||||
|
" credentials = credentialsJson;" +
|
||||||
|
" }" +
|
||||||
|
" return credentials;" +
|
||||||
|
" }" +
|
||||||
|
" window.fetch = async function(resource, init) {" +
|
||||||
|
" if (window." + variableForShouldInterceptFetchRequestsJS + " == null || window." + variableForShouldInterceptFetchRequestsJS + " == true) {" +
|
||||||
|
" var fetchRequest = {" +
|
||||||
|
" url: null," +
|
||||||
|
" method: null," +
|
||||||
|
" headers: null," +
|
||||||
|
" body: null," +
|
||||||
|
" mode: null," +
|
||||||
|
" credentials: null," +
|
||||||
|
" cache: null," +
|
||||||
|
" redirect: null," +
|
||||||
|
" referrer: null," +
|
||||||
|
" referrerPolicy: null," +
|
||||||
|
" integrity: null," +
|
||||||
|
" keepalive: null" +
|
||||||
|
" };" +
|
||||||
|
" if (resource instanceof Request) {" +
|
||||||
|
" fetchRequest.url = resource.url;" +
|
||||||
|
" fetchRequest.method = resource.method;" +
|
||||||
|
" fetchRequest.headers = resource.headers;" +
|
||||||
|
" fetchRequest.body = resource.body;" +
|
||||||
|
" fetchRequest.mode = resource.mode;" +
|
||||||
|
" fetchRequest.credentials = resource.credentials;" +
|
||||||
|
" fetchRequest.cache = resource.cache;" +
|
||||||
|
" fetchRequest.redirect = resource.redirect;" +
|
||||||
|
" fetchRequest.referrer = resource.referrer;" +
|
||||||
|
" fetchRequest.referrerPolicy = resource.referrerPolicy;" +
|
||||||
|
" fetchRequest.integrity = resource.integrity;" +
|
||||||
|
" fetchRequest.keepalive = resource.keepalive;" +
|
||||||
|
" } else {" +
|
||||||
|
" fetchRequest.url = resource;" +
|
||||||
|
" if (init != null) {" +
|
||||||
|
" fetchRequest.method = init.method;" +
|
||||||
|
" fetchRequest.headers = init.headers;" +
|
||||||
|
" fetchRequest.body = init.body;" +
|
||||||
|
" fetchRequest.mode = init.mode;" +
|
||||||
|
" fetchRequest.credentials = init.credentials;" +
|
||||||
|
" fetchRequest.cache = init.cache;" +
|
||||||
|
" fetchRequest.redirect = init.redirect;" +
|
||||||
|
" fetchRequest.referrer = init.referrer;" +
|
||||||
|
" fetchRequest.referrerPolicy = init.referrerPolicy;" +
|
||||||
|
" fetchRequest.integrity = init.integrity;" +
|
||||||
|
" fetchRequest.keepalive = init.keepalive;" +
|
||||||
|
" }" +
|
||||||
|
" }" +
|
||||||
|
" if (fetchRequest.headers instanceof Headers) {" +
|
||||||
|
" fetchRequest.headers = convertHeadersToJson(fetchRequest.headers);" +
|
||||||
|
" }" +
|
||||||
|
" fetchRequest.credentials = convertCredentialsToJson(fetchRequest.credentials);" +
|
||||||
|
" return convertBodyToArray(fetchRequest.body).then(function(body) {" +
|
||||||
|
" fetchRequest.body = body;" +
|
||||||
|
" return window." + JavaScriptBridgeInterface.name + ".callHandler('shouldInterceptFetchRequest', fetchRequest).then(function(result) {" +
|
||||||
|
" if (result != null) {" +
|
||||||
|
" switch (result.action) {" +
|
||||||
|
" case 0:" +
|
||||||
|
" var controller = new AbortController();" +
|
||||||
|
" if (init != null) {" +
|
||||||
|
" init.signal = controller.signal;" +
|
||||||
|
" } else {" +
|
||||||
|
" init = {" +
|
||||||
|
" signal: controller.signal" +
|
||||||
|
" };" +
|
||||||
|
" }" +
|
||||||
|
" controller.abort();" +
|
||||||
|
" break;" +
|
||||||
|
" }" +
|
||||||
|
" var resultResource = (result.resource != null) ? result.resource : resource;" +
|
||||||
|
" var resultInit = init;" +
|
||||||
|
" if (result.init != null) {" +
|
||||||
|
" resultInit.method = result.method;" +
|
||||||
|
" resultInit.headers = convertJsonToHeaders(result.headers);" +
|
||||||
|
" resultInit.body = convertArrayIntBodyToUint8Array(result.body);" +
|
||||||
|
" resultInit.mode = result.mode;" +
|
||||||
|
" resultInit.credentials = convertJsonToCredential(result.credentials);" +
|
||||||
|
" resultInit.cache = result.cache;" +
|
||||||
|
" resultInit.redirect = result.redirect;" +
|
||||||
|
" resultInit.referrer = result.referrer;" +
|
||||||
|
" resultInit.referrerPolicy = result.referrerPolicy;" +
|
||||||
|
" resultInit.integrity = result.integrity;" +
|
||||||
|
" resultInit.keepalive = result.keepalive;" +
|
||||||
|
" }" +
|
||||||
|
" return fetch(resultResource, resultInit);" +
|
||||||
|
" }" +
|
||||||
|
" return fetch(resource, init);" +
|
||||||
|
" });" +
|
||||||
|
" });" +
|
||||||
|
" } else {" +
|
||||||
|
" return fetch(resource, init);" +
|
||||||
|
" }" +
|
||||||
|
" };" +
|
||||||
|
"})(window.fetch);";
|
||||||
|
|
||||||
|
|
||||||
public InAppWebView(Context context) {
|
public InAppWebView(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
|
@ -163,19 +499,28 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
settings.setDatabaseEnabled(options.databaseEnabled);
|
settings.setDatabaseEnabled(options.databaseEnabled);
|
||||||
settings.setDomStorageEnabled(options.domStorageEnabled);
|
settings.setDomStorageEnabled(options.domStorageEnabled);
|
||||||
|
|
||||||
if (!options.userAgent.isEmpty())
|
if (options.userAgent != null && !options.userAgent.isEmpty())
|
||||||
settings.setUserAgentString(options.userAgent);
|
settings.setUserAgentString(options.userAgent);
|
||||||
|
else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||||||
|
settings.setUserAgentString(WebSettings.getDefaultUserAgent(getContext()));
|
||||||
|
|
||||||
|
if (options.applicationNameForUserAgent != null && !options.applicationNameForUserAgent.isEmpty()) {
|
||||||
|
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||||
|
String userAgent = (options.userAgent != null && !options.userAgent.isEmpty()) ? options.userAgent :WebSettings.getDefaultUserAgent(getContext());
|
||||||
|
String userAgentWithApplicationName = userAgent + " " + options.applicationNameForUserAgent;
|
||||||
|
settings.setUserAgentString(userAgentWithApplicationName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (options.clearCache)
|
if (options.clearCache)
|
||||||
clearAllCache();
|
clearAllCache();
|
||||||
else if (options.clearSessionCache)
|
else if (options.clearSessionCache)
|
||||||
CookieManager.getInstance().removeSessionCookie();
|
CookieManager.getInstance().removeSessionCookie();
|
||||||
|
|
||||||
// Enable Thirdparty Cookies on >=Android 5.0 device
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||||
CookieManager.getInstance().setAcceptThirdPartyCookies(this, true);
|
CookieManager.getInstance().setAcceptThirdPartyCookies(this, options.thirdPartyCookiesEnabled);
|
||||||
|
|
||||||
settings.setLoadWithOverviewMode(true);
|
settings.setLoadWithOverviewMode(options.loadWithOverviewMode);
|
||||||
settings.setUseWideViewPort(options.useWideViewPort);
|
settings.setUseWideViewPort(options.useWideViewPort);
|
||||||
settings.setSupportZoom(options.supportZoom);
|
settings.setSupportZoom(options.supportZoom);
|
||||||
settings.setTextZoom(options.textZoom);
|
settings.setTextZoom(options.textZoom);
|
||||||
|
@ -192,8 +537,8 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
settings.setAllowFileAccess(options.allowFileAccess);
|
settings.setAllowFileAccess(options.allowFileAccess);
|
||||||
settings.setAllowFileAccessFromFileURLs(options.allowFileAccessFromFileURLs);
|
settings.setAllowFileAccessFromFileURLs(options.allowFileAccessFromFileURLs);
|
||||||
settings.setAllowUniversalAccessFromFileURLs(options.allowUniversalAccessFromFileURLs);
|
settings.setAllowUniversalAccessFromFileURLs(options.allowUniversalAccessFromFileURLs);
|
||||||
settings.setAppCacheEnabled(options.appCacheEnabled);
|
setCacheEnabled(options.cacheEnabled);
|
||||||
if (options.appCachePath != null && !options.appCachePath.isEmpty() && options.appCacheEnabled)
|
if (options.appCachePath != null && !options.appCachePath.isEmpty() && options.cacheEnabled)
|
||||||
settings.setAppCachePath(options.appCachePath);
|
settings.setAppCachePath(options.appCachePath);
|
||||||
settings.setBlockNetworkImage(options.blockNetworkImage);
|
settings.setBlockNetworkImage(options.blockNetworkImage);
|
||||||
settings.setBlockNetworkLoads(options.blockNetworkLoads);
|
settings.setBlockNetworkLoads(options.blockNetworkLoads);
|
||||||
|
@ -212,7 +557,6 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
settings.setGeolocationEnabled(options.geolocationEnabled);
|
settings.setGeolocationEnabled(options.geolocationEnabled);
|
||||||
if (options.layoutAlgorithm != null)
|
if (options.layoutAlgorithm != null)
|
||||||
settings.setLayoutAlgorithm(options.layoutAlgorithm);
|
settings.setLayoutAlgorithm(options.layoutAlgorithm);
|
||||||
settings.setLoadWithOverviewMode(options.loadWithOverviewMode);
|
|
||||||
settings.setLoadsImagesAutomatically(options.loadsImagesAutomatically);
|
settings.setLoadsImagesAutomatically(options.loadsImagesAutomatically);
|
||||||
settings.setMinimumFontSize(options.minimumFontSize);
|
settings.setMinimumFontSize(options.minimumFontSize);
|
||||||
settings.setMinimumLogicalFontSize(options.minimumLogicalFontSize);
|
settings.setMinimumLogicalFontSize(options.minimumLogicalFontSize);
|
||||||
|
@ -237,6 +581,13 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
settings.setSaveFormData(options.saveFormData);
|
||||||
|
if (options.incognito)
|
||||||
|
setIncognito(true);
|
||||||
|
if (options.hardwareAcceleration)
|
||||||
|
setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
||||||
|
else
|
||||||
|
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||||
|
|
||||||
contentBlockerHandler.getRuleList().clear();
|
contentBlockerHandler.getRuleList().clear();
|
||||||
for (Map<String, Map<String, Object>> contentBlocker : options.contentBlockers) {
|
for (Map<String, Map<String, Object>> contentBlocker : options.contentBlockers) {
|
||||||
|
@ -260,6 +611,49 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setIncognito(boolean enabled) {
|
||||||
|
WebSettings settings = getSettings();
|
||||||
|
if (enabled) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
CookieManager.getInstance().removeAllCookies(null);
|
||||||
|
} else {
|
||||||
|
CookieManager.getInstance().removeAllCookie();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable caching
|
||||||
|
settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
|
||||||
|
settings.setAppCacheEnabled(false);
|
||||||
|
clearHistory();
|
||||||
|
clearCache(true);
|
||||||
|
|
||||||
|
// No form data or autofill enabled
|
||||||
|
clearFormData();
|
||||||
|
settings.setSavePassword(false);
|
||||||
|
settings.setSaveFormData(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
settings.setCacheMode(WebSettings.LOAD_DEFAULT);
|
||||||
|
settings.setAppCacheEnabled(true);
|
||||||
|
settings.setSavePassword(true);
|
||||||
|
settings.setSaveFormData(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCacheEnabled(boolean enabled) {
|
||||||
|
WebSettings settings = getSettings();
|
||||||
|
if (enabled) {
|
||||||
|
Context ctx = getContext();
|
||||||
|
if (ctx != null) {
|
||||||
|
settings.setAppCachePath(ctx.getCacheDir().getAbsolutePath());
|
||||||
|
settings.setCacheMode(WebSettings.LOAD_DEFAULT);
|
||||||
|
settings.setAppCacheEnabled(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
|
||||||
|
settings.setAppCacheEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void loadUrl(String url, MethodChannel.Result result) {
|
public void loadUrl(String url, MethodChannel.Result result) {
|
||||||
if (!url.isEmpty()) {
|
if (!url.isEmpty()) {
|
||||||
loadUrl(url);
|
loadUrl(url);
|
||||||
|
@ -393,6 +787,36 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
if (newOptionsMap.get("debuggingEnabled") != null && options.debuggingEnabled != newOptions.debuggingEnabled && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
|
if (newOptionsMap.get("debuggingEnabled") != null && options.debuggingEnabled != newOptions.debuggingEnabled && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
|
||||||
setWebContentsDebuggingEnabled(newOptions.debuggingEnabled);
|
setWebContentsDebuggingEnabled(newOptions.debuggingEnabled);
|
||||||
|
|
||||||
|
if (newOptionsMap.get("useShouldInterceptAjaxRequest") != null && options.useShouldInterceptAjaxRequest != newOptions.useShouldInterceptAjaxRequest) {
|
||||||
|
String placeholderValue = newOptions.useShouldInterceptAjaxRequest ? "true" : "false";
|
||||||
|
String sourceJs = InAppWebView.enableVariableForShouldInterceptAjaxRequestJS.replace("$PLACEHOLDER_VALUE", placeholderValue);
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
|
evaluateJavascript(sourceJs, (ValueCallback<String>) null);
|
||||||
|
} else {
|
||||||
|
loadUrl("javascript:" + sourceJs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newOptionsMap.get("useShouldInterceptFetchRequest") != null && options.useShouldInterceptFetchRequest != newOptions.useShouldInterceptFetchRequest) {
|
||||||
|
String placeholderValue = newOptions.useShouldInterceptFetchRequest ? "true" : "false";
|
||||||
|
String sourceJs = InAppWebView.enableVariableForShouldInterceptFetchRequestsJS.replace("$PLACEHOLDER_VALUE", placeholderValue);
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
|
evaluateJavascript(sourceJs, (ValueCallback<String>) null);
|
||||||
|
} else {
|
||||||
|
loadUrl("javascript:" + sourceJs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newOptionsMap.get("useOnLoadResource") != null && options.useOnLoadResource != newOptions.useOnLoadResource) {
|
||||||
|
String placeholderValue = newOptions.useOnLoadResource ? "true" : "false";
|
||||||
|
String sourceJs = InAppWebView.enableVariableForOnLoadResourceJS.replace("$PLACEHOLDER_VALUE", placeholderValue);
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
|
evaluateJavascript(sourceJs, (ValueCallback<String>) null);
|
||||||
|
} else {
|
||||||
|
loadUrl("javascript:" + sourceJs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (newOptionsMap.get("javaScriptCanOpenWindowsAutomatically") != null && options.javaScriptCanOpenWindowsAutomatically != newOptions.javaScriptCanOpenWindowsAutomatically)
|
if (newOptionsMap.get("javaScriptCanOpenWindowsAutomatically") != null && options.javaScriptCanOpenWindowsAutomatically != newOptions.javaScriptCanOpenWindowsAutomatically)
|
||||||
settings.setJavaScriptCanOpenWindowsAutomatically(newOptions.javaScriptCanOpenWindowsAutomatically);
|
settings.setJavaScriptCanOpenWindowsAutomatically(newOptions.javaScriptCanOpenWindowsAutomatically);
|
||||||
|
|
||||||
|
@ -417,11 +841,22 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
if (newOptionsMap.get("userAgent") != null && !options.userAgent.equals(newOptions.userAgent) && !newOptions.userAgent.isEmpty())
|
if (newOptionsMap.get("userAgent") != null && !options.userAgent.equals(newOptions.userAgent) && !newOptions.userAgent.isEmpty())
|
||||||
settings.setUserAgentString(newOptions.userAgent);
|
settings.setUserAgentString(newOptions.userAgent);
|
||||||
|
|
||||||
|
if (newOptionsMap.get("applicationNameForUserAgent") != null && !options.applicationNameForUserAgent.equals(newOptions.applicationNameForUserAgent) && !newOptions.applicationNameForUserAgent.isEmpty()) {
|
||||||
|
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||||
|
String userAgent = (newOptions.userAgent != null && !newOptions.userAgent.isEmpty()) ? newOptions.userAgent : WebSettings.getDefaultUserAgent(getContext());
|
||||||
|
String userAgentWithApplicationName = userAgent + " " + options.applicationNameForUserAgent;
|
||||||
|
settings.setUserAgentString(userAgentWithApplicationName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (newOptionsMap.get("clearCache") != null && newOptions.clearCache)
|
if (newOptionsMap.get("clearCache") != null && newOptions.clearCache)
|
||||||
clearAllCache();
|
clearAllCache();
|
||||||
else if (newOptionsMap.get("clearSessionCache") != null && newOptions.clearSessionCache)
|
else if (newOptionsMap.get("clearSessionCache") != null && newOptions.clearSessionCache)
|
||||||
CookieManager.getInstance().removeSessionCookie();
|
CookieManager.getInstance().removeSessionCookie();
|
||||||
|
|
||||||
|
if (newOptionsMap.get("thirdPartyCookiesEnabled") != null && options.thirdPartyCookiesEnabled != newOptions.thirdPartyCookiesEnabled && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
CookieManager.getInstance().setAcceptThirdPartyCookies(this, newOptions.thirdPartyCookiesEnabled);
|
||||||
|
|
||||||
if (newOptionsMap.get("useWideViewPort") != null && options.useWideViewPort != newOptions.useWideViewPort)
|
if (newOptionsMap.get("useWideViewPort") != null && options.useWideViewPort != newOptions.useWideViewPort)
|
||||||
settings.setUseWideViewPort(newOptions.useWideViewPort);
|
settings.setUseWideViewPort(newOptions.useWideViewPort);
|
||||||
|
|
||||||
|
@ -472,12 +907,11 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
if (newOptionsMap.get("allowUniversalAccessFromFileURLs") != null && options.allowUniversalAccessFromFileURLs != newOptions.allowUniversalAccessFromFileURLs)
|
if (newOptionsMap.get("allowUniversalAccessFromFileURLs") != null && options.allowUniversalAccessFromFileURLs != newOptions.allowUniversalAccessFromFileURLs)
|
||||||
settings.setAllowUniversalAccessFromFileURLs(newOptions.allowUniversalAccessFromFileURLs);
|
settings.setAllowUniversalAccessFromFileURLs(newOptions.allowUniversalAccessFromFileURLs);
|
||||||
|
|
||||||
if (newOptionsMap.get("appCacheEnabled") != null && options.appCacheEnabled != newOptions.appCacheEnabled)
|
if (newOptionsMap.get("cacheEnabled") != null && options.cacheEnabled != newOptions.cacheEnabled)
|
||||||
settings.setAppCacheEnabled(newOptions.appCacheEnabled);
|
setCacheEnabled(newOptions.cacheEnabled);
|
||||||
|
|
||||||
if (newOptionsMap.get("appCachePath") != null && !options.appCachePath.equals(newOptions.appCachePath))
|
if (newOptionsMap.get("appCachePath") != null && !options.appCachePath.equals(newOptions.appCachePath))
|
||||||
if (newOptions.appCacheEnabled)
|
settings.setAppCachePath(newOptions.appCachePath);
|
||||||
settings.setAppCachePath(newOptions.appCachePath);
|
|
||||||
|
|
||||||
if (newOptionsMap.get("blockNetworkImage") != null && options.blockNetworkImage != newOptions.blockNetworkImage)
|
if (newOptionsMap.get("blockNetworkImage") != null && options.blockNetworkImage != newOptions.blockNetworkImage)
|
||||||
settings.setBlockNetworkImage(newOptions.blockNetworkImage);
|
settings.setBlockNetworkImage(newOptions.blockNetworkImage);
|
||||||
|
@ -551,6 +985,19 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
if (newOptionsMap.get("standardFontFamily") != null && !options.standardFontFamily.equals(newOptions.standardFontFamily))
|
if (newOptionsMap.get("standardFontFamily") != null && !options.standardFontFamily.equals(newOptions.standardFontFamily))
|
||||||
settings.setStandardFontFamily(newOptions.standardFontFamily);
|
settings.setStandardFontFamily(newOptions.standardFontFamily);
|
||||||
|
|
||||||
|
if (newOptionsMap.get("saveFormData") != null && options.saveFormData != newOptions.saveFormData)
|
||||||
|
settings.setSaveFormData(newOptions.saveFormData);
|
||||||
|
|
||||||
|
if (newOptionsMap.get("incognito") != null && options.incognito != newOptions.incognito)
|
||||||
|
setIncognito(newOptions.incognito);
|
||||||
|
|
||||||
|
if (newOptionsMap.get("hardwareAcceleration") != null && options.hardwareAcceleration != newOptions.hardwareAcceleration) {
|
||||||
|
if (newOptions.hardwareAcceleration)
|
||||||
|
setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
||||||
|
else
|
||||||
|
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||||
|
}
|
||||||
|
|
||||||
if (newOptions.contentBlockers != null) {
|
if (newOptions.contentBlockers != null) {
|
||||||
contentBlockerHandler.getRuleList().clear();
|
contentBlockerHandler.getRuleList().clear();
|
||||||
for (Map<String, Map<String, Object>> contentBlocker : newOptions.contentBlockers) {
|
for (Map<String, Map<String, Object>> contentBlocker : newOptions.contentBlockers) {
|
||||||
|
@ -630,22 +1077,22 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void injectScriptCode(String source, MethodChannel.Result result) {
|
public void evaluateJavascript(String source, MethodChannel.Result result) {
|
||||||
String jsWrapper = "(function(){return JSON.stringify(eval(%s));})();";
|
String jsWrapper = "(function(){return JSON.stringify(eval(%s));})();";
|
||||||
injectDeferredObject(source, jsWrapper, result);
|
injectDeferredObject(source, jsWrapper, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void injectScriptFile(String urlFile) {
|
public void injectJavascriptFileFromUrl(String urlFile) {
|
||||||
String jsWrapper = "(function(d) { var c = d.createElement('script'); c.src = %s; d.body.appendChild(c); })(document);";
|
String jsWrapper = "(function(d) { var c = d.createElement('script'); c.src = %s; d.body.appendChild(c); })(document);";
|
||||||
injectDeferredObject(urlFile, jsWrapper, null);
|
injectDeferredObject(urlFile, jsWrapper, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void injectStyleCode(String source) {
|
public void injectCSSCode(String source) {
|
||||||
String jsWrapper = "(function(d) { var c = d.createElement('style'); c.innerHTML = %s; d.body.appendChild(c); })(document);";
|
String jsWrapper = "(function(d) { var c = d.createElement('style'); c.innerHTML = %s; d.body.appendChild(c); })(document);";
|
||||||
injectDeferredObject(source, jsWrapper, null);
|
injectDeferredObject(source, jsWrapper, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void injectStyleFile(String urlFile) {
|
public void injectCSSFileFromUrl(String urlFile) {
|
||||||
String jsWrapper = "(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %s; d.head.appendChild(c); })(document);";
|
String jsWrapper = "(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %s; d.head.appendChild(c); })(document);";
|
||||||
injectDeferredObject(urlFile, jsWrapper, null);
|
injectDeferredObject(urlFile, jsWrapper, null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import android.net.http.SslCertificate;
|
||||||
import android.net.http.SslError;
|
import android.net.http.SslError;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Base64;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.webkit.ClientCertRequest;
|
import android.webkit.ClientCertRequest;
|
||||||
import android.webkit.CookieManager;
|
import android.webkit.CookieManager;
|
||||||
|
@ -51,9 +50,9 @@ public class InAppWebViewClient extends WebViewClient {
|
||||||
private FlutterWebView flutterWebView;
|
private FlutterWebView flutterWebView;
|
||||||
private InAppBrowserActivity inAppBrowserActivity;
|
private InAppBrowserActivity inAppBrowserActivity;
|
||||||
Map<Integer, String> statusCodeMapping = new HashMap<Integer, String>();
|
Map<Integer, String> statusCodeMapping = new HashMap<Integer, String>();
|
||||||
long startPageTime = 0;
|
|
||||||
private static int previousAuthRequestFailureCount = 0;
|
private static int previousAuthRequestFailureCount = 0;
|
||||||
private static List<Credential> credentialsProposed = null;
|
private static List<Credential> credentialsProposed = null;
|
||||||
|
private String onPageStartedURL = "";
|
||||||
|
|
||||||
public InAppWebViewClient(Object obj) {
|
public InAppWebViewClient(Object obj) {
|
||||||
super();
|
super();
|
||||||
|
@ -61,60 +60,7 @@ public class InAppWebViewClient extends WebViewClient {
|
||||||
this.inAppBrowserActivity = (InAppBrowserActivity) obj;
|
this.inAppBrowserActivity = (InAppBrowserActivity) obj;
|
||||||
else if (obj instanceof FlutterWebView)
|
else if (obj instanceof FlutterWebView)
|
||||||
this.flutterWebView = (FlutterWebView) obj;
|
this.flutterWebView = (FlutterWebView) obj;
|
||||||
prepareStatusCodeMapping();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareStatusCodeMapping() {
|
|
||||||
statusCodeMapping.put(100, "Continue");
|
|
||||||
statusCodeMapping.put(101, "Switching Protocols");
|
|
||||||
statusCodeMapping.put(200, "OK");
|
|
||||||
statusCodeMapping.put(201, "Created");
|
|
||||||
statusCodeMapping.put(202, "Accepted");
|
|
||||||
statusCodeMapping.put(203, "Non-Authoritative Information");
|
|
||||||
statusCodeMapping.put(204, "No Content");
|
|
||||||
statusCodeMapping.put(205, "Reset Content");
|
|
||||||
statusCodeMapping.put(206, "Partial Content");
|
|
||||||
statusCodeMapping.put(300, "Multiple Choices");
|
|
||||||
statusCodeMapping.put(301, "Moved Permanently");
|
|
||||||
statusCodeMapping.put(302, "Found");
|
|
||||||
statusCodeMapping.put(303, "See Other");
|
|
||||||
statusCodeMapping.put(304, "Not Modified");
|
|
||||||
statusCodeMapping.put(307, "Temporary Redirect");
|
|
||||||
statusCodeMapping.put(308, "Permanent Redirect");
|
|
||||||
statusCodeMapping.put(400, "Bad Request");
|
|
||||||
statusCodeMapping.put(401, "Unauthorized");
|
|
||||||
statusCodeMapping.put(403, "Forbidden");
|
|
||||||
statusCodeMapping.put(404, "Not Found");
|
|
||||||
statusCodeMapping.put(405, "Method Not Allowed");
|
|
||||||
statusCodeMapping.put(406, "Not Acceptable");
|
|
||||||
statusCodeMapping.put(407, "Proxy Authentication Required");
|
|
||||||
statusCodeMapping.put(408, "Request Timeout");
|
|
||||||
statusCodeMapping.put(409, "Conflict");
|
|
||||||
statusCodeMapping.put(410, "Gone");
|
|
||||||
statusCodeMapping.put(411, "Length Required");
|
|
||||||
statusCodeMapping.put(412, "Precondition Failed");
|
|
||||||
statusCodeMapping.put(413, "Payload Too Large");
|
|
||||||
statusCodeMapping.put(414, "URI Too Long");
|
|
||||||
statusCodeMapping.put(415, "Unsupported Media Type");
|
|
||||||
statusCodeMapping.put(416, "Range Not Satisfiable");
|
|
||||||
statusCodeMapping.put(417, "Expectation Failed");
|
|
||||||
statusCodeMapping.put(418, "I'm a teapot");
|
|
||||||
statusCodeMapping.put(422, "Unprocessable Entity");
|
|
||||||
statusCodeMapping.put(425, "Too Early");
|
|
||||||
statusCodeMapping.put(426, "Upgrade Required");
|
|
||||||
statusCodeMapping.put(428, "Precondition Required");
|
|
||||||
statusCodeMapping.put(429, "Too Many Requests");
|
|
||||||
statusCodeMapping.put(431, "Request Header Fields Too Large");
|
|
||||||
statusCodeMapping.put(451, "Unavailable For Legal Reasons");
|
|
||||||
statusCodeMapping.put(500, "Internal Server Error");
|
|
||||||
statusCodeMapping.put(501, "Not Implemented");
|
|
||||||
statusCodeMapping.put(502, "Bad Gateway");
|
|
||||||
statusCodeMapping.put(503, "Service Unavailable");
|
|
||||||
statusCodeMapping.put(504, "Gateway Timeout");
|
|
||||||
statusCodeMapping.put(505, "HTTP Version Not Supported");
|
|
||||||
statusCodeMapping.put(511, "Network Authentication Required");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldOverrideUrlLoading(WebView webView, String url) {
|
public boolean shouldOverrideUrlLoading(WebView webView, String url) {
|
||||||
|
|
||||||
|
@ -183,25 +129,26 @@ public class InAppWebViewClient extends WebViewClient {
|
||||||
return super.shouldOverrideUrlLoading(webView, url);
|
return super.shouldOverrideUrlLoading(webView, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* onPageStarted fires the LOAD_START_EVENT
|
|
||||||
*
|
|
||||||
* @param view
|
|
||||||
* @param url
|
|
||||||
* @param favicon
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void onPageStarted(WebView view, String url, Bitmap favicon) {
|
public void onPageStarted(WebView view, String url, Bitmap favicon) {
|
||||||
|
|
||||||
InAppWebView webView = (InAppWebView) view;
|
InAppWebView webView = (InAppWebView) view;
|
||||||
|
|
||||||
if (webView.options.useOnLoadResource)
|
webView.loadUrl("javascript:" + InAppWebView.consoleLogJS.replaceAll("[\r\n]+", ""));
|
||||||
webView.loadUrl("javascript:" + webView.resourceObserverJS.replaceAll("[\r\n]+", ""));
|
webView.loadUrl("javascript:" + JavaScriptBridgeInterface.flutterInAppBroserJSClass.replaceAll("[\r\n]+", ""));
|
||||||
|
if (webView.options.useShouldInterceptAjaxRequest) {
|
||||||
|
webView.loadUrl("javascript:" + InAppWebView.interceptAjaxRequestsJS.replaceAll("[\r\n]+", ""));
|
||||||
|
}
|
||||||
|
if (webView.options.useShouldInterceptFetchRequest) {
|
||||||
|
webView.loadUrl("javascript:" + InAppWebView.interceptFetchRequestsJS.replaceAll("[\r\n]+", ""));
|
||||||
|
}
|
||||||
|
if (webView.options.useOnLoadResource) {
|
||||||
|
webView.loadUrl("javascript:" + InAppWebView.resourceObserverJS.replaceAll("[\r\n]+", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
onPageStartedURL = url;
|
||||||
super.onPageStarted(view, url, favicon);
|
super.onPageStarted(view, url, favicon);
|
||||||
|
|
||||||
startPageTime = System.currentTimeMillis();
|
|
||||||
webView.isLoading = true;
|
webView.isLoading = true;
|
||||||
if (inAppBrowserActivity != null && inAppBrowserActivity.searchView != null && !url.equals(inAppBrowserActivity.searchView.getQuery().toString())) {
|
if (inAppBrowserActivity != null && inAppBrowserActivity.searchView != null && !url.equals(inAppBrowserActivity.searchView.getQuery().toString())) {
|
||||||
inAppBrowserActivity.searchView.setQuery(url, false);
|
inAppBrowserActivity.searchView.setQuery(url, false);
|
||||||
|
@ -215,8 +162,8 @@ public class InAppWebViewClient extends WebViewClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void onPageFinished(final WebView view, String url) {
|
public void onPageFinished(WebView view, String url) {
|
||||||
InAppWebView webView = (InAppWebView) view;
|
final InAppWebView webView = (InAppWebView) view;
|
||||||
|
|
||||||
super.onPageFinished(view, url);
|
super.onPageFinished(view, url);
|
||||||
|
|
||||||
|
@ -236,18 +183,9 @@ public class InAppWebViewClient extends WebViewClient {
|
||||||
view.requestFocus();
|
view.requestFocus();
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
view.evaluateJavascript(InAppWebView.consoleLogJS, null);
|
webView.evaluateJavascript(InAppWebView.platformReadyJS, (ValueCallback<String>) null);
|
||||||
view.evaluateJavascript(JavaScriptBridgeInterface.flutterInAppBroserJSClass, new ValueCallback<String>() {
|
|
||||||
@Override
|
|
||||||
public void onReceiveValue(String value) {
|
|
||||||
view.evaluateJavascript(InAppWebView.platformReadyJS, null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
view.loadUrl("javascript:" + InAppWebView.consoleLogJS);
|
webView.loadUrl("javascript:" + InAppWebView.platformReadyJS.replaceAll("[\r\n]+", ""));
|
||||||
view.loadUrl("javascript:" + JavaScriptBridgeInterface.flutterInAppBroserJSClass);
|
|
||||||
view.loadUrl("javascript:" + InAppWebView.platformReadyJS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, Object> obj = new HashMap<>();
|
Map<String, Object> obj = new HashMap<>();
|
||||||
|
@ -257,6 +195,21 @@ public class InAppWebViewClient extends WebViewClient {
|
||||||
getChannel().invokeMethod("onLoadStop", obj);
|
getChannel().invokeMethod("onLoadStop", obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doUpdateVisitedHistory (WebView view, String url, boolean isReload) {
|
||||||
|
super.doUpdateVisitedHistory(view, url, isReload);
|
||||||
|
|
||||||
|
if (!isReload && !url.equals(onPageStartedURL)) {
|
||||||
|
onPageStartedURL = "";
|
||||||
|
Map<String, Object> obj = new HashMap<>();
|
||||||
|
if (inAppBrowserActivity != null)
|
||||||
|
obj.put("uuid", inAppBrowserActivity.uuid);
|
||||||
|
obj.put("url", url);
|
||||||
|
getChannel().invokeMethod("onNavigationStateChange", obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
|
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
|
||||||
super.onReceivedError(view, errorCode, description, failingUrl);
|
super.onReceivedError(view, errorCode, description, failingUrl);
|
||||||
|
|
||||||
|
|
|
@ -12,42 +12,46 @@ public class InAppWebViewOptions extends Options {
|
||||||
|
|
||||||
public static final String LOG_TAG = "InAppWebViewOptions";
|
public static final String LOG_TAG = "InAppWebViewOptions";
|
||||||
|
|
||||||
public boolean useShouldOverrideUrlLoading = false;
|
public Boolean useShouldOverrideUrlLoading = false;
|
||||||
public boolean useOnLoadResource = false;
|
public Boolean useOnLoadResource = false;
|
||||||
public boolean useOnDownloadStart = false;
|
public Boolean useOnDownloadStart = false;
|
||||||
public boolean useOnTargetBlank = false;
|
public Boolean useOnTargetBlank = false;
|
||||||
public boolean clearCache = false;
|
public Boolean clearCache = false;
|
||||||
public String userAgent = "";
|
public String userAgent = "";
|
||||||
public boolean javaScriptEnabled = true;
|
public String applicationNameForUserAgent = "";
|
||||||
public boolean debuggingEnabled = false;
|
public Boolean javaScriptEnabled = true;
|
||||||
public boolean javaScriptCanOpenWindowsAutomatically = false;
|
public Boolean debuggingEnabled = false;
|
||||||
public boolean mediaPlaybackRequiresUserGesture = true;
|
public Boolean javaScriptCanOpenWindowsAutomatically = false;
|
||||||
|
public Boolean mediaPlaybackRequiresUserGesture = true;
|
||||||
public Integer textZoom = 100;
|
public Integer textZoom = 100;
|
||||||
public Integer minimumFontSize = 8;
|
public Integer minimumFontSize = 8;
|
||||||
public boolean verticalScrollBarEnabled = true;
|
public Boolean verticalScrollBarEnabled = true;
|
||||||
public boolean horizontalScrollBarEnabled = true;
|
public Boolean horizontalScrollBarEnabled = true;
|
||||||
public List<String> resourceCustomSchemes = new ArrayList<>();
|
public List<String> resourceCustomSchemes = new ArrayList<>();
|
||||||
public List<Map<String, Map<String, Object>>> contentBlockers = new ArrayList<>();
|
public List<Map<String, Map<String, Object>>> contentBlockers = new ArrayList<>();
|
||||||
public Integer preferredContentMode = PreferredContentModeOptionType.RECOMMENDED.toValue();
|
public Integer preferredContentMode = PreferredContentModeOptionType.RECOMMENDED.toValue();
|
||||||
|
public Boolean useShouldInterceptAjaxRequest = false;
|
||||||
|
public Boolean useShouldInterceptFetchRequest = false;
|
||||||
|
public Boolean incognito = false;
|
||||||
|
public Boolean cacheEnabled = true;
|
||||||
|
public Boolean transparentBackground = false;
|
||||||
|
|
||||||
public boolean clearSessionCache = false;
|
public Boolean clearSessionCache = false;
|
||||||
public boolean builtInZoomControls = false;
|
public Boolean builtInZoomControls = false;
|
||||||
public boolean displayZoomControls = false;
|
public Boolean displayZoomControls = false;
|
||||||
public boolean supportZoom = true;
|
public Boolean supportZoom = true;
|
||||||
public boolean databaseEnabled = false;
|
public Boolean databaseEnabled = false;
|
||||||
public boolean domStorageEnabled = false;
|
public Boolean domStorageEnabled = false;
|
||||||
public boolean useWideViewPort = true;
|
public Boolean useWideViewPort = true;
|
||||||
public boolean safeBrowsingEnabled = true;
|
public Boolean safeBrowsingEnabled = true;
|
||||||
public boolean transparentBackground = false;
|
|
||||||
public Integer mixedContentMode;
|
public Integer mixedContentMode;
|
||||||
public boolean allowContentAccess = true;
|
public Boolean allowContentAccess = true;
|
||||||
public boolean allowFileAccess = true;
|
public Boolean allowFileAccess = true;
|
||||||
public boolean allowFileAccessFromFileURLs = true;
|
public Boolean allowFileAccessFromFileURLs = true;
|
||||||
public boolean allowUniversalAccessFromFileURLs = true;
|
public Boolean allowUniversalAccessFromFileURLs = true;
|
||||||
public boolean appCacheEnabled = true;
|
|
||||||
public String appCachePath;
|
public String appCachePath;
|
||||||
public boolean blockNetworkImage = false;
|
public Boolean blockNetworkImage = false;
|
||||||
public boolean blockNetworkLoads = false;
|
public Boolean blockNetworkLoads = false;
|
||||||
public Integer cacheMode = WebSettings.LOAD_DEFAULT;
|
public Integer cacheMode = WebSettings.LOAD_DEFAULT;
|
||||||
public String cursiveFontFamily = "cursive";
|
public String cursiveFontFamily = "cursive";
|
||||||
public Integer defaultFixedFontSize = 16;
|
public Integer defaultFixedFontSize = 16;
|
||||||
|
@ -57,15 +61,18 @@ public class InAppWebViewOptions extends Options {
|
||||||
public String fantasyFontFamily = "fantasy";
|
public String fantasyFontFamily = "fantasy";
|
||||||
public String fixedFontFamily = "monospace";
|
public String fixedFontFamily = "monospace";
|
||||||
public Integer forceDark = 0; // WebSettings.FORCE_DARK_OFF
|
public Integer forceDark = 0; // WebSettings.FORCE_DARK_OFF
|
||||||
public boolean geolocationEnabled = true;
|
public Boolean geolocationEnabled = true;
|
||||||
public WebSettings.LayoutAlgorithm layoutAlgorithm;
|
public WebSettings.LayoutAlgorithm layoutAlgorithm;
|
||||||
public boolean loadWithOverviewMode = true;
|
public Boolean loadWithOverviewMode = true;
|
||||||
public boolean loadsImagesAutomatically = true;
|
public Boolean loadsImagesAutomatically = true;
|
||||||
public Integer minimumLogicalFontSize = 8;
|
public Integer minimumLogicalFontSize = 8;
|
||||||
public Integer initialScale;
|
public Integer initialScale;
|
||||||
public boolean needInitialFocus = true;
|
public Boolean needInitialFocus = true;
|
||||||
public boolean offscreenPreRaster = false;
|
public Boolean offscreenPreRaster = false;
|
||||||
public String sansSerifFontFamily = "sans-serif";
|
public String sansSerifFontFamily = "sans-serif";
|
||||||
public String serifFontFamily = "sans-serif";
|
public String serifFontFamily = "sans-serif";
|
||||||
public String standardFontFamily = "sans-serif";
|
public String standardFontFamily = "sans-serif";
|
||||||
|
public Boolean saveFormData = true;
|
||||||
|
public Boolean thirdPartyCookiesEnabled = true;
|
||||||
|
public Boolean hardwareAcceleration = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ public class JavaScriptBridgeInterface {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
webView.evaluateJavascript("window." + name + "[" + _callHandlerID + "](" + json + "); delete window." + name + "[" + _callHandlerID + "];", null);
|
webView.evaluateJavascript("window." + name + "[" + _callHandlerID + "](" + json + "); delete window." + name + "[" + _callHandlerID + "];", (MethodChannel.Result) null);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
webView.loadUrl("javascript:window." + name + "[" + _callHandlerID + "](" + json + "); delete window." + name + "[" + _callHandlerID + "];");
|
webView.loadUrl("javascript:window." + name + "[" + _callHandlerID + "](" + json + "); delete window." + name + "[" + _callHandlerID + "];");
|
||||||
|
@ -82,42 +82,6 @@ public class JavaScriptBridgeInterface {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@JavascriptInterface
|
|
||||||
public void _resourceLoaded(String json) {
|
|
||||||
try {
|
|
||||||
|
|
||||||
JSONObject jsonObject = new JSONObject(json);
|
|
||||||
|
|
||||||
final Map<String, Object> obj = new HashMap<>();
|
|
||||||
|
|
||||||
if (inAppBrowserActivity != null)
|
|
||||||
obj.put("uuid", inAppBrowserActivity.uuid);
|
|
||||||
|
|
||||||
String initiatorType = jsonObject.getString("initiatorType");
|
|
||||||
String url = jsonObject.getString("name");
|
|
||||||
Double startTime = jsonObject.getDouble("startTime");
|
|
||||||
Double duration = jsonObject.getDouble("duration");
|
|
||||||
|
|
||||||
obj.put("initiatorType", initiatorType);
|
|
||||||
obj.put("url", url);
|
|
||||||
obj.put("startTime", startTime);
|
|
||||||
obj.put("duration", duration);
|
|
||||||
|
|
||||||
// java.lang.RuntimeException: Methods marked with @UiThread must be executed on the main thread.
|
|
||||||
// https://github.com/pichillilorenzo/flutter_inappbrowser/issues/98
|
|
||||||
final Handler handler = new Handler(Looper.getMainLooper());
|
|
||||||
handler.post(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
getChannel().invokeMethod("onLoadResource", obj);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch (final JSONException e) {
|
|
||||||
Log.e(LOG_TAG, "Json parsing error: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private MethodChannel getChannel() {
|
private MethodChannel getChannel() {
|
||||||
return (inAppBrowserActivity != null) ? InAppBrowserFlutterPlugin.inAppBrowser.channel : flutterWebView.channel;
|
return (inAppBrowserActivity != null) ? InAppBrowserFlutterPlugin.inAppBrowser.channel : flutterWebView.channel;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,11 @@
|
||||||
<option value="1">option 1</option>
|
<option value="1">option 1</option>
|
||||||
<option value="2">option 2</option>
|
<option value="2">option 2</option>
|
||||||
</select>
|
</select>
|
||||||
|
<input type="file">
|
||||||
|
<input type="file" accept="image/*" capture>
|
||||||
|
<button onclick="testHistoryPush1()">History Push 1</button>
|
||||||
|
<button onclick="testHistoryPush2()">History Push 2</button>
|
||||||
|
<button onclick="testLocationHref()">Location Href</button>
|
||||||
<p>
|
<p>
|
||||||
<img src="https://via.placeholder.com/100x50" alt="placeholder 100x50">
|
<img src="https://via.placeholder.com/100x50" alt="placeholder 100x50">
|
||||||
</p>
|
</p>
|
||||||
|
@ -51,27 +56,82 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
var state = { 'page_id': 1, 'user_id': 5 };
|
||||||
|
function testHistoryPush1() {
|
||||||
|
var randomNumber = 100 * Math.random();
|
||||||
|
var title = 'Hello World ' + randomNumber;
|
||||||
|
var url = 'hello-foo-' + randomNumber + '.html';
|
||||||
|
history.pushState(state, title, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testHistoryPush2() {
|
||||||
|
var randomNumber = 100 * Math.random();
|
||||||
|
var title = 'Hello World ' + randomNumber;
|
||||||
|
var url = 'hello-bar-' + randomNumber + '.html';
|
||||||
|
history.replaceState(state, title, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testLocationHref() {
|
||||||
|
var randomNumber = 100 * Math.random();
|
||||||
|
window.location = "#foo-" + randomNumber;
|
||||||
|
}
|
||||||
|
|
||||||
window.addEventListener("flutterInAppBrowserPlatformReady", function(event) {
|
window.addEventListener("flutterInAppBrowserPlatformReady", function(event) {
|
||||||
console.log("ready");
|
console.log("ready");
|
||||||
|
|
||||||
window.flutter_inappbrowser.callHandler('handlerFoo').then(function(result) {
|
window.flutter_inappbrowser.callHandler('handlerFoo').then(function(result) {
|
||||||
console.log(result, typeof result);
|
//console.log(result, typeof result);
|
||||||
console.log(JSON.stringify(result), result.bar);
|
//console.log(JSON.stringify(result), result.bar);
|
||||||
});
|
});
|
||||||
|
|
||||||
window.flutter_inappbrowser.callHandler('handlerFooWithArgs', 1, true, ['bar', 5], {foo: 'baz'}).then(function(result) {
|
window.flutter_inappbrowser.callHandler('handlerFooWithArgs', 1, true, ['bar', 5], {foo: 'baz'}).then(function(result) {
|
||||||
console.log(result, typeof result);
|
//console.log(result, typeof result);
|
||||||
console.log(JSON.stringify(result));
|
//console.log(JSON.stringify(result));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
|
||||||
|
console.log("jQuery ready");
|
||||||
|
|
||||||
|
var xhttp = new XMLHttpRequest();
|
||||||
|
xhttp.addEventListener("load", function() {
|
||||||
|
console.log(this.responseText);
|
||||||
|
});
|
||||||
|
xhttp.open("POST", "http://192.168.1.20:8082/test-ajax-post");
|
||||||
|
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||||
|
xhttp.send("name=Lorenzo");
|
||||||
|
|
||||||
|
var xhttp2 = new XMLHttpRequest();
|
||||||
|
xhttp2.open("GET", "http://192.168.1.20:8082/test-download-file");
|
||||||
|
xhttp2.send();
|
||||||
|
|
||||||
|
fetch(new Request("http://192.168.1.20:8082/test-download-file")).then(function(response) {
|
||||||
|
console.log(response);
|
||||||
|
}).catch(function(error) {
|
||||||
|
console.error("ERROR: " + error);
|
||||||
|
});
|
||||||
|
|
||||||
|
fetch("http://192.168.1.20:8082/test-ajax-post", {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({
|
||||||
|
name: 'Lorenzo Fetch API'
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
}).then(function(response) {
|
||||||
|
console.log(response);
|
||||||
|
}).catch(function(error) {
|
||||||
|
console.error("ERROR: " + error);
|
||||||
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
alert("Alert Popup");
|
alert("Alert Popup");
|
||||||
console.log(confirm("Press a button!"));
|
console.log(confirm("Press a button!"));
|
||||||
console.log(prompt("Please enter your name", "Lorenzo"));
|
console.log(prompt("Please enter your name", "Lorenzo"));
|
||||||
*/
|
*/
|
||||||
|
|
||||||
console.log("jQuery ready");
|
|
||||||
/*
|
/*
|
||||||
if ("geolocation" in navigator) {
|
if ("geolocation" in navigator) {
|
||||||
console.log("Geolocation API enabled");
|
console.log("Geolocation API enabled");
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
# This is a generated file; do not edit or check into version control.
|
# This is a generated file; do not edit or check into version control.
|
||||||
export "FLUTTER_ROOT=/Users/lorenzopichilli/flutter"
|
export "FLUTTER_ROOT=/Users/lorenzopichilli/flutter"
|
||||||
export "FLUTTER_APPLICATION_PATH=/Users/lorenzopichilli/Desktop/flutter_inappbrowser/example"
|
export "FLUTTER_APPLICATION_PATH=/Users/lorenzopichilli/Desktop/flutter_inappbrowser/example"
|
||||||
export "FLUTTER_TARGET=lib/main.dart"
|
export "FLUTTER_TARGET=/Users/lorenzopichilli/Desktop/flutter_inappbrowser/example/lib/main.dart"
|
||||||
export "FLUTTER_BUILD_DIR=build"
|
export "FLUTTER_BUILD_DIR=build"
|
||||||
export "SYMROOT=${SOURCE_ROOT}/../build/ios"
|
export "SYMROOT=${SOURCE_ROOT}/../build/ios"
|
||||||
export "FLUTTER_FRAMEWORK_DIR=/Users/lorenzopichilli/flutter/bin/cache/artifacts/engine/ios"
|
export "FLUTTER_FRAMEWORK_DIR=/Users/lorenzopichilli/flutter/bin/cache/artifacts/engine/ios"
|
||||||
export "FLUTTER_BUILD_NAME=1.0.0"
|
export "FLUTTER_BUILD_NAME=1.0.0"
|
||||||
export "FLUTTER_BUILD_NUMBER=1"
|
export "FLUTTER_BUILD_NUMBER=1"
|
||||||
|
export "TRACK_WIDGET_CREATION=true"
|
||||||
|
|
|
@ -268,7 +268,6 @@
|
||||||
inputPaths = (
|
inputPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
|
||||||
"${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework",
|
"${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/WKWebViewWithURLProtocol/WKWebViewWithURLProtocol.framework",
|
|
||||||
"${BUILT_PRODUCTS_DIR}/flutter_downloader/flutter_downloader.framework",
|
"${BUILT_PRODUCTS_DIR}/flutter_downloader/flutter_downloader.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/flutter_inappbrowser/flutter_inappbrowser.framework",
|
"${BUILT_PRODUCTS_DIR}/flutter_inappbrowser/flutter_inappbrowser.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/path_provider/path_provider.framework",
|
"${BUILT_PRODUCTS_DIR}/path_provider/path_provider.framework",
|
||||||
|
@ -276,7 +275,6 @@
|
||||||
name = "[CP] Embed Pods Frameworks";
|
name = "[CP] Embed Pods Frameworks";
|
||||||
outputPaths = (
|
outputPaths = (
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/WKWebViewWithURLProtocol.framework",
|
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_downloader.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_downloader.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_inappbrowser.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_inappbrowser.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider.framework",
|
||||||
|
|
|
@ -96,8 +96,10 @@ class _InlineExampleScreenState extends State<InlineExampleScreen> {
|
||||||
//clearCache: true,
|
//clearCache: true,
|
||||||
useShouldOverrideUrlLoading: true,
|
useShouldOverrideUrlLoading: true,
|
||||||
useOnTargetBlank: true,
|
useOnTargetBlank: true,
|
||||||
//useOnLoadResource: true,
|
useOnLoadResource: true,
|
||||||
useOnDownloadStart: true,
|
useOnDownloadStart: true,
|
||||||
|
useShouldInterceptAjaxRequest: true,
|
||||||
|
useShouldInterceptFetchRequest: true,
|
||||||
//preferredContentMode: InAppWebViewUserPreferredContentMode.DESKTOP,
|
//preferredContentMode: InAppWebViewUserPreferredContentMode.DESKTOP,
|
||||||
resourceCustomSchemes: ["my-special-custom-scheme"],
|
resourceCustomSchemes: ["my-special-custom-scheme"],
|
||||||
contentBlockers: [
|
contentBlockers: [
|
||||||
|
@ -111,7 +113,6 @@ class _InlineExampleScreenState extends State<InlineExampleScreen> {
|
||||||
),
|
),
|
||||||
androidInAppWebViewOptions: AndroidInAppWebViewOptions(
|
androidInAppWebViewOptions: AndroidInAppWebViewOptions(
|
||||||
databaseEnabled: true,
|
databaseEnabled: true,
|
||||||
appCacheEnabled: true,
|
|
||||||
domStorageEnabled: true,
|
domStorageEnabled: true,
|
||||||
geolocationEnabled: true,
|
geolocationEnabled: true,
|
||||||
//safeBrowsingEnabled: true,
|
//safeBrowsingEnabled: true,
|
||||||
|
@ -286,6 +287,36 @@ class _InlineExampleScreenState extends State<InlineExampleScreen> {
|
||||||
onFindResultReceived: (InAppWebViewController controller, int activeMatchOrdinal, int numberOfMatches, bool isDoneCounting) async {
|
onFindResultReceived: (InAppWebViewController controller, int activeMatchOrdinal, int numberOfMatches, bool isDoneCounting) async {
|
||||||
print("Current highlighted: $activeMatchOrdinal, Number of matches found: $numberOfMatches, find operation completed: $isDoneCounting");
|
print("Current highlighted: $activeMatchOrdinal, Number of matches found: $numberOfMatches, find operation completed: $isDoneCounting");
|
||||||
},
|
},
|
||||||
|
shouldInterceptAjaxRequest: (InAppWebViewController controller, AjaxRequest ajaxRequest) async {
|
||||||
|
//print("AJAX REQUEST: ${ajaxRequest.method} - ${ajaxRequest.url}, DATA: ${ajaxRequest.data}");
|
||||||
|
// ajaxRequest.method = "GET";
|
||||||
|
// ajaxRequest.url = "http://192.168.1.20:8082/test-download-file";
|
||||||
|
// ajaxRequest.headers = {
|
||||||
|
// "Custom-Header": "Custom-Value"
|
||||||
|
// };
|
||||||
|
// return ajaxRequest;
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
onAjaxReadyStateChange: (InAppWebViewController controller, AjaxRequest ajaxRequest) async {
|
||||||
|
//print("AJAX READY STATE CHANGE: ${ajaxRequest.method} - ${ajaxRequest.url}, ${ajaxRequest.status}, ${ajaxRequest.readyState}, ${ajaxRequest.responseType}, ${ajaxRequest.responseText}, ${ajaxRequest.responseHeaders}");
|
||||||
|
return AjaxRequestAction.PROCEED;
|
||||||
|
},
|
||||||
|
onAjaxProgress: (InAppWebViewController controller, AjaxRequest ajaxRequest) async {
|
||||||
|
//print("AJAX EVENT: ${ajaxRequest.method} - ${ajaxRequest.url}, ${ajaxRequest.event.type}, LOADED: ${ajaxRequest.event.loaded}, ${ajaxRequest.responseHeaders}");
|
||||||
|
return AjaxRequestAction.PROCEED;
|
||||||
|
},
|
||||||
|
shouldInterceptFetchRequest: (InAppWebViewController controller, FetchRequest fetchRequest) async {
|
||||||
|
print("FETCH REQUEST: ${fetchRequest.method} - ${fetchRequest.url}, headers: ${fetchRequest.headers}");
|
||||||
|
fetchRequest.action = FetchRequestAction.ABORT;
|
||||||
|
print(fetchRequest.body);
|
||||||
|
return fetchRequest;
|
||||||
|
},
|
||||||
|
onNavigationStateChange: (InAppWebViewController controller, String url) async {
|
||||||
|
print("NAVIGATION STATE CHANGE: ${url}");
|
||||||
|
setState(() {
|
||||||
|
this.url = url;
|
||||||
|
});
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -161,33 +161,33 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView {
|
||||||
result(false)
|
result(false)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case "injectScriptCode":
|
case "evaluateJavascript":
|
||||||
if webView != nil {
|
if webView != nil {
|
||||||
let source = (arguments!["source"] as? String)!
|
let source = (arguments!["source"] as? String)!
|
||||||
webView!.injectScriptCode(source: source, result: result)
|
webView!.evaluateJavascript(source: source, result: result)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result("")
|
result("")
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case "injectScriptFile":
|
case "injectJavascriptFileFromUrl":
|
||||||
if webView != nil {
|
if webView != nil {
|
||||||
let urlFile = (arguments!["urlFile"] as? String)!
|
let urlFile = (arguments!["urlFile"] as? String)!
|
||||||
webView!.injectScriptFile(urlFile: urlFile)
|
webView!.injectJavascriptFileFromUrl(urlFile: urlFile)
|
||||||
}
|
}
|
||||||
result(true)
|
result(true)
|
||||||
break
|
break
|
||||||
case "injectStyleCode":
|
case "injectCSSCode":
|
||||||
if webView != nil {
|
if webView != nil {
|
||||||
let source = (arguments!["source"] as? String)!
|
let source = (arguments!["source"] as? String)!
|
||||||
webView!.injectStyleCode(source: source)
|
webView!.injectCSSCode(source: source)
|
||||||
}
|
}
|
||||||
result(true)
|
result(true)
|
||||||
break
|
break
|
||||||
case "injectStyleFile":
|
case "injectCSSFileFromUrl":
|
||||||
if webView != nil {
|
if webView != nil {
|
||||||
let urlFile = (arguments!["urlFile"] as? String)!
|
let urlFile = (arguments!["urlFile"] as? String)!
|
||||||
webView!.injectStyleFile(urlFile: urlFile)
|
webView!.injectCSSFileFromUrl(urlFile: urlFile)
|
||||||
}
|
}
|
||||||
result(true)
|
result(true)
|
||||||
break
|
break
|
||||||
|
@ -302,6 +302,10 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView {
|
||||||
}
|
}
|
||||||
result(true)
|
result(true)
|
||||||
break
|
break
|
||||||
|
case "removeFromSuperview":
|
||||||
|
webView!.removeFromSuperview()
|
||||||
|
result(true)
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
result(FlutterMethodNotImplemented)
|
result(FlutterMethodNotImplemented)
|
||||||
break
|
break
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
import Flutter
|
import Flutter
|
||||||
import Foundation
|
import Foundation
|
||||||
import WebKit
|
import WebKit
|
||||||
import WKWebViewWithURLProtocol
|
|
||||||
|
|
||||||
func currentTimeInMilliSeconds() -> Int64 {
|
func currentTimeInMilliSeconds() -> Int64 {
|
||||||
let currentDate = Date()
|
let currentDate = Date()
|
||||||
|
@ -27,9 +26,24 @@ func convertToDictionary(text: String) -> [String: Any]? {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func JSONStringify(value: Any, prettyPrinted: Bool = false) -> String {
|
||||||
|
let options: JSONSerialization.WritingOptions = prettyPrinted ? .prettyPrinted : .init(rawValue: 0)
|
||||||
|
if JSONSerialization.isValidJSONObject(value) {
|
||||||
|
let data = try? JSONSerialization.data(withJSONObject: value, options: options)
|
||||||
|
if data != nil {
|
||||||
|
if let string = String(data: data!, encoding: .utf8) {
|
||||||
|
return string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
let JAVASCRIPT_BRIDGE_NAME = "flutter_inappbrowser"
|
||||||
|
|
||||||
// the message needs to be concatenated with '' in order to have the same behavior like on Android
|
// the message needs to be concatenated with '' in order to have the same behavior like on Android
|
||||||
let consoleLogJS = """
|
let consoleLogJS = """
|
||||||
(function() {
|
(function(console) {
|
||||||
var oldLogs = {
|
var oldLogs = {
|
||||||
'consoleLog': console.log,
|
'consoleLog': console.log,
|
||||||
'consoleDebug': console.debug,
|
'consoleDebug': console.debug,
|
||||||
|
@ -54,22 +68,9 @@ let consoleLogJS = """
|
||||||
}
|
}
|
||||||
})(k);
|
})(k);
|
||||||
}
|
}
|
||||||
})();
|
})(window.console);
|
||||||
"""
|
"""
|
||||||
|
|
||||||
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']});
|
|
||||||
})();
|
|
||||||
"""
|
|
||||||
|
|
||||||
let JAVASCRIPT_BRIDGE_NAME = "flutter_inappbrowser"
|
|
||||||
|
|
||||||
let javaScriptBridgeJS = """
|
let javaScriptBridgeJS = """
|
||||||
window.\(JAVASCRIPT_BRIDGE_NAME) = {};
|
window.\(JAVASCRIPT_BRIDGE_NAME) = {};
|
||||||
window.\(JAVASCRIPT_BRIDGE_NAME).callHandler = function() {
|
window.\(JAVASCRIPT_BRIDGE_NAME).callHandler = function() {
|
||||||
|
@ -125,7 +126,7 @@ function wkwebview_FindAllAsyncForElement(element, keyword) {
|
||||||
value.substr(idx + keyword.length)
|
value.substr(idx + keyword.length)
|
||||||
);
|
);
|
||||||
|
|
||||||
window.webkit.messageHandlers["findResultReceived"].postMessage(
|
window.webkit.messageHandlers["onFindResultReceived"].postMessage(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
activeMatchOrdinal: wkwebview_CurrentHighlight,
|
activeMatchOrdinal: wkwebview_CurrentHighlight,
|
||||||
numberOfMatches: wkwebview_SearchResultCount,
|
numberOfMatches: wkwebview_SearchResultCount,
|
||||||
|
@ -155,7 +156,7 @@ function wkwebview_FindAllAsync(keyword) {
|
||||||
wkwebview_ClearMatches();
|
wkwebview_ClearMatches();
|
||||||
wkwebview_FindAllAsyncForElement(document.body, keyword.toLowerCase());
|
wkwebview_FindAllAsyncForElement(document.body, keyword.toLowerCase());
|
||||||
wkwebview_IsDoneCounting = true;
|
wkwebview_IsDoneCounting = true;
|
||||||
window.webkit.messageHandlers["findResultReceived"].postMessage(
|
window.webkit.messageHandlers["onFindResultReceived"].postMessage(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
activeMatchOrdinal: wkwebview_CurrentHighlight,
|
activeMatchOrdinal: wkwebview_CurrentHighlight,
|
||||||
numberOfMatches: wkwebview_SearchResultCount,
|
numberOfMatches: wkwebview_SearchResultCount,
|
||||||
|
@ -222,7 +223,7 @@ function wkwebview_FindNext(forward) {
|
||||||
block: "center"
|
block: "center"
|
||||||
});
|
});
|
||||||
|
|
||||||
window.webkit.messageHandlers["findResultReceived"].postMessage(
|
window.webkit.messageHandlers["onFindResultReceived"].postMessage(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
activeMatchOrdinal: wkwebview_CurrentHighlight,
|
activeMatchOrdinal: wkwebview_CurrentHighlight,
|
||||||
numberOfMatches: wkwebview_SearchResultCount,
|
numberOfMatches: wkwebview_SearchResultCount,
|
||||||
|
@ -233,6 +234,385 @@ function wkwebview_FindNext(forward) {
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
let variableForOnLoadResourceJS = "window._flutter_inappbrowser_useOnLoadResource"
|
||||||
|
let enableVariableForOnLoadResourceJS = "\(variableForOnLoadResourceJS) = $PLACEHOLDER_VALUE;"
|
||||||
|
|
||||||
|
let resourceObserverJS = """
|
||||||
|
(function() {
|
||||||
|
var observer = new PerformanceObserver(function(list) {
|
||||||
|
list.getEntries().forEach(function(entry) {
|
||||||
|
if (window.\(variableForOnLoadResourceJS) == null || window.\(variableForOnLoadResourceJS) == true) {
|
||||||
|
window.\(JAVASCRIPT_BRIDGE_NAME).callHandler("onLoadResource", entry);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
observer.observe({entryTypes: ['resource']});
|
||||||
|
})();
|
||||||
|
"""
|
||||||
|
|
||||||
|
let variableForShouldInterceptAjaxRequestJS = "window._flutter_inappbrowser_useShouldInterceptAjaxRequest"
|
||||||
|
let enableVariableForShouldInterceptAjaxRequestJS = "\(variableForShouldInterceptAjaxRequestJS) = $PLACEHOLDER_VALUE;"
|
||||||
|
|
||||||
|
let interceptAjaxRequestsJS = """
|
||||||
|
(function(ajax) {
|
||||||
|
var send = ajax.prototype.send;
|
||||||
|
var open = ajax.prototype.open;
|
||||||
|
var setRequestHeader = ajax.prototype.setRequestHeader;
|
||||||
|
ajax.prototype._flutter_inappbrowser_url = null;
|
||||||
|
ajax.prototype._flutter_inappbrowser_method = null;
|
||||||
|
ajax.prototype._flutter_inappbrowser_isAsync = null;
|
||||||
|
ajax.prototype._flutter_inappbrowser_user = null;
|
||||||
|
ajax.prototype._flutter_inappbrowser_password = null;
|
||||||
|
ajax.prototype._flutter_inappbrowser_password = null;
|
||||||
|
ajax.prototype._flutter_inappbrowser_already_onreadystatechange_wrapped = false;
|
||||||
|
ajax.prototype._flutter_inappbrowser_request_headers = {};
|
||||||
|
ajax.prototype.open = function(method, url, isAsync, user, password) {
|
||||||
|
isAsync = (isAsync != null) ? isAsync : true;
|
||||||
|
this._flutter_inappbrowser_url = url;
|
||||||
|
this._flutter_inappbrowser_method = method;
|
||||||
|
this._flutter_inappbrowser_isAsync = isAsync;
|
||||||
|
this._flutter_inappbrowser_user = user;
|
||||||
|
this._flutter_inappbrowser_password = password;
|
||||||
|
open.call(this, method, url, isAsync, user, password);
|
||||||
|
};
|
||||||
|
ajax.prototype.setRequestHeader = function(header, value) {
|
||||||
|
this._flutter_inappbrowser_request_headers[header] = value;
|
||||||
|
setRequestHeader.call(this, header, value);
|
||||||
|
};
|
||||||
|
function handleEvent(e) {
|
||||||
|
var self = this;
|
||||||
|
if (window.\(variableForShouldInterceptAjaxRequestJS) == null || window.\(variableForShouldInterceptAjaxRequestJS) == true) {
|
||||||
|
var headers = this.getAllResponseHeaders();
|
||||||
|
var responseHeaders = {};
|
||||||
|
if (headers != null) {
|
||||||
|
var arr = headers.trim().split(/[\\r\\n]+/);
|
||||||
|
arr.forEach(function (line) {
|
||||||
|
var parts = line.split(': ');
|
||||||
|
var header = parts.shift();
|
||||||
|
var value = parts.join(': ');
|
||||||
|
responseHeaders[header] = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var ajaxRequest = {
|
||||||
|
method: this._flutter_inappbrowser_method,
|
||||||
|
url: this._flutter_inappbrowser_url,
|
||||||
|
isAsync: this._flutter_inappbrowser_isAsync,
|
||||||
|
user: this._flutter_inappbrowser_user,
|
||||||
|
password: this._flutter_inappbrowser_password,
|
||||||
|
withCredentials: this.withCredentials,
|
||||||
|
headers: this._flutter_inappbrowser_request_headers,
|
||||||
|
readyState: this.readyState,
|
||||||
|
status: this.status,
|
||||||
|
responseURL: this.responseURL,
|
||||||
|
responseType: this.responseType,
|
||||||
|
responseText: this.responseText,
|
||||||
|
statusText: this.statusText,
|
||||||
|
responseHeaders, responseHeaders,
|
||||||
|
event: {
|
||||||
|
type: e.type,
|
||||||
|
loaded: e.loaded,
|
||||||
|
lengthComputable: e.lengthComputable
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.\(JAVASCRIPT_BRIDGE_NAME).callHandler('onAjaxProgress', ajaxRequest).then(function(result) {
|
||||||
|
if (result != null) {
|
||||||
|
switch (result) {
|
||||||
|
case 0:
|
||||||
|
self.abort();
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ajax.prototype.send = function(data) {
|
||||||
|
var self = this;
|
||||||
|
if (window.\(variableForShouldInterceptAjaxRequestJS) == null || window.\(variableForShouldInterceptAjaxRequestJS) == true) {
|
||||||
|
if (!this._flutter_inappbrowser_already_onreadystatechange_wrapped) {
|
||||||
|
this._flutter_inappbrowser_already_onreadystatechange_wrapped = true;
|
||||||
|
var onreadystatechange = this.onreadystatechange;
|
||||||
|
this.onreadystatechange = function() {
|
||||||
|
if (window.\(variableForShouldInterceptAjaxRequestJS) == null || window.\(variableForShouldInterceptAjaxRequestJS) == true) {
|
||||||
|
var headers = this.getAllResponseHeaders();
|
||||||
|
var responseHeaders = {};
|
||||||
|
if (headers != null) {
|
||||||
|
var arr = headers.trim().split(/[\\r\\n]+/);
|
||||||
|
arr.forEach(function (line) {
|
||||||
|
var parts = line.split(': ');
|
||||||
|
var header = parts.shift();
|
||||||
|
var value = parts.join(': ');
|
||||||
|
responseHeaders[header] = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var ajaxRequest = {
|
||||||
|
method: this._flutter_inappbrowser_method,
|
||||||
|
url: this._flutter_inappbrowser_url,
|
||||||
|
isAsync: this._flutter_inappbrowser_isAsync,
|
||||||
|
user: this._flutter_inappbrowser_user,
|
||||||
|
password: this._flutter_inappbrowser_password,
|
||||||
|
withCredentials: this.withCredentials,
|
||||||
|
headers: this._flutter_inappbrowser_request_headers,
|
||||||
|
readyState: this.readyState,
|
||||||
|
status: this.status,
|
||||||
|
responseURL: this.responseURL,
|
||||||
|
responseType: this.responseType,
|
||||||
|
responseText: this.responseText,
|
||||||
|
statusText: this.statusText,
|
||||||
|
responseHeaders: responseHeaders
|
||||||
|
};
|
||||||
|
window.\(JAVASCRIPT_BRIDGE_NAME).callHandler('onAjaxReadyStateChange', ajaxRequest).then(function(result) {
|
||||||
|
if (result != null) {
|
||||||
|
switch (result) {
|
||||||
|
case 0:
|
||||||
|
self.abort();
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (onreadystatechange != null) {
|
||||||
|
onreadystatechange();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (onreadystatechange != null) {
|
||||||
|
onreadystatechange();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
this.addEventListener('loadstart', handleEvent);
|
||||||
|
this.addEventListener('load', handleEvent);
|
||||||
|
this.addEventListener('loadend', handleEvent);
|
||||||
|
this.addEventListener('progress', handleEvent);
|
||||||
|
this.addEventListener('error', handleEvent);
|
||||||
|
this.addEventListener('abort', handleEvent);
|
||||||
|
var ajaxRequest = {
|
||||||
|
data: data,
|
||||||
|
method: this._flutter_inappbrowser_method,
|
||||||
|
url: this._flutter_inappbrowser_url,
|
||||||
|
isAsync: this._flutter_inappbrowser_isAsync,
|
||||||
|
user: this._flutter_inappbrowser_user,
|
||||||
|
password: this._flutter_inappbrowser_password,
|
||||||
|
withCredentials: this.withCredentials,
|
||||||
|
headers: this._flutter_inappbrowser_request_headers
|
||||||
|
};
|
||||||
|
window.\(JAVASCRIPT_BRIDGE_NAME).callHandler('shouldInterceptAjaxRequest', ajaxRequest).then(function(result) {
|
||||||
|
if (result != null) {
|
||||||
|
switch (result.action) {
|
||||||
|
case 0:
|
||||||
|
self.abort();
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
data = result.data;
|
||||||
|
self.withCredentials = result.withCredentials;
|
||||||
|
for (var header in result.headers) {
|
||||||
|
var value = result.headers[header];
|
||||||
|
self.setRequestHeader(header, value);
|
||||||
|
};
|
||||||
|
if ((self._flutter_inappbrowser_method != result.method && result.method != null) || (self._flutter_inappbrowser_url != result.url && result.url != null)) {
|
||||||
|
self.abort();
|
||||||
|
self.open(result.method, result.url, result.isAsync, result.user, result.password);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
send.call(self, data);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
send.call(this, data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})(window.XMLHttpRequest);
|
||||||
|
"""
|
||||||
|
|
||||||
|
let variableForShouldInterceptFetchRequestsJS = "window._flutter_inappbrowser_useShouldInterceptFetchRequest"
|
||||||
|
let enableVariableForShouldInterceptFetchRequestsJS = "\(variableForShouldInterceptFetchRequestsJS) = $PLACEHOLDER_VALUE;"
|
||||||
|
|
||||||
|
let interceptFetchRequestsJS = """
|
||||||
|
(function(fetch) {
|
||||||
|
if (fetch == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
function convertHeadersToJson(headers) {
|
||||||
|
var headersObj = {};
|
||||||
|
for (var header of headers.keys()) {
|
||||||
|
var value = headers.get(header);
|
||||||
|
headersObj[header] = value;
|
||||||
|
}
|
||||||
|
return headersObj;
|
||||||
|
}
|
||||||
|
function convertJsonToHeaders(headersJson) {
|
||||||
|
return new Headers(headersJson);
|
||||||
|
}
|
||||||
|
function convertBodyToArray(body) {
|
||||||
|
return new Response(body).arrayBuffer().then(function(arrayBuffer) {
|
||||||
|
var arr = Array.from(new Uint8Array(arrayBuffer));
|
||||||
|
return arr;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function convertArrayIntBodyToUint8Array(arrayIntBody) {
|
||||||
|
return new Uint8Array(arrayIntBody);
|
||||||
|
}
|
||||||
|
function convertCredentialsToJson(credentials) {
|
||||||
|
var credentialsObj = {};
|
||||||
|
if (window.FederatedCredential != null && credentials instanceof FederatedCredential) {
|
||||||
|
credentialsObj.type = credentials.type;
|
||||||
|
credentialsObj.id = credentials.id;
|
||||||
|
credentialsObj.name = credentials.name;
|
||||||
|
credentialsObj.protocol = credentials.protocol;
|
||||||
|
credentialsObj.provider = credentials.provider;
|
||||||
|
credentialsObj.iconURL = credentials.iconURL;
|
||||||
|
} else if (window.PasswordCredential != null && credentials instanceof PasswordCredential) {
|
||||||
|
credentialsObj.type = credentials.type;
|
||||||
|
credentialsObj.id = credentials.id;
|
||||||
|
credentialsObj.name = credentials.name;
|
||||||
|
credentialsObj.password = credentials.password;
|
||||||
|
credentialsObj.iconURL = credentials.iconURL;
|
||||||
|
} else {
|
||||||
|
credentialsObj.type = 'default';
|
||||||
|
credentialsObj.value = credentials;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function convertJsonToCredential(credentialsJson) {
|
||||||
|
var credentials;
|
||||||
|
if (window.FederatedCredential != null && credentialsJson.type === 'federated') {
|
||||||
|
credentials = new FederatedCredential({
|
||||||
|
id: credentialsJson.id,
|
||||||
|
name: credentialsJson.name,
|
||||||
|
protocol: credentialsJson.protocol,
|
||||||
|
provider: credentialsJson.provider,
|
||||||
|
iconURL: credentialsJson.iconURL
|
||||||
|
});
|
||||||
|
} else if (window.PasswordCredential != null && credentialsJson.type === 'password') {
|
||||||
|
credentials = new PasswordCredential({
|
||||||
|
id: credentialsJson.id,
|
||||||
|
name: credentialsJson.name,
|
||||||
|
password: credentialsJson.password,
|
||||||
|
iconURL: credentialsJson.iconURL
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
credentials = credentialsJson;
|
||||||
|
}
|
||||||
|
return credentials;
|
||||||
|
}
|
||||||
|
window.fetch = async function(resource, init) {
|
||||||
|
if (window.\(variableForShouldInterceptFetchRequestsJS) == null || window.\(variableForShouldInterceptFetchRequestsJS) == true) {
|
||||||
|
var fetchRequest = {
|
||||||
|
url: null,
|
||||||
|
method: null,
|
||||||
|
headers: null,
|
||||||
|
body: null,
|
||||||
|
mode: null,
|
||||||
|
credentials: null,
|
||||||
|
cache: null,
|
||||||
|
redirect: null,
|
||||||
|
referrer: null,
|
||||||
|
referrerPolicy: null,
|
||||||
|
integrity: null,
|
||||||
|
keepalive: null
|
||||||
|
};
|
||||||
|
if (resource instanceof Request) {
|
||||||
|
fetchRequest.url = resource.url;
|
||||||
|
fetchRequest.method = resource.method;
|
||||||
|
fetchRequest.headers = resource.headers;
|
||||||
|
fetchRequest.body = resource.body;
|
||||||
|
fetchRequest.mode = resource.mode;
|
||||||
|
fetchRequest.credentials = resource.credentials;
|
||||||
|
fetchRequest.cache = resource.cache;
|
||||||
|
fetchRequest.redirect = resource.redirect;
|
||||||
|
fetchRequest.referrer = resource.referrer;
|
||||||
|
fetchRequest.referrerPolicy = resource.referrerPolicy;
|
||||||
|
fetchRequest.integrity = resource.integrity;
|
||||||
|
fetchRequest.keepalive = resource.keepalive;
|
||||||
|
} else {
|
||||||
|
fetchRequest.url = resource;
|
||||||
|
if (init != null) {
|
||||||
|
fetchRequest.method = init.method;
|
||||||
|
fetchRequest.headers = init.headers;
|
||||||
|
fetchRequest.body = init.body;
|
||||||
|
fetchRequest.mode = init.mode;
|
||||||
|
fetchRequest.credentials = init.credentials;
|
||||||
|
fetchRequest.cache = init.cache;
|
||||||
|
fetchRequest.redirect = init.redirect;
|
||||||
|
fetchRequest.referrer = init.referrer;
|
||||||
|
fetchRequest.referrerPolicy = init.referrerPolicy;
|
||||||
|
fetchRequest.integrity = init.integrity;
|
||||||
|
fetchRequest.keepalive = init.keepalive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fetchRequest.headers instanceof Headers) {
|
||||||
|
fetchRequest.headers = convertHeadersToJson(fetchRequest.headers);
|
||||||
|
}
|
||||||
|
fetchRequest.credentials = convertCredentialsToJson(fetchRequest.credentials);
|
||||||
|
return convertBodyToArray(fetchRequest.body).then(function(body) {
|
||||||
|
fetchRequest.body = body;
|
||||||
|
return window.\(JAVASCRIPT_BRIDGE_NAME).callHandler('shouldInterceptFetchRequest', fetchRequest).then(function(result) {
|
||||||
|
if (result != null) {
|
||||||
|
switch (result.action) {
|
||||||
|
case 0:
|
||||||
|
var controller = new AbortController();
|
||||||
|
if (init != null) {
|
||||||
|
init.signal = controller.signal;
|
||||||
|
} else {
|
||||||
|
init = {
|
||||||
|
signal: controller.signal
|
||||||
|
};
|
||||||
|
}
|
||||||
|
controller.abort();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var resultResource = (result.resource != null) ? result.resource : resource;
|
||||||
|
var resultInit = init;
|
||||||
|
if (result.init != null) {
|
||||||
|
resultInit.method = result.method;
|
||||||
|
resultInit.headers = convertJsonToHeaders(result.headers);
|
||||||
|
resultInit.body = convertArrayIntBodyToUint8Array(result.body);
|
||||||
|
resultInit.mode = result.mode;
|
||||||
|
resultInit.credentials = convertJsonToCredential(result.credentials);
|
||||||
|
resultInit.cache = result.cache;
|
||||||
|
resultInit.redirect = result.redirect;
|
||||||
|
resultInit.referrer = result.referrer;
|
||||||
|
resultInit.referrerPolicy = result.referrerPolicy;
|
||||||
|
resultInit.integrity = result.integrity;
|
||||||
|
resultInit.keepalive = result.keepalive;
|
||||||
|
}
|
||||||
|
return fetch(resultResource, resultInit);
|
||||||
|
}
|
||||||
|
return fetch(resource, init);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return fetch(resource, init);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})(window.fetch);
|
||||||
|
"""
|
||||||
|
|
||||||
|
let interceptNavigationStateChangeJS = """
|
||||||
|
(function(window, document, history) {
|
||||||
|
history.pushState = (function(f) {
|
||||||
|
return function pushState(){
|
||||||
|
var ret = f.apply(this, arguments);
|
||||||
|
window.dispatchEvent(new Event('pushstate'));
|
||||||
|
window.dispatchEvent(new Event('_flutter_inappbrowser_locationchange'));
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
})(history.pushState);
|
||||||
|
history.replaceState = ( function(f) {
|
||||||
|
return function replaceState(){
|
||||||
|
var ret = f.apply(this, arguments);
|
||||||
|
window.dispatchEvent(new Event('replacestate'));
|
||||||
|
window.dispatchEvent(new Event('_flutter_inappbrowser_locationchange'));
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
})(history.replaceState);
|
||||||
|
window.addEventListener('popstate',function() {
|
||||||
|
window.dispatchEvent(new Event('_flutter_inappbrowser_locationchange'));
|
||||||
|
});
|
||||||
|
window.addEventListener('_flutter_inappbrowser_locationchange', function() {
|
||||||
|
window.webkit.messageHandlers["onNavigationStateChange"].postMessage(JSON.stringify({
|
||||||
|
url: document.location.href
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
})(window, window.document, window.history);
|
||||||
|
"""
|
||||||
|
|
||||||
public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler {
|
public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler {
|
||||||
|
|
||||||
var IABController: InAppBrowserWebViewController?
|
var IABController: InAppBrowserWebViewController?
|
||||||
|
@ -295,7 +675,6 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
let jscriptWebkitTouchCallout = WKUserScript(source: "document.body.style.webkitTouchCallout='none';", injectionTime: .atDocumentEnd, forMainFrameOnly: true)
|
let jscriptWebkitTouchCallout = WKUserScript(source: "document.body.style.webkitTouchCallout='none';", injectionTime: .atDocumentEnd, forMainFrameOnly: true)
|
||||||
configuration.userContentController.addUserScript(jscriptWebkitTouchCallout)
|
configuration.userContentController.addUserScript(jscriptWebkitTouchCallout)
|
||||||
|
|
||||||
|
|
||||||
let consoleLogJSScript = WKUserScript(source: consoleLogJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
let consoleLogJSScript = WKUserScript(source: consoleLogJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||||
configuration.userContentController.addUserScript(consoleLogJSScript)
|
configuration.userContentController.addUserScript(consoleLogJSScript)
|
||||||
configuration.userContentController.add(self, name: "consoleLog")
|
configuration.userContentController.add(self, name: "consoleLog")
|
||||||
|
@ -308,25 +687,63 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
configuration.userContentController.addUserScript(javaScriptBridgeJSScript)
|
configuration.userContentController.addUserScript(javaScriptBridgeJSScript)
|
||||||
configuration.userContentController.add(self, name: "callHandler")
|
configuration.userContentController.add(self, name: "callHandler")
|
||||||
|
|
||||||
let resourceObserverJSScript = WKUserScript(source: resourceObserverJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
if (options?.useOnLoadResource)! {
|
||||||
configuration.userContentController.addUserScript(resourceObserverJSScript)
|
let resourceObserverJSScript = WKUserScript(source: resourceObserverJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||||
configuration.userContentController.add(self, name: "resourceLoaded")
|
configuration.userContentController.addUserScript(resourceObserverJSScript)
|
||||||
|
}
|
||||||
|
|
||||||
let findTextHighlightJSScript = WKUserScript(source: findTextHighlightJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
let findTextHighlightJSScript = WKUserScript(source: findTextHighlightJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||||
configuration.userContentController.addUserScript(findTextHighlightJSScript)
|
configuration.userContentController.addUserScript(findTextHighlightJSScript)
|
||||||
configuration.userContentController.add(self, name: "findResultReceived")
|
configuration.userContentController.add(self, name: "onFindResultReceived")
|
||||||
|
|
||||||
//keyboardDisplayRequiresUserAction = browserOptions?.keyboardDisplayRequiresUserAction
|
let interceptNavigationStateChangeJSScript = WKUserScript(source: interceptNavigationStateChangeJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||||
|
configuration.userContentController.addUserScript(interceptNavigationStateChangeJSScript)
|
||||||
|
configuration.userContentController.add(self, name: "onNavigationStateChange")
|
||||||
|
|
||||||
|
|
||||||
|
if (options?.useShouldInterceptAjaxRequest)! {
|
||||||
|
let interceptAjaxRequestsJSScript = WKUserScript(source: interceptAjaxRequestsJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||||
|
configuration.userContentController.addUserScript(interceptAjaxRequestsJSScript)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options?.useShouldInterceptFetchRequest)! {
|
||||||
|
let interceptFetchRequestsJSScript = WKUserScript(source: interceptFetchRequestsJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||||
|
configuration.userContentController.addUserScript(interceptFetchRequestsJSScript)
|
||||||
|
}
|
||||||
|
|
||||||
|
if #available(iOS 9.0, *) {
|
||||||
|
if ((options?.incognito)!) {
|
||||||
|
configuration.websiteDataStore = WKWebsiteDataStore.nonPersistent()
|
||||||
|
} else if ((options?.cacheEnabled)!) {
|
||||||
|
configuration.websiteDataStore = WKWebsiteDataStore.default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if #available(iOS 11.0, *) {
|
||||||
|
if((options?.sharedCookiesEnabled)!) {
|
||||||
|
// More info to sending cookies with WKWebView
|
||||||
|
// https://stackoverflow.com/questions/26573137/can-i-set-the-cookies-to-be-used-by-a-wkwebview/26577303#26577303
|
||||||
|
// Set Cookies in iOS 11 and above, initialize websiteDataStore before setting cookies
|
||||||
|
// See also https://forums.developer.apple.com/thread/97194
|
||||||
|
// check if websiteDataStore has not been initialized before
|
||||||
|
if(!(options?.incognito)! && !(options?.cacheEnabled)!) {
|
||||||
|
configuration.websiteDataStore = WKWebsiteDataStore.nonPersistent()
|
||||||
|
}
|
||||||
|
for cookie in HTTPCookieStorage.shared.cookies ?? [] {
|
||||||
|
configuration.websiteDataStore.httpCookieStore.setCookie(cookie, completionHandler: nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
configuration.suppressesIncrementalRendering = (options?.suppressesIncrementalRendering)!
|
configuration.suppressesIncrementalRendering = (options?.suppressesIncrementalRendering)!
|
||||||
allowsBackForwardNavigationGestures = (options?.allowsBackForwardNavigationGestures)!
|
allowsBackForwardNavigationGestures = (options?.allowsBackForwardNavigationGestures)!
|
||||||
if #available(iOS 9.0, *) {
|
if #available(iOS 9.0, *) {
|
||||||
allowsLinkPreview = (options?.allowsLinkPreview)!
|
allowsLinkPreview = (options?.allowsLinkPreview)!
|
||||||
configuration.allowsPictureInPictureMediaPlayback = (options?.allowsPictureInPictureMediaPlayback)!
|
configuration.allowsPictureInPictureMediaPlayback = (options?.allowsPictureInPictureMediaPlayback)!
|
||||||
if ((options?.applicationNameForUserAgent)! != "") {
|
if (options?.applicationNameForUserAgent != nil && (options?.applicationNameForUserAgent)! != "") {
|
||||||
configuration.applicationNameForUserAgent = (options?.applicationNameForUserAgent)!
|
configuration.applicationNameForUserAgent = (options?.applicationNameForUserAgent)!
|
||||||
}
|
}
|
||||||
if ((options?.userAgent)! != "") {
|
if (options?.userAgent != nil && (options?.userAgent)! != "") {
|
||||||
customUserAgent = (options?.userAgent)!
|
customUserAgent = (options?.userAgent)!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -423,7 +840,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
|
|
||||||
override public func observeValue(forKeyPath keyPath: String?, of object: Any?,
|
override public func observeValue(forKeyPath keyPath: String?, of object: Any?,
|
||||||
change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
|
change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
|
||||||
if keyPath == "estimatedProgress" {
|
if keyPath == #keyPath(WKWebView.estimatedProgress) {
|
||||||
let progress = Int(estimatedProgress * 100)
|
let progress = Int(estimatedProgress * 100)
|
||||||
onProgressChanged(progress: progress)
|
onProgressChanged(progress: progress)
|
||||||
}
|
}
|
||||||
|
@ -543,11 +960,45 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if #available(iOS 9.0, *) {
|
||||||
|
if (newOptionsMap["incognito"] != nil && options?.incognito != newOptions.incognito && newOptions.incognito) {
|
||||||
|
configuration.websiteDataStore = WKWebsiteDataStore.nonPersistent()
|
||||||
|
} else if (newOptionsMap["cacheEnabled"] != nil && options?.cacheEnabled != newOptions.cacheEnabled && newOptions.cacheEnabled) {
|
||||||
|
configuration.websiteDataStore = WKWebsiteDataStore.default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if #available(iOS 11.0, *) {
|
||||||
|
if (newOptionsMap["sharedCookiesEnabled"] != nil && options?.sharedCookiesEnabled != newOptions.sharedCookiesEnabled && newOptions.sharedCookiesEnabled) {
|
||||||
|
if(!newOptions.incognito && !newOptions.cacheEnabled) {
|
||||||
|
configuration.websiteDataStore = WKWebsiteDataStore.nonPersistent()
|
||||||
|
}
|
||||||
|
for cookie in HTTPCookieStorage.shared.cookies ?? [] {
|
||||||
|
configuration.websiteDataStore.httpCookieStore.setCookie(cookie, completionHandler: nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if newOptionsMap["enableViewportScale"] != nil && options?.enableViewportScale != newOptions.enableViewportScale && newOptions.enableViewportScale {
|
if newOptionsMap["enableViewportScale"] != nil && options?.enableViewportScale != newOptions.enableViewportScale && newOptions.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 jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"
|
||||||
evaluateJavaScript(jscript, completionHandler: nil)
|
evaluateJavaScript(jscript, completionHandler: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if newOptionsMap["useOnLoadResource"] != nil && options?.useOnLoadResource != newOptions.useOnLoadResource && newOptions.useOnLoadResource {
|
||||||
|
let placeholderValue = newOptions.useOnLoadResource ? "true" : "false"
|
||||||
|
evaluateJavaScript(enableVariableForOnLoadResourceJS.replacingOccurrences(of: "$PLACEHOLDER_VALUE", with: placeholderValue), completionHandler: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
if newOptionsMap["useShouldInterceptAjaxRequest"] != nil && options?.useShouldInterceptAjaxRequest != newOptions.useShouldInterceptAjaxRequest && newOptions.useShouldInterceptAjaxRequest {
|
||||||
|
let placeholderValue = newOptions.useShouldInterceptAjaxRequest ? "true" : "false"
|
||||||
|
evaluateJavaScript(enableVariableForShouldInterceptAjaxRequestJS.replacingOccurrences(of: "$PLACEHOLDER_VALUE", with: placeholderValue), completionHandler: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
if newOptionsMap["useShouldInterceptFetchRequest"] != nil && options?.useShouldInterceptFetchRequest != newOptions.useShouldInterceptFetchRequest && newOptions.useShouldInterceptFetchRequest {
|
||||||
|
let placeholderValue = newOptions.useShouldInterceptFetchRequest ? "true" : "false"
|
||||||
|
evaluateJavaScript(enableVariableForShouldInterceptFetchRequestsJS.replacingOccurrences(of: "$PLACEHOLDER_VALUE", with: placeholderValue), completionHandler: nil)
|
||||||
|
}
|
||||||
|
|
||||||
if newOptionsMap["mediaPlaybackRequiresUserGesture"] != nil && options?.mediaPlaybackRequiresUserGesture != newOptions.mediaPlaybackRequiresUserGesture {
|
if newOptionsMap["mediaPlaybackRequiresUserGesture"] != nil && options?.mediaPlaybackRequiresUserGesture != newOptions.mediaPlaybackRequiresUserGesture {
|
||||||
if #available(iOS 10.0, *) {
|
if #available(iOS 10.0, *) {
|
||||||
configuration.mediaTypesRequiringUserActionForPlayback = (newOptions.mediaPlaybackRequiresUserGesture) ? .all : []
|
configuration.mediaTypesRequiringUserActionForPlayback = (newOptions.mediaPlaybackRequiresUserGesture) ? .all : []
|
||||||
|
@ -561,10 +1012,6 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
configuration.allowsInlineMediaPlayback = newOptions.allowsInlineMediaPlayback
|
configuration.allowsInlineMediaPlayback = newOptions.allowsInlineMediaPlayback
|
||||||
}
|
}
|
||||||
|
|
||||||
// if newOptionsMap["keyboardDisplayRequiresUserAction"] != nil && browserOptions?.keyboardDisplayRequiresUserAction != newOptions.keyboardDisplayRequiresUserAction {
|
|
||||||
// self.webView.keyboardDisplayRequiresUserAction = newOptions.keyboardDisplayRequiresUserAction
|
|
||||||
// }
|
|
||||||
|
|
||||||
if newOptionsMap["suppressesIncrementalRendering"] != nil && options?.suppressesIncrementalRendering != newOptions.suppressesIncrementalRendering {
|
if newOptionsMap["suppressesIncrementalRendering"] != nil && options?.suppressesIncrementalRendering != newOptions.suppressesIncrementalRendering {
|
||||||
configuration.suppressesIncrementalRendering = newOptions.suppressesIncrementalRendering
|
configuration.suppressesIncrementalRendering = newOptions.suppressesIncrementalRendering
|
||||||
}
|
}
|
||||||
|
@ -734,22 +1181,22 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func injectScriptCode(source: String, result: FlutterResult?) {
|
public func evaluateJavascript(source: String, result: FlutterResult?) {
|
||||||
let jsWrapper = "(function(){return JSON.stringify(eval(%@));})();"
|
let jsWrapper = "(function(){return JSON.stringify(eval(%@));})();"
|
||||||
injectDeferredObject(source: source, withWrapper: jsWrapper, result: result)
|
injectDeferredObject(source: source, withWrapper: jsWrapper, result: result)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func injectScriptFile(urlFile: String) {
|
public func injectJavascriptFileFromUrl(urlFile: String) {
|
||||||
let jsWrapper = "(function(d) { var c = d.createElement('script'); c.src = %@; d.body.appendChild(c); })(document);"
|
let jsWrapper = "(function(d) { var c = d.createElement('script'); c.src = %@; d.body.appendChild(c); })(document);"
|
||||||
injectDeferredObject(source: urlFile, withWrapper: jsWrapper, result: nil)
|
injectDeferredObject(source: urlFile, withWrapper: jsWrapper, result: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func injectStyleCode(source: String) {
|
public func injectCSSCode(source: String) {
|
||||||
let jsWrapper = "(function(d) { var c = d.createElement('style'); c.innerHTML = %@; d.body.appendChild(c); })(document);"
|
let jsWrapper = "(function(d) { var c = d.createElement('style'); c.innerHTML = %@; d.body.appendChild(c); })(document);"
|
||||||
injectDeferredObject(source: source, withWrapper: jsWrapper, result: nil)
|
injectDeferredObject(source: source, withWrapper: jsWrapper, result: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func injectStyleFile(urlFile: String) {
|
public func injectCSSFileFromUrl(urlFile: String) {
|
||||||
let jsWrapper = "(function(d) { var c = d.createElement('link'); c.rel='stylesheet', c.type='text/css'; c.href = %@; d.body.appendChild(c); })(document);"
|
let jsWrapper = "(function(d) { var c = d.createElement('link'); c.rel='stylesheet', c.type='text/css'; c.href = %@; d.body.appendChild(c); })(document);"
|
||||||
injectDeferredObject(source: urlFile, withWrapper: jsWrapper, result: nil)
|
injectDeferredObject(source: urlFile, withWrapper: jsWrapper, result: nil)
|
||||||
}
|
}
|
||||||
|
@ -1333,21 +1780,6 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func onLoadResource(initiatorType: String, url: String, startTime: Double, duration: Double) {
|
|
||||||
var arguments: [String : Any] = [
|
|
||||||
"initiatorType": initiatorType,
|
|
||||||
"url": url,
|
|
||||||
"startTime": startTime,
|
|
||||||
"duration": duration
|
|
||||||
]
|
|
||||||
if IABController != nil {
|
|
||||||
arguments["uuid"] = IABController!.uuid
|
|
||||||
}
|
|
||||||
if let channel = getChannel() {
|
|
||||||
channel.invokeMethod("onLoadResource", arguments: arguments)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func onFindResultReceived(activeMatchOrdinal: Int, numberOfMatches: Int, isDoneCounting: Bool) {
|
public func onFindResultReceived(activeMatchOrdinal: Int, numberOfMatches: Int, isDoneCounting: Bool) {
|
||||||
var arguments: [String : Any] = [
|
var arguments: [String : Any] = [
|
||||||
"activeMatchOrdinal": activeMatchOrdinal,
|
"activeMatchOrdinal": activeMatchOrdinal,
|
||||||
|
@ -1362,6 +1794,18 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func onNavigationStateChange(url: String) {
|
||||||
|
var arguments: [String : Any] = [
|
||||||
|
"url": url
|
||||||
|
]
|
||||||
|
if IABController != nil {
|
||||||
|
arguments["uuid"] = IABController!.uuid
|
||||||
|
}
|
||||||
|
if let channel = getChannel() {
|
||||||
|
channel.invokeMethod("onNavigationStateChange", arguments: arguments)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public func onScrollChanged(x: Int, y: Int) {
|
public func onScrollChanged(x: Int, y: Int) {
|
||||||
var arguments: [String: Any] = ["x": x, "y": y]
|
var arguments: [String: Any] = ["x": x, "y": y]
|
||||||
if IABController != nil {
|
if IABController != nil {
|
||||||
|
@ -1561,29 +2005,13 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
}
|
}
|
||||||
onConsoleMessage(sourceURL: "", lineNumber: 1, message: message.body as! String, messageLevel: messageLevel)
|
onConsoleMessage(sourceURL: "", lineNumber: 1, message: message.body as! String, messageLevel: messageLevel)
|
||||||
}
|
}
|
||||||
else if message.name == "resourceLoaded" && (options?.useOnLoadResource)! {
|
|
||||||
if let resource = convertToDictionary(text: message.body 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) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let initiatorType = resource["initiatorType"] as! String
|
|
||||||
let startTime = resource["startTime"] as! Double
|
|
||||||
let duration = resource["duration"] as! Double
|
|
||||||
|
|
||||||
self.onLoadResource(initiatorType: initiatorType, url: url.absoluteString, startTime: startTime, duration: duration)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if message.name == "callHandler" {
|
else if message.name == "callHandler" {
|
||||||
let body = message.body as! [String: Any]
|
let body = message.body as! [String: Any]
|
||||||
let handlerName = body["handlerName"] as! String
|
let handlerName = body["handlerName"] as! String
|
||||||
let _callHandlerID = body["_callHandlerID"] as! Int64
|
let _callHandlerID = body["_callHandlerID"] as! Int64
|
||||||
let args = body["args"] as! String
|
let args = body["args"] as! String
|
||||||
onCallJsHandler(handlerName: handlerName, _callHandlerID: _callHandlerID, args: args)
|
onCallJsHandler(handlerName: handlerName, _callHandlerID: _callHandlerID, args: args)
|
||||||
} else if message.name == "findResultReceived" {
|
} else if message.name == "onFindResultReceived" {
|
||||||
if let resource = convertToDictionary(text: message.body as! String) {
|
if let resource = convertToDictionary(text: message.body as! String) {
|
||||||
let activeMatchOrdinal = resource["activeMatchOrdinal"] as! Int
|
let activeMatchOrdinal = resource["activeMatchOrdinal"] as! Int
|
||||||
let numberOfMatches = resource["numberOfMatches"] as! Int
|
let numberOfMatches = resource["numberOfMatches"] as! Int
|
||||||
|
@ -1591,6 +2019,13 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
|
|
||||||
self.onFindResultReceived(activeMatchOrdinal: activeMatchOrdinal, numberOfMatches: numberOfMatches, isDoneCounting: isDoneCounting)
|
self.onFindResultReceived(activeMatchOrdinal: activeMatchOrdinal, numberOfMatches: numberOfMatches, isDoneCounting: isDoneCounting)
|
||||||
}
|
}
|
||||||
|
} else if message.name == "onNavigationStateChange" {
|
||||||
|
if let resource = convertToDictionary(text: message.body as! String) {
|
||||||
|
let url = resource["url"] as! String
|
||||||
|
|
||||||
|
self.onNavigationStateChange(url: url)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1610,4 +2045,24 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
func clearMatches(completionHandler: ((Any?, Error?) -> Void)?) {
|
func clearMatches(completionHandler: ((Any?, Error?) -> Void)?) {
|
||||||
evaluateJavaScript("wkwebview_ClearMatches();", completionHandler: completionHandler)
|
evaluateJavaScript("wkwebview_ClearMatches();", completionHandler: completionHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override func removeFromSuperview() {
|
||||||
|
configuration.userContentController.removeScriptMessageHandler(forName: "consoleLog")
|
||||||
|
configuration.userContentController.removeScriptMessageHandler(forName: "consoleDebug")
|
||||||
|
configuration.userContentController.removeScriptMessageHandler(forName: "consoleError")
|
||||||
|
configuration.userContentController.removeScriptMessageHandler(forName: "consoleInfo")
|
||||||
|
configuration.userContentController.removeScriptMessageHandler(forName: "consoleWarn")
|
||||||
|
configuration.userContentController.removeScriptMessageHandler(forName: "callHandler")
|
||||||
|
configuration.userContentController.removeScriptMessageHandler(forName: "onFindResultReceived")
|
||||||
|
configuration.userContentController.removeScriptMessageHandler(forName: "onNavigationStateChange")
|
||||||
|
configuration.userContentController.removeAllUserScripts()
|
||||||
|
removeObserver(self, forKeyPath: "estimatedProgress")
|
||||||
|
super.removeFromSuperview()
|
||||||
|
uiDelegate = nil
|
||||||
|
navigationDelegate = nil
|
||||||
|
scrollView.delegate = nil
|
||||||
|
IAWController?.channel?.setMethodCallHandler(nil)
|
||||||
|
IABController?.webView = nil
|
||||||
|
IAWController?.webView = nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ public class InAppWebViewOptions: Options {
|
||||||
var useOnTargetBlank = false
|
var useOnTargetBlank = false
|
||||||
var clearCache = false
|
var clearCache = false
|
||||||
var userAgent = ""
|
var userAgent = ""
|
||||||
|
var applicationNameForUserAgent = ""
|
||||||
var javaScriptEnabled = true
|
var javaScriptEnabled = true
|
||||||
var debuggingEnabled = true
|
var debuggingEnabled = true
|
||||||
var javaScriptCanOpenWindowsAutomatically = false
|
var javaScriptCanOpenWindowsAutomatically = false
|
||||||
|
@ -25,11 +26,15 @@ public class InAppWebViewOptions: Options {
|
||||||
var horizontalScrollBarEnabled = true
|
var horizontalScrollBarEnabled = true
|
||||||
var resourceCustomSchemes: [String] = []
|
var resourceCustomSchemes: [String] = []
|
||||||
var contentBlockers: [[String: [String : Any]]] = []
|
var contentBlockers: [[String: [String : Any]]] = []
|
||||||
var minimumFontSize = 0;
|
var minimumFontSize = 0
|
||||||
|
var useShouldInterceptAjaxRequest = false
|
||||||
|
var useShouldInterceptFetchRequest = false
|
||||||
|
var incognito = false
|
||||||
|
var cacheEnabled = true
|
||||||
|
var transparentBackground = false
|
||||||
|
|
||||||
var disallowOverScroll = false
|
var disallowOverScroll = false
|
||||||
var enableViewportScale = false
|
var enableViewportScale = false
|
||||||
//var keyboardDisplayRequiresUserAction = true
|
|
||||||
var suppressesIncrementalRendering = false
|
var suppressesIncrementalRendering = false
|
||||||
var allowsAirPlayForMediaPlayback = true
|
var allowsAirPlayForMediaPlayback = true
|
||||||
var allowsBackForwardNavigationGestures = true
|
var allowsBackForwardNavigationGestures = true
|
||||||
|
@ -37,12 +42,11 @@ public class InAppWebViewOptions: Options {
|
||||||
var ignoresViewportScaleLimits = false
|
var ignoresViewportScaleLimits = false
|
||||||
var allowsInlineMediaPlayback = false
|
var allowsInlineMediaPlayback = false
|
||||||
var allowsPictureInPictureMediaPlayback = true
|
var allowsPictureInPictureMediaPlayback = true
|
||||||
var transparentBackground = false
|
|
||||||
var applicationNameForUserAgent = "";
|
|
||||||
var isFraudulentWebsiteWarningEnabled = true;
|
var isFraudulentWebsiteWarningEnabled = true;
|
||||||
var selectionGranularity = 0;
|
var selectionGranularity = 0;
|
||||||
var dataDetectorTypes: [String] = ["NONE"]; // WKDataDetectorTypeNone
|
var dataDetectorTypes: [String] = ["NONE"] // WKDataDetectorTypeNone
|
||||||
var preferredContentMode = 0;
|
var preferredContentMode = 0
|
||||||
|
var sharedCookiesEnabled = false
|
||||||
|
|
||||||
override init(){
|
override init(){
|
||||||
super.init()
|
super.init()
|
||||||
|
|
|
@ -195,19 +195,19 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
||||||
result(false)
|
result(false)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case "injectScriptCode":
|
case "evaluateJavascript":
|
||||||
self.injectScriptCode(uuid: uuid, arguments: arguments!, result: result)
|
self.evaluateJavascript(uuid: uuid, arguments: arguments!, result: result)
|
||||||
break
|
break
|
||||||
case "injectScriptFile":
|
case "injectJavascriptFileFromUrl":
|
||||||
self.injectScriptFile(uuid: uuid, arguments: arguments!)
|
self.injectJavascriptFileFromUrl(uuid: uuid, arguments: arguments!)
|
||||||
result(true)
|
result(true)
|
||||||
break
|
break
|
||||||
case "injectStyleCode":
|
case "injectCSSCode":
|
||||||
self.injectStyleCode(uuid: uuid, arguments: arguments!)
|
self.injectCSSCode(uuid: uuid, arguments: arguments!)
|
||||||
result(true)
|
result(true)
|
||||||
break
|
break
|
||||||
case "injectStyleFile":
|
case "injectCSSFileFromUrl":
|
||||||
self.injectStyleFile(uuid: uuid, arguments: arguments!)
|
self.injectCSSFileFromUrl(uuid: uuid, arguments: arguments!)
|
||||||
result(true)
|
result(true)
|
||||||
break
|
break
|
||||||
case "takeScreenshot":
|
case "takeScreenshot":
|
||||||
|
@ -665,30 +665,30 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func injectScriptCode(uuid: String, arguments: NSDictionary, result: @escaping FlutterResult) {
|
public func evaluateJavascript(uuid: String, arguments: NSDictionary, result: @escaping FlutterResult) {
|
||||||
if let webViewController = self.webViewControllers[uuid] {
|
if let webViewController = self.webViewControllers[uuid] {
|
||||||
webViewController!.webView.injectScriptCode(source: arguments["source"] as! String, result: result)
|
webViewController!.webView.evaluateJavascript(source: arguments["source"] as! String, result: result)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result(FlutterError(code: "InAppBrowserFlutterPlugin", message: "webView is null", details: nil))
|
result(FlutterError(code: "InAppBrowserFlutterPlugin", message: "webView is null", details: nil))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func injectScriptFile(uuid: String, arguments: NSDictionary) {
|
public func injectJavascriptFileFromUrl(uuid: String, arguments: NSDictionary) {
|
||||||
if let webViewController = self.webViewControllers[uuid] {
|
if let webViewController = self.webViewControllers[uuid] {
|
||||||
webViewController!.webView.injectScriptFile(urlFile: arguments["urlFile"] as! String)
|
webViewController!.webView.injectJavascriptFileFromUrl(urlFile: arguments["urlFile"] as! String)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func injectStyleCode(uuid: String, arguments: NSDictionary) {
|
public func injectCSSCode(uuid: String, arguments: NSDictionary) {
|
||||||
if let webViewController = self.webViewControllers[uuid] {
|
if let webViewController = self.webViewControllers[uuid] {
|
||||||
webViewController!.webView.injectStyleCode(source: arguments["source"] as! String)
|
webViewController!.webView.injectCSSCode(source: arguments["source"] as! String)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func injectStyleFile(uuid: String, arguments: NSDictionary) {
|
public func injectCSSFileFromUrl(uuid: String, arguments: NSDictionary) {
|
||||||
if let webViewController = self.webViewControllers[uuid] {
|
if let webViewController = self.webViewControllers[uuid] {
|
||||||
webViewController!.webView.injectStyleFile(urlFile: arguments["urlFile"] as! String)
|
webViewController!.webView.injectCSSFileFromUrl(urlFile: arguments["urlFile"] as! String)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,5 +19,4 @@ A new Flutter plugin.
|
||||||
|
|
||||||
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' }
|
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' }
|
||||||
s.swift_version = '5.0'
|
s.swift_version = '5.0'
|
||||||
s.dependency "WKWebViewWithURLProtocol"
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -483,6 +483,36 @@ class InAppBrowser {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
Future<AjaxRequest> shouldInterceptAjaxRequest(AjaxRequest ajaxRequest) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
Future<AjaxRequestAction> onAjaxReadyStateChange(AjaxRequest ajaxRequest) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
Future<AjaxRequestAction> onAjaxProgress(AjaxRequest ajaxRequest) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
Future<FetchRequest> shouldInterceptFetchRequest(FetchRequest fetchRequest) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
///Event fired when the navigation state of the [InAppWebView] changes throught the usage of
|
||||||
|
///javascript **[History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API)** functions (`pushState()`, `replaceState()`) and `onpopstate` event.
|
||||||
|
///
|
||||||
|
///Also, the event is fired when the javascript `window.location` changes without reloading the webview (for example appending or modifying an hash to the url).
|
||||||
|
///
|
||||||
|
///[url] represents the new url.
|
||||||
|
void onNavigationStateChange(String url) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void throwIsAlreadyOpened({String message = ''}) {
|
void throwIsAlreadyOpened({String message = ''}) {
|
||||||
if (this.isOpened()) {
|
if (this.isOpened()) {
|
||||||
throw Exception(['Error: ${ (message.isEmpty) ? '' : message + ' '}The browser is already opened.']);
|
throw Exception(['Error: ${ (message.isEmpty) ? '' : message + ' '}The browser is already opened.']);
|
||||||
|
|
|
@ -16,30 +16,7 @@ import 'types.dart';
|
||||||
import 'in_app_browser.dart';
|
import 'in_app_browser.dart';
|
||||||
import 'webview_options.dart';
|
import 'webview_options.dart';
|
||||||
|
|
||||||
/*
|
const javaScriptHandlerForbiddenNames = ["onLoadResource", "shouldInterceptAjaxRequest", "onAjaxReadyStateChange", "onAjaxProgress", "shouldInterceptFetchRequest"];
|
||||||
* TODO: injectJavaScriptBeforeLoad
|
|
||||||
*/
|
|
||||||
|
|
||||||
///Initial [data] as a content for an [InAppWebView] instance, using [baseUrl] as the base URL for it.
|
|
||||||
///The [mimeType] property specifies the format of the data.
|
|
||||||
///The [encoding] property specifies the encoding of the data.
|
|
||||||
class InAppWebViewInitialData {
|
|
||||||
String data;
|
|
||||||
String mimeType;
|
|
||||||
String encoding;
|
|
||||||
String baseUrl;
|
|
||||||
|
|
||||||
InAppWebViewInitialData(this.data, {this.mimeType = "text/html", this.encoding = "utf8", this.baseUrl = "about:blank"});
|
|
||||||
|
|
||||||
Map<String, String> toMap() {
|
|
||||||
return {
|
|
||||||
"data": data,
|
|
||||||
"mimeType": mimeType,
|
|
||||||
"encoding": encoding,
|
|
||||||
"baseUrl": baseUrl
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///InAppWebView Widget class.
|
///InAppWebView Widget class.
|
||||||
///
|
///
|
||||||
|
@ -64,7 +41,7 @@ class InAppWebViewInitialData {
|
||||||
/// - __builtInZoomControls__: Set to `true` if the WebView should use its built-in zoom mechanisms. The default value is `false`.
|
/// - __builtInZoomControls__: Set to `true` if the WebView should use its built-in zoom mechanisms. The default value is `false`.
|
||||||
/// - __displayZoomControls__: Set to `true` if the WebView should display on-screen zoom controls when using the built-in zoom mechanisms. The default value is `false`.
|
/// - __displayZoomControls__: Set to `true` if the WebView should display on-screen zoom controls when using the built-in zoom mechanisms. The default value is `false`.
|
||||||
/// - __supportZoom__: Set to `false` if the WebView should not support zooming using its on-screen zoom controls and gestures. The default value is `true`.
|
/// - __supportZoom__: Set to `false` if the WebView should not support zooming using its on-screen zoom controls and gestures. The default value is `true`.
|
||||||
/// - __databaseEnabled__: Set to `true` if you want the database storage API is enabled. The default value is `false`.
|
/// - __databaseEnabled__: Set to `true` if you want injectScriptFilethe database storage API is enabled. The default value is `false`.
|
||||||
/// - __domStorageEnabled__: Set to `true` if you want the DOM storage API is enabled. The default value is `false`.
|
/// - __domStorageEnabled__: Set to `true` if you want the DOM storage API is enabled. The default value is `false`.
|
||||||
/// - __useWideViewPort__: Set to `true` if the WebView should enable support for the "viewport" HTML meta tag or should use a wide viewport. When the value of the setting is false, the layout width is always set to the width of the WebView control in device-independent (CSS) pixels. When the value is true and the page contains the viewport meta tag, the value of the width specified in the tag is used. If the page does not contain the tag or does not provide a width, then a wide viewport will be used. The default value is `true`.
|
/// - __useWideViewPort__: Set to `true` if the WebView should enable support for the "viewport" HTML meta tag or should use a wide viewport. When the value of the setting is false, the layout width is always set to the width of the WebView control in device-independent (CSS) pixels. When the value is true and the page contains the viewport meta tag, the value of the width specified in the tag is used. If the page does not contain the tag or does not provide a width, then a wide viewport will be used. The default value is `true`.
|
||||||
/// - __safeBrowsingEnabled__: Set to `true` if you want the Safe Browsing is enabled. Safe Browsing allows WebView to protect against malware and phishing attacks by verifying the links. The default value is `true`.
|
/// - __safeBrowsingEnabled__: Set to `true` if you want the Safe Browsing is enabled. Safe Browsing allows WebView to protect against malware and phishing attacks by verifying the links. The default value is `true`.
|
||||||
|
@ -198,6 +175,26 @@ class InAppWebView extends StatefulWidget {
|
||||||
///[isDoneCounting] whether the find operation has actually completed.
|
///[isDoneCounting] whether the find operation has actually completed.
|
||||||
final void Function(InAppWebViewController controller, int activeMatchOrdinal, int numberOfMatches, bool isDoneCounting) onFindResultReceived;
|
final void Function(InAppWebViewController controller, int activeMatchOrdinal, int numberOfMatches, bool isDoneCounting) onFindResultReceived;
|
||||||
|
|
||||||
|
///
|
||||||
|
final Future<AjaxRequest> Function(InAppWebViewController controller, AjaxRequest ajaxRequest) shouldInterceptAjaxRequest;
|
||||||
|
|
||||||
|
///
|
||||||
|
final Future<AjaxRequestAction> Function(InAppWebViewController controller, AjaxRequest ajaxRequest) onAjaxReadyStateChange;
|
||||||
|
|
||||||
|
///
|
||||||
|
final Future<AjaxRequestAction> Function(InAppWebViewController controller, AjaxRequest ajaxRequest) onAjaxProgress;
|
||||||
|
|
||||||
|
///
|
||||||
|
final Future<FetchRequest> Function(InAppWebViewController controller, FetchRequest fetchRequest) shouldInterceptFetchRequest;
|
||||||
|
|
||||||
|
///Event fired when the navigation state of the [InAppWebView] changes throught the usage of
|
||||||
|
///javascript **[History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API)** functions (`pushState()`, `replaceState()`) and `onpopstate` event.
|
||||||
|
///
|
||||||
|
///Also, the event is fired when the javascript `window.location` changes without reloading the webview (for example appending or modifying an hash to the url).
|
||||||
|
///
|
||||||
|
///[url] represents the new url.
|
||||||
|
final void Function(InAppWebViewController controller, String url) onNavigationStateChange;
|
||||||
|
|
||||||
///Initial url that will be loaded.
|
///Initial url that will be loaded.
|
||||||
final String initialUrl;
|
final String initialUrl;
|
||||||
///Initial asset file that will be loaded. See [InAppWebView.loadFile()] for explanation.
|
///Initial asset file that will be loaded. See [InAppWebView.loadFile()] for explanation.
|
||||||
|
@ -245,6 +242,11 @@ class InAppWebView extends StatefulWidget {
|
||||||
this.onReceivedServerTrustAuthRequest,
|
this.onReceivedServerTrustAuthRequest,
|
||||||
this.onReceivedClientCertRequest,
|
this.onReceivedClientCertRequest,
|
||||||
this.onFindResultReceived,
|
this.onFindResultReceived,
|
||||||
|
this.shouldInterceptAjaxRequest,
|
||||||
|
this.onAjaxReadyStateChange,
|
||||||
|
this.onAjaxProgress,
|
||||||
|
this.shouldInterceptFetchRequest,
|
||||||
|
this.onNavigationStateChange,
|
||||||
this.gestureRecognizers,
|
this.gestureRecognizers,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@ -323,6 +325,13 @@ class _InAppWebViewState extends State<InAppWebView> {
|
||||||
super.didUpdateWidget(oldWidget);
|
super.didUpdateWidget(oldWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose(){
|
||||||
|
super.dispose();
|
||||||
|
if (Platform.isIOS)
|
||||||
|
_controller._channel.invokeMethod('removeFromSuperview');
|
||||||
|
}
|
||||||
|
|
||||||
void _onPlatformViewCreated(int id) {
|
void _onPlatformViewCreated(int id) {
|
||||||
_controller = InAppWebViewController(id, widget);
|
_controller = InAppWebViewController(id, widget);
|
||||||
if (widget.onWebViewCreated != null) {
|
if (widget.onWebViewCreated != null) {
|
||||||
|
@ -399,19 +408,6 @@ class InAppWebViewController {
|
||||||
else if (_inAppBrowser != null)
|
else if (_inAppBrowser != null)
|
||||||
_inAppBrowser.shouldOverrideUrlLoading(url);
|
_inAppBrowser.shouldOverrideUrlLoading(url);
|
||||||
break;
|
break;
|
||||||
case "onLoadResource":
|
|
||||||
String initiatorType = call.arguments["initiatorType"];
|
|
||||||
String url = call.arguments["url"];
|
|
||||||
double startTime = call.arguments["startTime"];
|
|
||||||
double duration = call.arguments["duration"];
|
|
||||||
|
|
||||||
var response = new LoadedResource(initiatorType, url, startTime, duration);
|
|
||||||
|
|
||||||
if (_widget != null && _widget.onLoadResource != null)
|
|
||||||
_widget.onLoadResource(this, response);
|
|
||||||
else if (_inAppBrowser != null)
|
|
||||||
_inAppBrowser.onLoadResource(response);
|
|
||||||
break;
|
|
||||||
case "onConsoleMessage":
|
case "onConsoleMessage":
|
||||||
String sourceURL = call.arguments["sourceURL"];
|
String sourceURL = call.arguments["sourceURL"];
|
||||||
int lineNumber = call.arguments["lineNumber"];
|
int lineNumber = call.arguments["lineNumber"];
|
||||||
|
@ -551,10 +547,133 @@ class InAppWebViewController {
|
||||||
else if (_inAppBrowser != null)
|
else if (_inAppBrowser != null)
|
||||||
_inAppBrowser.onFindResultReceived(activeMatchOrdinal, numberOfMatches, isDoneCounting);
|
_inAppBrowser.onFindResultReceived(activeMatchOrdinal, numberOfMatches, isDoneCounting);
|
||||||
break;
|
break;
|
||||||
|
case "onNavigationStateChange":
|
||||||
|
String url = call.arguments["url"];
|
||||||
|
if (_widget != null && _widget.onNavigationStateChange != null)
|
||||||
|
_widget.onNavigationStateChange(this, url);
|
||||||
|
else if (_inAppBrowser != null)
|
||||||
|
_inAppBrowser.onNavigationStateChange(url);
|
||||||
|
break;
|
||||||
case "onCallJsHandler":
|
case "onCallJsHandler":
|
||||||
String handlerName = call.arguments["handlerName"];
|
String handlerName = call.arguments["handlerName"];
|
||||||
// decode args to json
|
// decode args to json
|
||||||
List<dynamic> args = jsonDecode(call.arguments["args"]);
|
List<dynamic> args = jsonDecode(call.arguments["args"]);
|
||||||
|
|
||||||
|
switch(handlerName) {
|
||||||
|
case "onLoadResource":
|
||||||
|
Map<dynamic, dynamic> argMap = args[0];
|
||||||
|
String initiatorType = argMap["initiatorType"];
|
||||||
|
String url = argMap["name"];
|
||||||
|
double startTime = argMap["startTime"] is int ? argMap["startTime"].toDouble() : argMap["startTime"];
|
||||||
|
double duration = argMap["duration"] is int ? argMap["duration"].toDouble() : argMap["duration"];
|
||||||
|
|
||||||
|
var response = new LoadedResource(initiatorType, url, startTime, duration);
|
||||||
|
|
||||||
|
if (_widget != null && _widget.onLoadResource != null)
|
||||||
|
_widget.onLoadResource(this, response);
|
||||||
|
else if (_inAppBrowser != null)
|
||||||
|
_inAppBrowser.onLoadResource(response);
|
||||||
|
return null;
|
||||||
|
case "shouldInterceptAjaxRequest":
|
||||||
|
Map<dynamic, dynamic> argMap = args[0];
|
||||||
|
dynamic data = argMap["data"];
|
||||||
|
String method = argMap["method"];
|
||||||
|
String url = argMap["url"];
|
||||||
|
bool isAsync = argMap["isAsync"];
|
||||||
|
String user = argMap["user"];
|
||||||
|
String password = argMap["password"];
|
||||||
|
bool withCredentials = argMap["withCredentials"];
|
||||||
|
Map<dynamic, dynamic> headers = argMap["headers"];
|
||||||
|
|
||||||
|
var request = new AjaxRequest(data: data, method: method, url: url, isAsync: isAsync, user: user, password: password, withCredentials: withCredentials, headers: headers);
|
||||||
|
|
||||||
|
if (_widget != null && _widget.shouldInterceptAjaxRequest != null)
|
||||||
|
return jsonEncode(await _widget.shouldInterceptAjaxRequest(this, request));
|
||||||
|
else if (_inAppBrowser != null)
|
||||||
|
return jsonEncode(await _inAppBrowser.shouldInterceptAjaxRequest(request));
|
||||||
|
return null;
|
||||||
|
case "onAjaxReadyStateChange":
|
||||||
|
Map<dynamic, dynamic> argMap = args[0];
|
||||||
|
dynamic data = argMap["data"];
|
||||||
|
String method = argMap["method"];
|
||||||
|
String url = argMap["url"];
|
||||||
|
bool isAsync = argMap["isAsync"];
|
||||||
|
String user = argMap["user"];
|
||||||
|
String password = argMap["password"];
|
||||||
|
bool withCredentials = argMap["withCredentials"];
|
||||||
|
Map<dynamic, dynamic> headers = argMap["headers"];
|
||||||
|
int readyState = argMap["readyState"];
|
||||||
|
int status = argMap["status"];
|
||||||
|
String responseURL = argMap["responseURL"];
|
||||||
|
String responseType = argMap["responseType"];
|
||||||
|
String responseText = argMap["responseText"];
|
||||||
|
String statusText = argMap["statusText"];
|
||||||
|
Map<dynamic, dynamic> responseHeaders = argMap["responseHeaders"];
|
||||||
|
|
||||||
|
var request = new AjaxRequest(data: data, method: method, url: url, isAsync: isAsync, user: user, password: password,
|
||||||
|
withCredentials: withCredentials, headers: headers, readyState: AjaxRequestReadyState.fromValue(readyState), status: status, responseURL: responseURL,
|
||||||
|
responseType: responseType, responseText: responseText, statusText: statusText, responseHeaders: responseHeaders);
|
||||||
|
|
||||||
|
if (_widget != null && _widget.onAjaxReadyStateChange != null)
|
||||||
|
return jsonEncode(await _widget.onAjaxReadyStateChange(this, request));
|
||||||
|
else if (_inAppBrowser != null)
|
||||||
|
return jsonEncode(await _inAppBrowser.onAjaxReadyStateChange(request));
|
||||||
|
return null;
|
||||||
|
case "onAjaxProgress":
|
||||||
|
Map<dynamic, dynamic> argMap = args[0];
|
||||||
|
dynamic data = argMap["data"];
|
||||||
|
String method = argMap["method"];
|
||||||
|
String url = argMap["url"];
|
||||||
|
bool isAsync = argMap["isAsync"];
|
||||||
|
String user = argMap["user"];
|
||||||
|
String password = argMap["password"];
|
||||||
|
bool withCredentials = argMap["withCredentials"];
|
||||||
|
Map<dynamic, dynamic> headers = argMap["headers"];
|
||||||
|
int readyState = argMap["readyState"];
|
||||||
|
int status = argMap["status"];
|
||||||
|
String responseURL = argMap["responseURL"];
|
||||||
|
String responseType = argMap["responseType"];
|
||||||
|
String responseText = argMap["responseText"];
|
||||||
|
String statusText = argMap["statusText"];
|
||||||
|
Map<dynamic, dynamic> responseHeaders = argMap["responseHeaders"];
|
||||||
|
Map<dynamic, dynamic> eventMap = argMap["event"];
|
||||||
|
|
||||||
|
AjaxRequestEvent event = AjaxRequestEvent(lengthComputable: eventMap["lengthComputable"], loaded: eventMap["loaded"], type: AjaxRequestEventType.fromValue(eventMap["type"]));
|
||||||
|
|
||||||
|
var request = new AjaxRequest(data: data, method: method, url: url, isAsync: isAsync, user: user, password: password,
|
||||||
|
withCredentials: withCredentials, headers: headers, readyState: AjaxRequestReadyState.fromValue(readyState), status: status, responseURL: responseURL,
|
||||||
|
responseType: responseType, responseText: responseText, statusText: statusText, responseHeaders: responseHeaders, event: event);
|
||||||
|
|
||||||
|
if (_widget != null && _widget.onAjaxProgress != null)
|
||||||
|
return jsonEncode(await _widget.onAjaxProgress(this, request));
|
||||||
|
else if (_inAppBrowser != null)
|
||||||
|
return jsonEncode(await _inAppBrowser.onAjaxProgress(request));
|
||||||
|
return null;
|
||||||
|
case "shouldInterceptFetchRequest":
|
||||||
|
Map<dynamic, dynamic> argMap = args[0];
|
||||||
|
String url = argMap["url"];
|
||||||
|
String method = argMap["method"];
|
||||||
|
Map<dynamic, dynamic> headers = argMap["headers"];
|
||||||
|
Uint8List body = Uint8List.fromList(argMap["body"].cast<int>());
|
||||||
|
String mode = argMap["mode"];
|
||||||
|
FetchRequestCredential credentials = FetchRequest.createFetchRequestCredentialFromMap(argMap["credentials"]);
|
||||||
|
String cache = argMap["cache"];
|
||||||
|
String redirect = argMap["redirect"];
|
||||||
|
String referrer = argMap["referrer"];
|
||||||
|
String referrerPolicy = argMap["referrerPolicy"];
|
||||||
|
String integrity = argMap["integrity"];
|
||||||
|
bool keepalive = argMap["keepalive"];
|
||||||
|
|
||||||
|
var request = new FetchRequest(url: url, method: method, headers: headers, body: body, mode: mode, credentials: credentials,
|
||||||
|
cache: cache, redirect: redirect, referrer: referrer, referrerPolicy: referrerPolicy, integrity: integrity, keepalive: keepalive);
|
||||||
|
|
||||||
|
if (_widget != null && _widget.shouldInterceptFetchRequest != null)
|
||||||
|
return jsonEncode(await _widget.shouldInterceptFetchRequest(this, request));
|
||||||
|
else if (_inAppBrowser != null)
|
||||||
|
return jsonEncode(await _inAppBrowser.shouldInterceptFetchRequest(request));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (javaScriptHandlersMap.containsKey(handlerName)) {
|
if (javaScriptHandlersMap.containsKey(handlerName)) {
|
||||||
// convert result to json
|
// convert result to json
|
||||||
try {
|
try {
|
||||||
|
@ -609,7 +728,7 @@ class InAppWebViewController {
|
||||||
var html = "";
|
var html = "";
|
||||||
InAppWebViewWidgetOptions options = await getOptions();
|
InAppWebViewWidgetOptions options = await getOptions();
|
||||||
if (options != null && options.inAppWebViewOptions.javaScriptEnabled == true) {
|
if (options != null && options.inAppWebViewOptions.javaScriptEnabled == true) {
|
||||||
html = await injectScriptCode("window.document.getElementsByTagName('html')[0].outerHTML;");
|
html = await evaluateJavascript("window.document.getElementsByTagName('html')[0].outerHTML;");
|
||||||
if (html.isNotEmpty)
|
if (html.isNotEmpty)
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
@ -828,7 +947,7 @@ class InAppWebViewController {
|
||||||
await _channel.invokeMethod('loadFile', args);
|
await _channel.invokeMethod('loadFile', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Reloads the [InAppWebView] window.
|
///Reloads the [InAppWebView].
|
||||||
Future<void> reload() async {
|
Future<void> reload() async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
if (_inAppBrowserUuid != null && _inAppBrowser != null) {
|
if (_inAppBrowserUuid != null && _inAppBrowser != null) {
|
||||||
|
@ -838,7 +957,7 @@ class InAppWebViewController {
|
||||||
await _channel.invokeMethod('reload', args);
|
await _channel.invokeMethod('reload', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Goes back in the history of the [InAppWebView] window.
|
///Goes back in the history of the [InAppWebView].
|
||||||
Future<void> goBack() async {
|
Future<void> goBack() async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
if (_inAppBrowserUuid != null && _inAppBrowser != null) {
|
if (_inAppBrowserUuid != null && _inAppBrowser != null) {
|
||||||
|
@ -858,7 +977,7 @@ class InAppWebViewController {
|
||||||
return await _channel.invokeMethod('canGoBack', args);
|
return await _channel.invokeMethod('canGoBack', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Goes forward in the history of the [InAppWebView] window.
|
///Goes forward in the history of the [InAppWebView].
|
||||||
Future<void> goForward() async {
|
Future<void> goForward() async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
if (_inAppBrowserUuid != null && _inAppBrowser != null) {
|
if (_inAppBrowserUuid != null && _inAppBrowser != null) {
|
||||||
|
@ -929,41 +1048,47 @@ class InAppWebViewController {
|
||||||
await _channel.invokeMethod('stopLoading', args);
|
await _channel.invokeMethod('stopLoading', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Injects JavaScript code into the [InAppWebView] window and returns the result of the evaluation.
|
///Evaluates JavaScript code into the [InAppWebView] and returns the result of the evaluation.
|
||||||
Future<String> injectScriptCode(String source) async {
|
Future<String> evaluateJavascript(String source) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
if (_inAppBrowserUuid != null && _inAppBrowser != null) {
|
if (_inAppBrowserUuid != null && _inAppBrowser != null) {
|
||||||
_inAppBrowser.throwIsNotOpened();
|
_inAppBrowser.throwIsNotOpened();
|
||||||
args.putIfAbsent('uuid', () => _inAppBrowserUuid);
|
args.putIfAbsent('uuid', () => _inAppBrowserUuid);
|
||||||
}
|
}
|
||||||
args.putIfAbsent('source', () => source);
|
args.putIfAbsent('source', () => source);
|
||||||
return await _channel.invokeMethod('injectScriptCode', args);
|
return await _channel.invokeMethod('evaluateJavascript', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Injects a JavaScript file into the [InAppWebView] window.
|
///Injects an external JavaScript file into the [InAppWebView] from a defined url.
|
||||||
Future<void> injectScriptFile(String urlFile) async {
|
Future<void> injectJavascriptFileFromUrl(String urlFile) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
if (_inAppBrowserUuid != null && _inAppBrowser != null) {
|
if (_inAppBrowserUuid != null && _inAppBrowser != null) {
|
||||||
_inAppBrowser.throwIsNotOpened();
|
_inAppBrowser.throwIsNotOpened();
|
||||||
args.putIfAbsent('uuid', () => _inAppBrowserUuid);
|
args.putIfAbsent('uuid', () => _inAppBrowserUuid);
|
||||||
}
|
}
|
||||||
args.putIfAbsent('urlFile', () => urlFile);
|
args.putIfAbsent('urlFile', () => urlFile);
|
||||||
await _channel.invokeMethod('injectScriptFile', args);
|
await _channel.invokeMethod('injectJavascriptFileFromUrl', args);
|
||||||
|
}
|
||||||
|
|
||||||
|
///Injects a JavaScript file into the [InAppWebView] from the flutter assets directory.
|
||||||
|
Future<void> injectJavascriptFileFromAsset(String assetFilePath) async {
|
||||||
|
String source = await rootBundle.loadString(assetFilePath);
|
||||||
|
await evaluateJavascript(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Injects CSS into the [InAppWebView] window.
|
///Injects CSS into the [InAppWebView].
|
||||||
Future<void> injectStyleCode(String source) async {
|
Future<void> injectCSSCode(String source) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
if (_inAppBrowserUuid != null && _inAppBrowser != null) {
|
if (_inAppBrowserUuid != null && _inAppBrowser != null) {
|
||||||
_inAppBrowser.throwIsNotOpened();
|
_inAppBrowser.throwIsNotOpened();
|
||||||
args.putIfAbsent('uuid', () => _inAppBrowserUuid);
|
args.putIfAbsent('uuid', () => _inAppBrowserUuid);
|
||||||
}
|
}
|
||||||
args.putIfAbsent('source', () => source);
|
args.putIfAbsent('source', () => source);
|
||||||
await _channel.invokeMethod('injectStyleCode', args);
|
await _channel.invokeMethod('injectCSSCode', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Injects a CSS file into the [InAppWebView] window.
|
///Injects an external CSS file into the [InAppWebView] from a defined url.
|
||||||
Future<void> injectStyleFile(String urlFile) async {
|
Future<void> injectCSSFileFromUrl(String urlFile) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
if (_inAppBrowserUuid != null && _inAppBrowser != null) {
|
if (_inAppBrowserUuid != null && _inAppBrowser != null) {
|
||||||
_inAppBrowser.throwIsNotOpened();
|
_inAppBrowser.throwIsNotOpened();
|
||||||
|
@ -973,6 +1098,12 @@ class InAppWebViewController {
|
||||||
await _channel.invokeMethod('injectStyleFile', args);
|
await _channel.invokeMethod('injectStyleFile', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///Injects a CSS file into the [InAppWebView] from the flutter assets directory.
|
||||||
|
Future<void> injectCSSFileFromAsset(String assetFilePath) async {
|
||||||
|
String source = await rootBundle.loadString(assetFilePath);
|
||||||
|
await injectCSSCode(source);
|
||||||
|
}
|
||||||
|
|
||||||
///Adds a JavaScript message handler [callback] ([JavaScriptHandlerCallback]) that listen to post messages sent from JavaScript by the handler with name [handlerName].
|
///Adds a JavaScript message handler [callback] ([JavaScriptHandlerCallback]) that listen to post messages sent from JavaScript by the handler with name [handlerName].
|
||||||
///
|
///
|
||||||
///The Android implementation uses [addJavascriptInterface](https://developer.android.com/reference/android/webkit/WebView#addJavascriptInterface(java.lang.Object,%20java.lang.String)).
|
///The Android implementation uses [addJavascriptInterface](https://developer.android.com/reference/android/webkit/WebView#addJavascriptInterface(java.lang.Object,%20java.lang.String)).
|
||||||
|
@ -1020,6 +1151,7 @@ class InAppWebViewController {
|
||||||
/// """);
|
/// """);
|
||||||
///```
|
///```
|
||||||
void addJavaScriptHandler(String handlerName, JavaScriptHandlerCallback callback) {
|
void addJavaScriptHandler(String handlerName, JavaScriptHandlerCallback callback) {
|
||||||
|
assert(!javaScriptHandlerForbiddenNames.contains(handlerName));
|
||||||
this.javaScriptHandlersMap[handlerName] = (callback);
|
this.javaScriptHandlersMap[handlerName] = (callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,27 @@ class LoadedResource {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///Initial [data] as a content for an [InAppWebView] instance, using [baseUrl] as the base URL for it.
|
||||||
|
///The [mimeType] property specifies the format of the data.
|
||||||
|
///The [encoding] property specifies the encoding of the data.
|
||||||
|
class InAppWebViewInitialData {
|
||||||
|
String data;
|
||||||
|
String mimeType;
|
||||||
|
String encoding;
|
||||||
|
String baseUrl;
|
||||||
|
|
||||||
|
InAppWebViewInitialData(this.data, {this.mimeType = "text/html", this.encoding = "utf8", this.baseUrl = "about:blank"});
|
||||||
|
|
||||||
|
Map<String, String> toMap() {
|
||||||
|
return {
|
||||||
|
"data": data,
|
||||||
|
"mimeType": mimeType,
|
||||||
|
"encoding": encoding,
|
||||||
|
"baseUrl": baseUrl
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
///Public class representing a resource request of the WebView.
|
///Public class representing a resource request of the WebView.
|
||||||
///It is used by the event [shouldInterceptRequest()].
|
///It is used by the event [shouldInterceptRequest()].
|
||||||
|
@ -671,4 +692,257 @@ class ChromeSafariBrowserClassOptions {
|
||||||
IosSafariOptions iosSafariOptions;
|
IosSafariOptions iosSafariOptions;
|
||||||
|
|
||||||
ChromeSafariBrowserClassOptions({this.androidChromeCustomTabsOptions, this.iosSafariOptions});
|
ChromeSafariBrowserClassOptions({this.androidChromeCustomTabsOptions, this.iosSafariOptions});
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class AjaxRequestAction {
|
||||||
|
final int _value;
|
||||||
|
const AjaxRequestAction._internal(this._value);
|
||||||
|
toValue() => _value;
|
||||||
|
|
||||||
|
static const ABORT = const AjaxRequestAction._internal(0);
|
||||||
|
static const PROCEED = const AjaxRequestAction._internal(1);
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
"action": _value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return this.toMap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class AjaxRequestEventType {
|
||||||
|
final String _value;
|
||||||
|
const AjaxRequestEventType._internal(this._value);
|
||||||
|
static AjaxRequestEventType fromValue(String value) {
|
||||||
|
return (["loadstart", "load", "loadend", "progress", "error", "abort"].contains(value)) ? AjaxRequestEventType._internal(value) : null;
|
||||||
|
}
|
||||||
|
toValue() => _value;
|
||||||
|
String toString() => _value;
|
||||||
|
|
||||||
|
static const LOADSTART = const AjaxRequestEventType._internal("loadstart");
|
||||||
|
static const LOAD = const AjaxRequestEventType._internal("load");
|
||||||
|
static const LOADEND = const AjaxRequestEventType._internal("loadend");
|
||||||
|
static const PROGRESS = const AjaxRequestEventType._internal("progress");
|
||||||
|
static const ERROR = const AjaxRequestEventType._internal("error");
|
||||||
|
static const ABORT = const AjaxRequestEventType._internal("abort");
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class AjaxRequestEvent {
|
||||||
|
AjaxRequestEventType type;
|
||||||
|
int loaded;
|
||||||
|
bool lengthComputable;
|
||||||
|
|
||||||
|
AjaxRequestEvent({this.type, this.loaded, this.lengthComputable});
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class AjaxRequestReadyState {
|
||||||
|
final int _value;
|
||||||
|
const AjaxRequestReadyState._internal(this._value);
|
||||||
|
static AjaxRequestReadyState fromValue(int value) {
|
||||||
|
if (value != null && value >= 0 && value <= 4)
|
||||||
|
return AjaxRequestReadyState._internal(value);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
toValue() => _value;
|
||||||
|
String toString() => _value.toString();
|
||||||
|
|
||||||
|
static const UNSENT = const AjaxRequestReadyState._internal(0);
|
||||||
|
static const OPENED = const AjaxRequestReadyState._internal(1);
|
||||||
|
static const HEADERS_RECEIVED = const AjaxRequestReadyState._internal(2);
|
||||||
|
static const LOADING = const AjaxRequestReadyState._internal(3);
|
||||||
|
static const DONE = const AjaxRequestReadyState._internal(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class AjaxRequest {
|
||||||
|
dynamic data;
|
||||||
|
String method;
|
||||||
|
String url;
|
||||||
|
bool isAsync;
|
||||||
|
String user;
|
||||||
|
String password;
|
||||||
|
bool withCredentials;
|
||||||
|
Map<dynamic, dynamic> headers;
|
||||||
|
AjaxRequestReadyState readyState;
|
||||||
|
int status;
|
||||||
|
String responseURL;
|
||||||
|
String responseType;
|
||||||
|
String responseText;
|
||||||
|
String statusText;
|
||||||
|
Map<dynamic, dynamic> responseHeaders;
|
||||||
|
AjaxRequestEvent event;
|
||||||
|
AjaxRequestAction action;
|
||||||
|
|
||||||
|
AjaxRequest({this.data, this.method, this.url, this.isAsync, this.user, this.password,
|
||||||
|
this.withCredentials, this.headers, this.readyState, this.status, this.responseURL, this.responseType,
|
||||||
|
this.responseText, this.statusText, this.responseHeaders, this.event, this.action = AjaxRequestAction.PROCEED});
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
"data": data,
|
||||||
|
"method": method,
|
||||||
|
"url": url,
|
||||||
|
"isAsync": isAsync,
|
||||||
|
"user": user,
|
||||||
|
"password": password,
|
||||||
|
"withCredentials": withCredentials,
|
||||||
|
"headers": headers,
|
||||||
|
"readyState": readyState?.toValue(),
|
||||||
|
"status": status,
|
||||||
|
"responseURL": responseURL,
|
||||||
|
"responseType": responseType,
|
||||||
|
"responseText": responseText,
|
||||||
|
"statusText": statusText,
|
||||||
|
"responseHeaders": responseHeaders,
|
||||||
|
"action": action?.toValue()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return this.toMap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class FetchRequestAction {
|
||||||
|
final int _value;
|
||||||
|
const FetchRequestAction._internal(this._value);
|
||||||
|
toValue() => _value;
|
||||||
|
|
||||||
|
static const ABORT = const FetchRequestAction._internal(0);
|
||||||
|
static const PROCEED = const FetchRequestAction._internal(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class FetchRequestCredential {
|
||||||
|
String type;
|
||||||
|
|
||||||
|
FetchRequestCredential({this.type});
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
"type": type
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class FetchRequestCredentialDefault extends FetchRequestCredential {
|
||||||
|
String value;
|
||||||
|
|
||||||
|
FetchRequestCredentialDefault({type, this.value}): super(type: type);
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
"type": type,
|
||||||
|
"value": value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class FetchRequestFederatedCredential extends FetchRequestCredential {
|
||||||
|
dynamic id;
|
||||||
|
String name;
|
||||||
|
String protocol;
|
||||||
|
String provider;
|
||||||
|
String iconURL;
|
||||||
|
|
||||||
|
FetchRequestFederatedCredential({type, this.id, this.name, this.protocol, this.provider, this.iconURL}): super(type: type);
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
"type": type,
|
||||||
|
"id": id,
|
||||||
|
"name": name,
|
||||||
|
"protocol": protocol,
|
||||||
|
"provider": provider,
|
||||||
|
"iconURL": iconURL
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class FetchRequestPasswordCredential extends FetchRequestCredential {
|
||||||
|
dynamic id;
|
||||||
|
String name;
|
||||||
|
String password;
|
||||||
|
String iconURL;
|
||||||
|
|
||||||
|
FetchRequestPasswordCredential({type, this.id, this.name, this.password, this.iconURL}): super(type: type);
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
"type": type,
|
||||||
|
"id": id,
|
||||||
|
"name": name,
|
||||||
|
"password": password,
|
||||||
|
"iconURL": iconURL
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class FetchRequest {
|
||||||
|
String url;
|
||||||
|
String method;
|
||||||
|
Map<String, dynamic> headers;
|
||||||
|
Uint8List body;
|
||||||
|
String mode;
|
||||||
|
FetchRequestCredential credentials;
|
||||||
|
String cache;
|
||||||
|
String redirect;
|
||||||
|
String referrer;
|
||||||
|
String referrerPolicy;
|
||||||
|
String integrity;
|
||||||
|
bool keepalive;
|
||||||
|
FetchRequestAction action;
|
||||||
|
|
||||||
|
FetchRequest({this.url, this.method, this.headers, this.body, this.mode, this.credentials,
|
||||||
|
this.cache, this.redirect, this.referrer, this.referrerPolicy, this.integrity, this.keepalive,
|
||||||
|
this.action = FetchRequestAction.PROCEED});
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
"url": url,
|
||||||
|
"method": method,
|
||||||
|
"headers": headers,
|
||||||
|
"body": body,
|
||||||
|
"mode": mode,
|
||||||
|
"credentials": credentials?.toMap(),
|
||||||
|
"cache": cache,
|
||||||
|
"redirect": redirect,
|
||||||
|
"referrer": referrer,
|
||||||
|
"referrerPolicy": referrerPolicy,
|
||||||
|
"integrity": integrity,
|
||||||
|
"keepalive": keepalive,
|
||||||
|
"action": action?.toValue()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return this.toMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
static FetchRequestCredential createFetchRequestCredentialFromMap(credentialsMap) {
|
||||||
|
if (credentialsMap != null) {
|
||||||
|
if (credentialsMap["type"] == "default") {
|
||||||
|
return FetchRequestCredentialDefault(type: credentialsMap["type"], value: credentialsMap["value"]);
|
||||||
|
} else if (credentialsMap["type"] == "federated") {
|
||||||
|
return FetchRequestFederatedCredential(type: credentialsMap["type"], id: credentialsMap["id"], name: credentialsMap["name"],
|
||||||
|
protocol: credentialsMap["protocol"], provider: credentialsMap["provider"], iconURL: credentialsMap["iconURL"]);
|
||||||
|
} else if (credentialsMap["type"] == "password") {
|
||||||
|
return FetchRequestPasswordCredential(type: credentialsMap["type"], id: credentialsMap["id"], name: credentialsMap["name"],
|
||||||
|
password: credentialsMap["password"], iconURL: credentialsMap["iconURL"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -43,6 +43,7 @@ class InAppWebViewOptions implements WebViewOptions, BrowserOptions, AndroidOpti
|
||||||
bool useOnTargetBlank;
|
bool useOnTargetBlank;
|
||||||
bool clearCache;
|
bool clearCache;
|
||||||
String userAgent;
|
String userAgent;
|
||||||
|
String applicationNameForUserAgent;
|
||||||
bool javaScriptEnabled;
|
bool javaScriptEnabled;
|
||||||
bool debuggingEnabled;
|
bool debuggingEnabled;
|
||||||
bool javaScriptCanOpenWindowsAutomatically;
|
bool javaScriptCanOpenWindowsAutomatically;
|
||||||
|
@ -54,11 +55,17 @@ class InAppWebViewOptions implements WebViewOptions, BrowserOptions, AndroidOpti
|
||||||
List<String> resourceCustomSchemes;
|
List<String> resourceCustomSchemes;
|
||||||
List<ContentBlocker> contentBlockers;
|
List<ContentBlocker> contentBlockers;
|
||||||
InAppWebViewUserPreferredContentMode preferredContentMode;
|
InAppWebViewUserPreferredContentMode preferredContentMode;
|
||||||
|
bool useShouldInterceptAjaxRequest;
|
||||||
|
bool useShouldInterceptFetchRequest;
|
||||||
|
bool incognito;
|
||||||
|
bool cacheEnabled;
|
||||||
|
bool transparentBackground;
|
||||||
|
|
||||||
InAppWebViewOptions({this.useShouldOverrideUrlLoading = false, this.useOnLoadResource = false, this.useOnDownloadStart = false, this.useOnTargetBlank = false,
|
InAppWebViewOptions({this.useShouldOverrideUrlLoading = false, this.useOnLoadResource = false, this.useOnDownloadStart = false, this.useOnTargetBlank = false,
|
||||||
this.clearCache = false, this.userAgent = "", this.javaScriptEnabled = true, this.debuggingEnabled = false, this.javaScriptCanOpenWindowsAutomatically = false,
|
this.clearCache = false, this.userAgent = "", this.applicationNameForUserAgent = "", this.javaScriptEnabled = true, this.debuggingEnabled = false, this.javaScriptCanOpenWindowsAutomatically = false,
|
||||||
this.mediaPlaybackRequiresUserGesture = true, this.textZoom = 100, this.minimumFontSize, this.verticalScrollBarEnabled = true, this.horizontalScrollBarEnabled = true,
|
this.mediaPlaybackRequiresUserGesture = true, this.textZoom = 100, this.minimumFontSize, this.verticalScrollBarEnabled = true, this.horizontalScrollBarEnabled = true,
|
||||||
this.resourceCustomSchemes = const [], this.contentBlockers = const [], this.preferredContentMode = InAppWebViewUserPreferredContentMode.RECOMMENDED}) {
|
this.resourceCustomSchemes = const [], this.contentBlockers = const [], this.preferredContentMode = InAppWebViewUserPreferredContentMode.RECOMMENDED,
|
||||||
|
this.useShouldInterceptAjaxRequest = false, this.useShouldInterceptFetchRequest = false, this.incognito = false, this.cacheEnabled = true, this.transparentBackground = false}) {
|
||||||
if (this.minimumFontSize == null)
|
if (this.minimumFontSize == null)
|
||||||
this.minimumFontSize = Platform.isAndroid ? 8 : 0;
|
this.minimumFontSize = Platform.isAndroid ? 8 : 0;
|
||||||
assert(!this.resourceCustomSchemes.contains("http") && !this.resourceCustomSchemes.contains("https"));
|
assert(!this.resourceCustomSchemes.contains("http") && !this.resourceCustomSchemes.contains("https"));
|
||||||
|
@ -78,6 +85,7 @@ class InAppWebViewOptions implements WebViewOptions, BrowserOptions, AndroidOpti
|
||||||
"useOnTargetBlank": useOnTargetBlank,
|
"useOnTargetBlank": useOnTargetBlank,
|
||||||
"clearCache": clearCache,
|
"clearCache": clearCache,
|
||||||
"userAgent": userAgent,
|
"userAgent": userAgent,
|
||||||
|
"applicationNameForUserAgent": applicationNameForUserAgent,
|
||||||
"javaScriptEnabled": javaScriptEnabled,
|
"javaScriptEnabled": javaScriptEnabled,
|
||||||
"debuggingEnabled": debuggingEnabled,
|
"debuggingEnabled": debuggingEnabled,
|
||||||
"javaScriptCanOpenWindowsAutomatically": javaScriptCanOpenWindowsAutomatically,
|
"javaScriptCanOpenWindowsAutomatically": javaScriptCanOpenWindowsAutomatically,
|
||||||
|
@ -87,7 +95,12 @@ class InAppWebViewOptions implements WebViewOptions, BrowserOptions, AndroidOpti
|
||||||
"horizontalScrollBarEnabled": horizontalScrollBarEnabled,
|
"horizontalScrollBarEnabled": horizontalScrollBarEnabled,
|
||||||
"resourceCustomSchemes": resourceCustomSchemes,
|
"resourceCustomSchemes": resourceCustomSchemes,
|
||||||
"contentBlockers": contentBlockersMapList,
|
"contentBlockers": contentBlockersMapList,
|
||||||
"preferredContentMode": preferredContentMode?.toValue()
|
"preferredContentMode": preferredContentMode?.toValue(),
|
||||||
|
"useShouldInterceptAjaxRequest": useShouldInterceptAjaxRequest,
|
||||||
|
"useShouldInterceptFetchRequest": useShouldInterceptFetchRequest,
|
||||||
|
"incognito": incognito,
|
||||||
|
"cacheEnabled": cacheEnabled,
|
||||||
|
"transparentBackground": transparentBackground
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +123,9 @@ class InAppWebViewOptions implements WebViewOptions, BrowserOptions, AndroidOpti
|
||||||
options.useOnTargetBlank = map["useOnTargetBlank"];
|
options.useOnTargetBlank = map["useOnTargetBlank"];
|
||||||
options.clearCache = map["clearCache"];
|
options.clearCache = map["clearCache"];
|
||||||
options.userAgent = map["userAgent"];
|
options.userAgent = map["userAgent"];
|
||||||
|
options.applicationNameForUserAgent = map["applicationNameForUserAgent"];
|
||||||
options.javaScriptEnabled = map["javaScriptEnabled"];
|
options.javaScriptEnabled = map["javaScriptEnabled"];
|
||||||
|
options.debuggingEnabled = map["debuggingEnabled"];
|
||||||
options.javaScriptCanOpenWindowsAutomatically = map["javaScriptCanOpenWindowsAutomatically"];
|
options.javaScriptCanOpenWindowsAutomatically = map["javaScriptCanOpenWindowsAutomatically"];
|
||||||
options.mediaPlaybackRequiresUserGesture = map["mediaPlaybackRequiresUserGesture"];
|
options.mediaPlaybackRequiresUserGesture = map["mediaPlaybackRequiresUserGesture"];
|
||||||
options.textZoom = map["textZoom"];
|
options.textZoom = map["textZoom"];
|
||||||
|
@ -119,6 +134,11 @@ class InAppWebViewOptions implements WebViewOptions, BrowserOptions, AndroidOpti
|
||||||
options.resourceCustomSchemes = List<String>.from(map["resourceCustomSchemes"] ?? []);
|
options.resourceCustomSchemes = List<String>.from(map["resourceCustomSchemes"] ?? []);
|
||||||
options.contentBlockers = contentBlockers;
|
options.contentBlockers = contentBlockers;
|
||||||
options.preferredContentMode = InAppWebViewUserPreferredContentMode.fromValue(map["preferredContentMode"]);
|
options.preferredContentMode = InAppWebViewUserPreferredContentMode.fromValue(map["preferredContentMode"]);
|
||||||
|
options.useShouldInterceptAjaxRequest = map["useShouldInterceptAjaxRequest"];
|
||||||
|
options.useShouldInterceptFetchRequest = map["useShouldInterceptFetchRequest"];
|
||||||
|
options.incognito = map["incognito"];
|
||||||
|
options.cacheEnabled = map["cacheEnabled"];
|
||||||
|
options.transparentBackground = map["transparentBackground"];
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,13 +152,11 @@ class AndroidInAppWebViewOptions implements WebViewOptions, BrowserOptions, Andr
|
||||||
bool domStorageEnabled;
|
bool domStorageEnabled;
|
||||||
bool useWideViewPort;
|
bool useWideViewPort;
|
||||||
bool safeBrowsingEnabled;
|
bool safeBrowsingEnabled;
|
||||||
bool transparentBackground;
|
|
||||||
AndroidInAppWebViewMixedContentMode mixedContentMode;
|
AndroidInAppWebViewMixedContentMode mixedContentMode;
|
||||||
bool allowContentAccess;
|
bool allowContentAccess;
|
||||||
bool allowFileAccess;
|
bool allowFileAccess;
|
||||||
bool allowFileAccessFromFileURLs;
|
bool allowFileAccessFromFileURLs;
|
||||||
bool allowUniversalAccessFromFileURLs;
|
bool allowUniversalAccessFromFileURLs;
|
||||||
bool appCacheEnabled;
|
|
||||||
String appCachePath;
|
String appCachePath;
|
||||||
bool blockNetworkImage;
|
bool blockNetworkImage;
|
||||||
bool blockNetworkLoads;
|
bool blockNetworkLoads;
|
||||||
|
@ -162,16 +180,19 @@ class AndroidInAppWebViewOptions implements WebViewOptions, BrowserOptions, Andr
|
||||||
String sansSerifFontFamily;
|
String sansSerifFontFamily;
|
||||||
String serifFontFamily;
|
String serifFontFamily;
|
||||||
String standardFontFamily;
|
String standardFontFamily;
|
||||||
|
bool saveFormData;
|
||||||
|
bool thirdPartyCookiesEnabled;
|
||||||
|
bool hardwareAcceleration;
|
||||||
|
|
||||||
AndroidInAppWebViewOptions({this.clearSessionCache = false, this.builtInZoomControls = false, this.displayZoomControls = false, this.supportZoom = true, this.databaseEnabled = false,
|
AndroidInAppWebViewOptions({this.clearSessionCache = false, this.builtInZoomControls = false, this.displayZoomControls = false, this.supportZoom = true, this.databaseEnabled = false,
|
||||||
this.domStorageEnabled = false, this.useWideViewPort = true, this.safeBrowsingEnabled = true, this.transparentBackground = false, this.mixedContentMode,
|
this.domStorageEnabled = false, this.useWideViewPort = true, this.safeBrowsingEnabled = true, this.mixedContentMode,
|
||||||
this.allowContentAccess = true, this.allowFileAccess = true, this.allowFileAccessFromFileURLs = true, this.allowUniversalAccessFromFileURLs = true,
|
this.allowContentAccess = true, this.allowFileAccess = true, this.allowFileAccessFromFileURLs = true, this.allowUniversalAccessFromFileURLs = true,
|
||||||
this.appCacheEnabled = true, this.appCachePath, this.blockNetworkImage = false, this.blockNetworkLoads = false, this.cacheMode = AndroidInAppWebViewCacheMode.LOAD_DEFAULT,
|
this.appCachePath, this.blockNetworkImage = false, this.blockNetworkLoads = false, this.cacheMode = AndroidInAppWebViewCacheMode.LOAD_DEFAULT,
|
||||||
this.cursiveFontFamily = "cursive", this.defaultFixedFontSize = 16, this.defaultFontSize = 16, this.defaultTextEncodingName = "UTF-8",
|
this.cursiveFontFamily = "cursive", this.defaultFixedFontSize = 16, this.defaultFontSize = 16, this.defaultTextEncodingName = "UTF-8",
|
||||||
this.disabledActionModeMenuItems, this.fantasyFontFamily = "fantasy", this.fixedFontFamily = "monospace", this.forceDark = AndroidInAppWebViewForceDark.FORCE_DARK_OFF,
|
this.disabledActionModeMenuItems, this.fantasyFontFamily = "fantasy", this.fixedFontFamily = "monospace", this.forceDark = AndroidInAppWebViewForceDark.FORCE_DARK_OFF,
|
||||||
this.geolocationEnabled = true, this.layoutAlgorithm, this.loadWithOverviewMode = true, this.loadsImagesAutomatically = true,
|
this.geolocationEnabled = true, this.layoutAlgorithm, this.loadWithOverviewMode = true, this.loadsImagesAutomatically = true,
|
||||||
this.minimumLogicalFontSize = 8, this.initialScale, this.needInitialFocus = true, this.offscreenPreRaster = false, this.sansSerifFontFamily = "sans-serif", this.serifFontFamily = "sans-serif",
|
this.minimumLogicalFontSize = 8, this.needInitialFocus = true, this.offscreenPreRaster = false, this.sansSerifFontFamily = "sans-serif", this.serifFontFamily = "sans-serif",
|
||||||
this.standardFontFamily = "sans-serif"
|
this.standardFontFamily = "sans-serif", this.saveFormData = true, this.thirdPartyCookiesEnabled = true, this.hardwareAcceleration = true, this.initialScale
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -185,13 +206,11 @@ class AndroidInAppWebViewOptions implements WebViewOptions, BrowserOptions, Andr
|
||||||
"domStorageEnabled": domStorageEnabled,
|
"domStorageEnabled": domStorageEnabled,
|
||||||
"useWideViewPort": useWideViewPort,
|
"useWideViewPort": useWideViewPort,
|
||||||
"safeBrowsingEnabled": safeBrowsingEnabled,
|
"safeBrowsingEnabled": safeBrowsingEnabled,
|
||||||
"transparentBackground": transparentBackground,
|
|
||||||
"mixedContentMode": mixedContentMode?.toValue(),
|
"mixedContentMode": mixedContentMode?.toValue(),
|
||||||
"allowContentAccess": allowContentAccess,
|
"allowContentAccess": allowContentAccess,
|
||||||
"allowFileAccess": allowFileAccess,
|
"allowFileAccess": allowFileAccess,
|
||||||
"allowFileAccessFromFileURLs": allowFileAccessFromFileURLs,
|
"allowFileAccessFromFileURLs": allowFileAccessFromFileURLs,
|
||||||
"allowUniversalAccessFromFileURLs": allowUniversalAccessFromFileURLs,
|
"allowUniversalAccessFromFileURLs": allowUniversalAccessFromFileURLs,
|
||||||
"appCacheEnabled": appCacheEnabled,
|
|
||||||
"appCachePath": appCachePath,
|
"appCachePath": appCachePath,
|
||||||
"blockNetworkImage": blockNetworkImage,
|
"blockNetworkImage": blockNetworkImage,
|
||||||
"blockNetworkLoads": blockNetworkLoads,
|
"blockNetworkLoads": blockNetworkLoads,
|
||||||
|
@ -214,7 +233,10 @@ class AndroidInAppWebViewOptions implements WebViewOptions, BrowserOptions, Andr
|
||||||
"offscreenPreRaster": offscreenPreRaster,
|
"offscreenPreRaster": offscreenPreRaster,
|
||||||
"sansSerifFontFamily": sansSerifFontFamily,
|
"sansSerifFontFamily": sansSerifFontFamily,
|
||||||
"serifFontFamily": serifFontFamily,
|
"serifFontFamily": serifFontFamily,
|
||||||
"standardFontFamily": standardFontFamily
|
"standardFontFamily": standardFontFamily,
|
||||||
|
"saveFormData": saveFormData,
|
||||||
|
"thirdPartyCookiesEnabled": thirdPartyCookiesEnabled,
|
||||||
|
"hardwareAcceleration": hardwareAcceleration
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,13 +251,11 @@ class AndroidInAppWebViewOptions implements WebViewOptions, BrowserOptions, Andr
|
||||||
options.domStorageEnabled = map["domStorageEnabled"];
|
options.domStorageEnabled = map["domStorageEnabled"];
|
||||||
options.useWideViewPort = map["useWideViewPort"];
|
options.useWideViewPort = map["useWideViewPort"];
|
||||||
options.safeBrowsingEnabled = map["safeBrowsingEnabled"];
|
options.safeBrowsingEnabled = map["safeBrowsingEnabled"];
|
||||||
options.transparentBackground = map["transparentBackground"];
|
|
||||||
options.mixedContentMode = AndroidInAppWebViewMixedContentMode.fromValue(map["mixedContentMode"]);
|
options.mixedContentMode = AndroidInAppWebViewMixedContentMode.fromValue(map["mixedContentMode"]);
|
||||||
options.allowContentAccess = map["allowContentAccess"];
|
options.allowContentAccess = map["allowContentAccess"];
|
||||||
options.allowFileAccess = map["allowFileAccess"];
|
options.allowFileAccess = map["allowFileAccess"];
|
||||||
options.allowFileAccessFromFileURLs = map["allowFileAccessFromFileURLs"];
|
options.allowFileAccessFromFileURLs = map["allowFileAccessFromFileURLs"];
|
||||||
options.allowUniversalAccessFromFileURLs = map["allowUniversalAccessFromFileURLs"];
|
options.allowUniversalAccessFromFileURLs = map["allowUniversalAccessFromFileURLs"];
|
||||||
options.appCacheEnabled = map["appCacheEnabled"];
|
|
||||||
options.appCachePath = map["appCachePath"];
|
options.appCachePath = map["appCachePath"];
|
||||||
options.blockNetworkImage = map["blockNetworkImage"];
|
options.blockNetworkImage = map["blockNetworkImage"];
|
||||||
options.blockNetworkLoads = map["blockNetworkLoads"];
|
options.blockNetworkLoads = map["blockNetworkLoads"];
|
||||||
|
@ -259,6 +279,9 @@ class AndroidInAppWebViewOptions implements WebViewOptions, BrowserOptions, Andr
|
||||||
options.sansSerifFontFamily = map["sansSerifFontFamily"];
|
options.sansSerifFontFamily = map["sansSerifFontFamily"];
|
||||||
options.serifFontFamily = map["serifFontFamily"];
|
options.serifFontFamily = map["serifFontFamily"];
|
||||||
options.standardFontFamily = map["standardFontFamily"];
|
options.standardFontFamily = map["standardFontFamily"];
|
||||||
|
options.saveFormData = map["saveFormData"];
|
||||||
|
options.thirdPartyCookiesEnabled = map["thirdPartyCookiesEnabled"];
|
||||||
|
options.hardwareAcceleration = map["hardwareAcceleration"];
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,16 +296,15 @@ class IosInAppWebViewOptions implements WebViewOptions, BrowserOptions, IosOptio
|
||||||
bool ignoresViewportScaleLimits;
|
bool ignoresViewportScaleLimits;
|
||||||
bool allowsInlineMediaPlayback;
|
bool allowsInlineMediaPlayback;
|
||||||
bool allowsPictureInPictureMediaPlayback;
|
bool allowsPictureInPictureMediaPlayback;
|
||||||
bool transparentBackground;
|
|
||||||
String applicationNameForUserAgent;
|
|
||||||
bool isFraudulentWebsiteWarningEnabled;
|
bool isFraudulentWebsiteWarningEnabled;
|
||||||
IosInAppWebViewSelectionGranularity selectionGranularity;
|
IosInAppWebViewSelectionGranularity selectionGranularity;
|
||||||
List<IosInAppWebViewDataDetectorTypes> dataDetectorTypes;
|
List<IosInAppWebViewDataDetectorTypes> dataDetectorTypes;
|
||||||
|
bool sharedCookiesEnabled;
|
||||||
|
|
||||||
IosInAppWebViewOptions({this.disallowOverScroll = false, this.enableViewportScale = false, this.suppressesIncrementalRendering = false, this.allowsAirPlayForMediaPlayback = true,
|
IosInAppWebViewOptions({this.disallowOverScroll = false, this.enableViewportScale = false, this.suppressesIncrementalRendering = false, this.allowsAirPlayForMediaPlayback = true,
|
||||||
this.allowsBackForwardNavigationGestures = true, this.allowsLinkPreview = true, this.ignoresViewportScaleLimits = false, this.allowsInlineMediaPlayback = false,
|
this.allowsBackForwardNavigationGestures = true, this.allowsLinkPreview = true, this.ignoresViewportScaleLimits = false, this.allowsInlineMediaPlayback = false,
|
||||||
this.allowsPictureInPictureMediaPlayback = true, this.transparentBackground = false, this.applicationNameForUserAgent = "", this.isFraudulentWebsiteWarningEnabled = true,
|
this.allowsPictureInPictureMediaPlayback = true, this.isFraudulentWebsiteWarningEnabled = true,
|
||||||
this.selectionGranularity = IosInAppWebViewSelectionGranularity.DYNAMIC, this.dataDetectorTypes = const [IosInAppWebViewDataDetectorTypes.NONE]
|
this.selectionGranularity = IosInAppWebViewSelectionGranularity.DYNAMIC, this.dataDetectorTypes = const [IosInAppWebViewDataDetectorTypes.NONE], this.sharedCookiesEnabled = false
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -302,11 +324,10 @@ class IosInAppWebViewOptions implements WebViewOptions, BrowserOptions, IosOptio
|
||||||
"ignoresViewportScaleLimits": ignoresViewportScaleLimits,
|
"ignoresViewportScaleLimits": ignoresViewportScaleLimits,
|
||||||
"allowsInlineMediaPlayback": allowsInlineMediaPlayback,
|
"allowsInlineMediaPlayback": allowsInlineMediaPlayback,
|
||||||
"allowsPictureInPictureMediaPlayback": allowsPictureInPictureMediaPlayback,
|
"allowsPictureInPictureMediaPlayback": allowsPictureInPictureMediaPlayback,
|
||||||
"transparentBackground": transparentBackground,
|
|
||||||
"applicationNameForUserAgent": applicationNameForUserAgent,
|
|
||||||
"isFraudulentWebsiteWarningEnabled": isFraudulentWebsiteWarningEnabled,
|
"isFraudulentWebsiteWarningEnabled": isFraudulentWebsiteWarningEnabled,
|
||||||
"selectionGranularity": selectionGranularity.toValue(),
|
"selectionGranularity": selectionGranularity.toValue(),
|
||||||
"dataDetectorTypes": dataDetectorTypesList
|
"dataDetectorTypes": dataDetectorTypesList,
|
||||||
|
"sharedCookiesEnabled": sharedCookiesEnabled
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,11 +349,10 @@ class IosInAppWebViewOptions implements WebViewOptions, BrowserOptions, IosOptio
|
||||||
options.ignoresViewportScaleLimits = map["ignoresViewportScaleLimits"];
|
options.ignoresViewportScaleLimits = map["ignoresViewportScaleLimits"];
|
||||||
options.allowsInlineMediaPlayback = map["allowsInlineMediaPlayback"];
|
options.allowsInlineMediaPlayback = map["allowsInlineMediaPlayback"];
|
||||||
options.allowsPictureInPictureMediaPlayback = map["allowsPictureInPictureMediaPlayback"];
|
options.allowsPictureInPictureMediaPlayback = map["allowsPictureInPictureMediaPlayback"];
|
||||||
options.transparentBackground = map["transparentBackground"];
|
|
||||||
options.applicationNameForUserAgent = map["applicationNameForUserAgent"];
|
|
||||||
options.isFraudulentWebsiteWarningEnabled = map["isFraudulentWebsiteWarningEnabled"];
|
options.isFraudulentWebsiteWarningEnabled = map["isFraudulentWebsiteWarningEnabled"];
|
||||||
options.selectionGranularity = IosInAppWebViewSelectionGranularity.fromValue(map["selectionGranularity"]);
|
options.selectionGranularity = IosInAppWebViewSelectionGranularity.fromValue(map["selectionGranularity"]);
|
||||||
options.dataDetectorTypes = dataDetectorTypes;
|
options.dataDetectorTypes = dataDetectorTypes;
|
||||||
|
options.sharedCookiesEnabled = map["sharedCookiesEnabled"];
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 83 KiB |
|
@ -1,12 +1,14 @@
|
||||||
// Example of the server https is taken from here: https://engineering.circle.com/https-authorized-certs-with-node-js-315e548354a2
|
// Example of the server https is taken from here: https://engineering.circle.com/https-authorized-certs-with-node-js-315e548354a2
|
||||||
// Conversion of client1-crt.pem to certificate.pfx: https://stackoverflow.com/a/38408666/4637638
|
// Conversion of client1-crt.pem to certificate.pfx: https://stackoverflow.com/a/38408666/4637638
|
||||||
const express = require('express')
|
const express = require('express')
|
||||||
var https = require('https')
|
const https = require('https')
|
||||||
|
const cors = require('cors')
|
||||||
const auth = require('basic-auth')
|
const auth = require('basic-auth')
|
||||||
const app = express()
|
const app = express()
|
||||||
const appHttps = express()
|
const appHttps = express()
|
||||||
const appAuthBasic = express()
|
const appAuthBasic = express()
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
key: fs.readFileSync('server-key.pem'),
|
key: fs.readFileSync('server-key.pem'),
|
||||||
|
@ -17,6 +19,7 @@ var options = {
|
||||||
};
|
};
|
||||||
|
|
||||||
appHttps.get('/', (req, res) => {
|
appHttps.get('/', (req, res) => {
|
||||||
|
console.log(JSON.stringify(req.headers))
|
||||||
const cert = req.connection.getPeerCertificate()
|
const cert = req.connection.getPeerCertificate()
|
||||||
|
|
||||||
// The `req.client.authorized` flag will be true if the certificate is valid and was issued by a CA we white-listed
|
// The `req.client.authorized` flag will be true if the certificate is valid and was issued by a CA we white-listed
|
||||||
|
@ -48,7 +51,8 @@ appHttps.get('/', (req, res) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
appHttps.get('/fakeResource', (req, res) => {
|
appHttps.get('/fakeResource', (req, res) => {
|
||||||
res.set("Content-Type", "text/javascript")
|
console.log(JSON.stringify(req.headers))
|
||||||
|
res.set("Content-Type", "text/javascript")
|
||||||
res.send(`alert("HI");`)
|
res.send(`alert("HI");`)
|
||||||
res.end()
|
res.end()
|
||||||
})
|
})
|
||||||
|
@ -70,6 +74,7 @@ appAuthBasic.use((req, res, next) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
appAuthBasic.get("/", (req, res) => {
|
appAuthBasic.get("/", (req, res) => {
|
||||||
|
console.log(JSON.stringify(req.headers))
|
||||||
res.send(`
|
res.send(`
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
@ -87,10 +92,13 @@ appAuthBasic.listen(8081)
|
||||||
// Parse URL-encoded bodies (as sent by HTML forms)
|
// Parse URL-encoded bodies (as sent by HTML forms)
|
||||||
app.use(express.urlencoded());
|
app.use(express.urlencoded());
|
||||||
|
|
||||||
|
app.use(cors());
|
||||||
|
|
||||||
// Parse JSON bodies (as sent by API clients)
|
// Parse JSON bodies (as sent by API clients)
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
|
|
||||||
app.get("/", (req, res) => {
|
app.get("/", (req, res) => {
|
||||||
|
console.log(JSON.stringify(req.headers))
|
||||||
res.send(`
|
res.send(`
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
@ -104,6 +112,7 @@ app.get("/", (req, res) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
app.post("/test-post", (req, res) => {
|
app.post("/test-post", (req, res) => {
|
||||||
|
console.log(JSON.stringify(req.headers))
|
||||||
res.send(`
|
res.send(`
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
@ -115,4 +124,27 @@ app.post("/test-post", (req, res) => {
|
||||||
`);
|
`);
|
||||||
res.end()
|
res.end()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
app.post("/test-ajax-post", (req, res) => {
|
||||||
|
console.log(JSON.stringify(req.headers))
|
||||||
|
res.set("Content-Type", "application/json")
|
||||||
|
res.send(JSON.stringify({
|
||||||
|
"name": req.body.name,
|
||||||
|
"key2": "value2"
|
||||||
|
}))
|
||||||
|
res.end()
|
||||||
|
})
|
||||||
|
|
||||||
|
app.get("/test-download-file", (req, res) => {
|
||||||
|
console.log(JSON.stringify(req.headers))
|
||||||
|
const filePath = path.join(__dirname, 'assets', 'flutter_logo.png');
|
||||||
|
const stat = fs.statSync(filePath);
|
||||||
|
const file = fs.readFileSync(filePath, 'binary');
|
||||||
|
res.setHeader('Content-Length', stat.size);
|
||||||
|
res.setHeader('Content-Type', 'image/png');
|
||||||
|
res.setHeader('Content-Disposition', 'attachment; filename=flutter_logo.png');
|
||||||
|
res.write(file, 'binary');
|
||||||
|
res.end();
|
||||||
|
})
|
||||||
|
|
||||||
app.listen(8082)
|
app.listen(8082)
|
|
@ -71,6 +71,15 @@
|
||||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||||
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
|
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
|
||||||
},
|
},
|
||||||
|
"cors": {
|
||||||
|
"version": "2.8.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
||||||
|
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
||||||
|
"requires": {
|
||||||
|
"object-assign": "^4",
|
||||||
|
"vary": "^1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"debug": {
|
"debug": {
|
||||||
"version": "2.6.9",
|
"version": "2.6.9",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||||
|
@ -248,6 +257,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
|
||||||
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
|
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
|
||||||
},
|
},
|
||||||
|
"object-assign": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
|
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
|
||||||
|
},
|
||||||
"on-finished": {
|
"on-finished": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"basic-auth": "latest",
|
"basic-auth": "latest",
|
||||||
|
"cors": "^2.8.5",
|
||||||
"express": "latest",
|
"express": "latest",
|
||||||
"https": "latest"
|
"https": "latest"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue