From 74550d11862933dfa97f0f6499db2b97270788ad Mon Sep 17 00:00:00 2001 From: Lorenzo Pichilli Date: Mon, 1 Mar 2021 03:21:07 +0100 Subject: [PATCH] Removed all the dependencies: uuid, device_info, intl, and mime --- .idea/libraries/Flutter_Plugins.xml | 1 - CHANGELOG.md | 1 + .../InAppWebViewFlutterPlugin.java | 6 + .../flutter_inappwebview/MyCookieManager.java | 2 +- .../flutter_inappwebview/PlatformUtil.java | 67 ++ .../ActionBroadcastReceiver.java | 6 +- .../ChromeCustomTabsActivity.java | 8 +- .../ChromeSafariBrowserManager.java | 8 +- .../in_app_browser/InAppBrowserActivity.java | 6 +- .../in_app_browser/InAppBrowserManager.java | 24 +- .../HeadlessInAppWebViewManager.java | 20 +- example/.flutter-plugins-dependencies | 2 +- example/ios/Runner.xcodeproj/project.pbxproj | 2 - .../InAppBrowser/InAppBrowserManager.swift | 24 +- .../InAppBrowserWebViewController.swift | 4 +- .../FlutterWebViewController.swift | 2 +- .../HeadlessInAppWebViewManager.swift | 18 +- ios/Classes/PlatformUtil.swift | 63 + .../ChromeSafariBrowserManager.swift | 8 +- .../SafariViewController.swift | 14 +- ios/Classes/SwiftFlutterPlugin.swift | 2 + lib/src/_uuid_generator.dart | 4 - .../chrome_safari_browser.dart | 10 +- lib/src/cookie_manager.dart | 38 +- lib/src/in_app_browser/in_app_browser.dart | 18 +- lib/src/in_app_localhost_server.dart | 6 +- .../headless_in_app_webview.dart | 12 +- lib/src/mime_type_resolver.dart | 1022 +++++++++++++++++ lib/src/platform_util.dart | 38 + lib/src/util.dart | 35 + pubspec.yaml | 4 - 31 files changed, 1345 insertions(+), 130 deletions(-) create mode 100755 android/src/main/java/com/pichillilorenzo/flutter_inappwebview/PlatformUtil.java create mode 100644 ios/Classes/PlatformUtil.swift delete mode 100644 lib/src/_uuid_generator.dart create mode 100644 lib/src/mime_type_resolver.dart create mode 100644 lib/src/platform_util.dart diff --git a/.idea/libraries/Flutter_Plugins.xml b/.idea/libraries/Flutter_Plugins.xml index c241dc8c..65bb3679 100755 --- a/.idea/libraries/Flutter_Plugins.xml +++ b/.idea/libraries/Flutter_Plugins.xml @@ -1,7 +1,6 @@ - diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ee3a18e..f6cf4a65 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## 5.0.5-nullsafety.1 - Updated Android `WebChromeClient.getDefaultVideoPoster` +- Removed all the dependencies: `uuid`, `device_info`, `intl`, and `mime` ## 5.0.4-nullsafety.1 diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewFlutterPlugin.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewFlutterPlugin.java index 645d5f19..cf44bf6e 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewFlutterPlugin.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewFlutterPlugin.java @@ -24,6 +24,7 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware { protected static final String LOG_TAG = "InAppWebViewFlutterPL"; + public static PlatformUtil platformUtil; public static InAppBrowserManager inAppBrowserManager; public static HeadlessInAppWebViewManager headlessInAppWebViewManager; public static ChromeSafariBrowserManager chromeSafariBrowserManager; @@ -70,6 +71,7 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware { platformViewRegistry.registerViewFactory( "com.pichillilorenzo/flutter_inappwebview", new FlutterWebViewFactory(messenger, flutterView)); + platformUtil = new PlatformUtil(messenger); inAppWebViewStatic = new InAppWebViewStatic(messenger); myCookieManager = new MyCookieManager(messenger); myWebStorage = new MyWebStorage(messenger); @@ -84,6 +86,10 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware { @Override public void onDetachedFromEngine(FlutterPluginBinding binding) { + if (platformUtil != null) { + platformUtil.dispose(); + platformUtil = null; + } if (inAppBrowserManager != null) { inAppBrowserManager.dispose(); inAppBrowserManager = null; diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyCookieManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyCookieManager.java index a48ab55f..82dff731 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyCookieManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyCookieManager.java @@ -306,7 +306,7 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler { } public static String getCookieExpirationDate(Long timestamp) { - final SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy hh:mm:ss z", Locale.US); + final SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy hh:mm:ss z", Locale.US); sdf.setTimeZone(TimeZone.getTimeZone("GMT")); return sdf.format(new Date(timestamp)); } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/PlatformUtil.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/PlatformUtil.java new file mode 100755 index 00000000..7f33775c --- /dev/null +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/PlatformUtil.java @@ -0,0 +1,67 @@ +package com.pichillilorenzo.flutter_inappwebview; + +import android.os.Build; + +import androidx.annotation.Nullable; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +import io.flutter.plugin.common.BinaryMessenger; +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; + +public class PlatformUtil implements MethodChannel.MethodCallHandler { + public MethodChannel channel; + + protected static final String LOG_TAG = "PlatformUtil"; + + public PlatformUtil(BinaryMessenger messenger) { + channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappwebview_platformutil"); + channel.setMethodCallHandler(this); + } + + @Override + public void onMethodCall(MethodCall call, final MethodChannel.Result result) { + switch (call.method) { + case "getSystemVersion": + result.success(String.valueOf(Build.VERSION.SDK_INT)); + break; + case "formatDate": + long date = (long) call.argument("date"); + String format = (String) call.argument("format"); + Locale locale = PlatformUtil.getLocaleFromString((String) call.argument("locale")); + String timezone = (String) call.argument("timezone"); + if (timezone == null) { + timezone = "UTC"; + } + result.success(PlatformUtil.formatDate(date, format, locale, TimeZone.getTimeZone(timezone))); + break; + default: + result.notImplemented(); + } + } + + public static Locale getLocaleFromString(@Nullable String locale) { + if (locale == null) { + return Locale.US; + } + String[] localeSplitted = locale.split("_"); + String language = localeSplitted[0]; + String country = localeSplitted.length > 1 ? localeSplitted[1] : ""; + String variant = localeSplitted.length > 2 ? localeSplitted[2] : ""; + return new Locale(language, country, variant); + } + + public static String formatDate(long date, String format, Locale locale, TimeZone timezone) { + final SimpleDateFormat sdf = new SimpleDateFormat(format, locale); + sdf.setTimeZone(timezone); + return sdf.format(new Date(date)); + } + + public void dispose() { + channel.setMethodCallHandler(null); + } +} diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ActionBroadcastReceiver.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ActionBroadcastReceiver.java index 04557756..fd8ce47a 100644 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ActionBroadcastReceiver.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ActionBroadcastReceiver.java @@ -15,7 +15,7 @@ import io.flutter.plugin.common.MethodChannel; public class ActionBroadcastReceiver extends BroadcastReceiver { protected static final String LOG_TAG = "ActionBroadcastReceiver"; public static final String KEY_ACTION_ID = "com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs.ACTION_ID"; - public static final String KEY_ACTION_UUID = "com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs.ACTION_UUID"; + public static final String KEY_ACTION_VIEW_ID = "com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs.ACTION_VIEW_ID"; public static final String KEY_URL_TITLE = "android.intent.extra.SUBJECT"; @Override @@ -23,11 +23,11 @@ public class ActionBroadcastReceiver extends BroadcastReceiver { String url = intent.getDataString(); if (url != null) { Bundle b = intent.getExtras(); - String uuid = b.getString(KEY_ACTION_UUID); + String viewId = b.getString(KEY_ACTION_VIEW_ID); int id = b.getInt(KEY_ACTION_ID); String title = b.getString(KEY_URL_TITLE); - MethodChannel channel = new MethodChannel(Shared.messenger, "com.pichillilorenzo/flutter_chromesafaribrowser_" + uuid); + MethodChannel channel = new MethodChannel(Shared.messenger, "com.pichillilorenzo/flutter_chromesafaribrowser_" + viewId); Map obj = new HashMap<>(); obj.put("url", url); obj.put("title", title); diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeCustomTabsActivity.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeCustomTabsActivity.java index 0de7ce9b..aaae3465 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeCustomTabsActivity.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeCustomTabsActivity.java @@ -26,7 +26,7 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel. protected static final String LOG_TAG = "CustomTabsActivity"; public MethodChannel channel; - public String uuid; + public String id; public CustomTabsIntent.Builder builder; public ChromeCustomTabsOptions options; public CustomTabActivityHelper customTabActivityHelper; @@ -43,9 +43,9 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel. Bundle b = getIntent().getExtras(); assert b != null; - uuid = b.getString("uuid"); + id = b.getString("id"); - channel = new MethodChannel(Shared.messenger, "com.pichillilorenzo/flutter_chromesafaribrowser_" + uuid); + channel = new MethodChannel(Shared.messenger, "com.pichillilorenzo/flutter_chromesafaribrowser_" + id); channel.setMethodCallHandler(this); final String url = b.getString("url"); @@ -201,7 +201,7 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel. Bundle extras = new Bundle(); extras.putInt(ActionBroadcastReceiver.KEY_ACTION_ID, actionSourceId); - extras.putString(ActionBroadcastReceiver.KEY_ACTION_UUID, uuid); + extras.putString(ActionBroadcastReceiver.KEY_ACTION_VIEW_ID, id); actionIntent.putExtras(extras); return PendingIntent.getBroadcast( diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeSafariBrowserManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeSafariBrowserManager.java index da2b95ed..b03a3fe7 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeSafariBrowserManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeSafariBrowserManager.java @@ -28,7 +28,7 @@ public class ChromeSafariBrowserManager implements MethodChannel.MethodCallHandl @Override public void onMethodCall(final MethodCall call, final MethodChannel.Result result) { final Activity activity = Shared.activity; - final String uuid = (String) call.argument("uuid"); + final String id = (String) call.argument("id"); switch (call.method) { case "open": @@ -36,7 +36,7 @@ public class ChromeSafariBrowserManager implements MethodChannel.MethodCallHandl String url = (String) call.argument("url"); HashMap options = (HashMap) call.argument("options"); List> menuItemList = (List>) call.argument("menuItemList"); - open(activity, uuid, url, options, menuItemList, result); + open(activity, id, url, options, menuItemList, result); } break; case "isAvailable": @@ -47,7 +47,7 @@ public class ChromeSafariBrowserManager implements MethodChannel.MethodCallHandl } } - public void open(Activity activity, String uuid, String url, HashMap options, + public void open(Activity activity, String id, String url, HashMap options, List> menuItemList, MethodChannel.Result result) { Intent intent = null; @@ -55,7 +55,7 @@ public class ChromeSafariBrowserManager implements MethodChannel.MethodCallHandl extras.putString("fromActivity", activity.getClass().getName()); extras.putString("url", url); extras.putBoolean("isData", false); - extras.putString("uuid", uuid); + extras.putString("id", id); extras.putSerializable("options", options); extras.putSerializable("menuItemList", (Serializable) menuItemList); diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_browser/InAppBrowserActivity.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_browser/InAppBrowserActivity.java index c8cac931..69b36f3a 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_browser/InAppBrowserActivity.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_browser/InAppBrowserActivity.java @@ -46,7 +46,7 @@ public class InAppBrowserActivity extends AppCompatActivity implements InAppBrow static final String LOG_TAG = "InAppBrowserActivity"; public MethodChannel channel; public Integer windowId; - public String uuid; + public String id; public InAppWebView webView; public ActionBar actionBar; public Menu menu; @@ -67,10 +67,10 @@ public class InAppBrowserActivity extends AppCompatActivity implements InAppBrow } Bundle b = getIntent().getExtras(); - uuid = b.getString("uuid"); + id = b.getString("id"); windowId = b.getInt("windowId"); - channel = new MethodChannel(Shared.messenger, "com.pichillilorenzo/flutter_inappbrowser_" + uuid); + channel = new MethodChannel(Shared.messenger, "com.pichillilorenzo/flutter_inappbrowser_" + id); setContentView(R.layout.activity_web_view); diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_browser/InAppBrowserManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_browser/InAppBrowserManager.java index 5b427bf1..b5c3a7f2 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_browser/InAppBrowserManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_browser/InAppBrowserManager.java @@ -64,31 +64,31 @@ public class InAppBrowserManager implements MethodChannel.MethodCallHandler { switch (call.method) { case "openUrlRequest": { - String uuid = (String) call.argument("uuid"); + String id = (String) call.argument("id"); Map urlRequest = (Map) call.argument("urlRequest"); Map options = (Map) call.argument("options"); Map contextMenu = (Map) call.argument("contextMenu"); Integer windowId = (Integer) call.argument("windowId"); List> initialUserScripts = (List>) call.argument("initialUserScripts"); - openUrlRequest(activity, uuid, urlRequest, options, contextMenu, windowId, initialUserScripts); + openUrlRequest(activity, id, urlRequest, options, contextMenu, windowId, initialUserScripts); } result.success(true); break; case "openFile": { - String uuid = (String) call.argument("uuid"); + String id = (String) call.argument("id"); String assetFilePath = (String) call.argument("assetFilePath"); Map options = (Map) call.argument("options"); Map contextMenu = (Map) call.argument("contextMenu"); Integer windowId = (Integer) call.argument("windowId"); List> initialUserScripts = (List>) call.argument("initialUserScripts"); - openFile(activity, uuid, assetFilePath, options, contextMenu, windowId, initialUserScripts); + openFile(activity, id, assetFilePath, options, contextMenu, windowId, initialUserScripts); } result.success(true); break; case "openData": { - String uuid = (String) call.argument("uuid"); + String id = (String) call.argument("id"); Map options = (Map) call.argument("options"); String data = (String) call.argument("data"); String mimeType = (String) call.argument("mimeType"); @@ -98,7 +98,7 @@ public class InAppBrowserManager implements MethodChannel.MethodCallHandler { Map contextMenu = (Map) call.argument("contextMenu"); Integer windowId = (Integer) call.argument("windowId"); List> initialUserScripts = (List>) call.argument("initialUserScripts"); - openData(activity, uuid, options, data, mimeType, encoding, baseUrl, historyUrl, contextMenu, windowId, initialUserScripts); + openData(activity, id, options, data, mimeType, encoding, baseUrl, historyUrl, contextMenu, windowId, initialUserScripts); } result.success(true); break; @@ -189,12 +189,12 @@ public class InAppBrowserManager implements MethodChannel.MethodCallHandler { } } - public void openUrlRequest(Activity activity, String uuid, Map urlRequest, Map options, + public void openUrlRequest(Activity activity, String id, Map urlRequest, Map options, Map contextMenu, Integer windowId, List> initialUserScripts) { Bundle extras = new Bundle(); extras.putString("fromActivity", activity.getClass().getName()); extras.putSerializable("initialUrlRequest", (Serializable) urlRequest); - extras.putString("uuid", uuid); + extras.putString("id", id); extras.putSerializable("options", (Serializable) options); extras.putSerializable("contextMenu", (Serializable) contextMenu); extras.putInt("windowId", windowId != null ? windowId : -1); @@ -202,12 +202,12 @@ public class InAppBrowserManager implements MethodChannel.MethodCallHandler { startInAppBrowserActivity(activity, extras); } - public void openFile(Activity activity, String uuid, String assetFilePath, Map options, + public void openFile(Activity activity, String id, String assetFilePath, Map options, Map contextMenu, Integer windowId, List> initialUserScripts) { Bundle extras = new Bundle(); extras.putString("fromActivity", activity.getClass().getName()); extras.putString("initialFile", assetFilePath); - extras.putString("uuid", uuid); + extras.putString("id", id); extras.putSerializable("options", (Serializable) options); extras.putSerializable("contextMenu", (Serializable) contextMenu); extras.putInt("windowId", windowId != null ? windowId : -1); @@ -215,10 +215,10 @@ public class InAppBrowserManager implements MethodChannel.MethodCallHandler { startInAppBrowserActivity(activity, extras); } - public void openData(Activity activity, String uuid, Map options, String data, String mimeType, String encoding, + public void openData(Activity activity, String id, Map options, String data, String mimeType, String encoding, String baseUrl, String historyUrl, Map contextMenu, Integer windowId, List> initialUserScripts) { Bundle extras = new Bundle(); - extras.putString("uuid", uuid); + extras.putString("id", id); extras.putSerializable("options", (Serializable) options); extras.putString("initialData", data); extras.putString("initialMimeType", mimeType); diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/HeadlessInAppWebViewManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/HeadlessInAppWebViewManager.java index 856d522b..78514268 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/HeadlessInAppWebViewManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/HeadlessInAppWebViewManager.java @@ -50,18 +50,18 @@ public class HeadlessInAppWebViewManager implements MethodChannel.MethodCallHand @Override public void onMethodCall(final MethodCall call, final Result result) { final Activity activity = Shared.activity; - final String uuid = (String) call.argument("uuid"); + final String id = (String) call.argument("id"); switch (call.method) { case "createHeadlessWebView": { HashMap params = (HashMap) call.argument("params"); - createHeadlessWebView(activity, uuid, params); + createHeadlessWebView(activity, id, params); } result.success(true); break; case "disposeHeadlessWebView": - disposeHeadlessWebView(uuid); + disposeHeadlessWebView(id); result.success(true); break; default: @@ -70,15 +70,15 @@ public class HeadlessInAppWebViewManager implements MethodChannel.MethodCallHand } - public void createHeadlessWebView(Activity activity, String uuid, HashMap params) { - FlutterWebView flutterWebView = new FlutterWebView(Shared.messenger, activity, uuid, params, null); - flutterWebViews.put(uuid, flutterWebView); + public void createHeadlessWebView(Activity activity, String id, HashMap params) { + FlutterWebView flutterWebView = new FlutterWebView(Shared.messenger, activity, id, params, null); + flutterWebViews.put(id, flutterWebView); } - public void disposeHeadlessWebView(String uuid) { - if (flutterWebViews.containsKey(uuid)) { - flutterWebViews.get(uuid).dispose(); - flutterWebViews.remove(uuid); + public void disposeHeadlessWebView(String id) { + if (flutterWebViews.containsKey(id)) { + flutterWebViews.get(id).dispose(); + flutterWebViews.remove(id); } } diff --git a/example/.flutter-plugins-dependencies b/example/.flutter-plugins-dependencies index 9cd56693..6f8c6f03 100644 --- a/example/.flutter-plugins-dependencies +++ b/example/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"device_info","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.0-nullsafety.2/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":["device_info"]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.0-nullsafety/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.1.0+2/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.6/","dependencies":[]}],"android":[{"name":"device_info","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.0-nullsafety.2/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":["device_info"]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.0-nullsafety/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.1.0+2/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.6/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.5-nullsafety/","dependencies":[]},{"name":"url_launcher_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-0.1.0-nullsafety.2/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.2.0-nullsafety/","dependencies":[]},{"name":"url_launcher_linux","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_linux-0.1.0-nullsafety.3/","dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-0.1.0-nullsafety.3/","dependencies":[]},{"name":"url_launcher_windows","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_windows-0.1.0-nullsafety.2/","dependencies":[]}],"web":[]},"dependencyGraph":[{"name":"device_info","dependencies":[]},{"name":"flutter_downloader","dependencies":[]},{"name":"flutter_inappwebview","dependencies":["device_info"]},{"name":"integration_test","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux","path_provider_windows"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"permission_handler","dependencies":[]},{"name":"url_launcher","dependencies":["url_launcher_linux","url_launcher_macos","url_launcher_windows"]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2021-02-28 03:33:24.583173","version":"1.27.0-4.0.pre"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.0-nullsafety/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.1.0+2/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.6/","dependencies":[]}],"android":[{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.0-nullsafety/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.1.0+2/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.6/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.5-nullsafety/","dependencies":[]},{"name":"url_launcher_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-0.1.0-nullsafety.2/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.2.0-nullsafety/","dependencies":[]},{"name":"url_launcher_linux","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_linux-0.1.0-nullsafety.3/","dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-0.1.0-nullsafety.3/","dependencies":[]},{"name":"url_launcher_windows","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_windows-0.1.0-nullsafety.2/","dependencies":[]}],"web":[]},"dependencyGraph":[{"name":"flutter_downloader","dependencies":[]},{"name":"flutter_inappwebview","dependencies":[]},{"name":"integration_test","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux","path_provider_windows"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"permission_handler","dependencies":[]},{"name":"url_launcher","dependencies":["url_launcher_linux","url_launcher_macos","url_launcher_windows"]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2021-03-01 03:17:40.431874","version":"1.27.0-4.0.pre"} \ No newline at end of file diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 6a66e670..8a7c5b93 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -258,7 +258,6 @@ inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", "${BUILT_PRODUCTS_DIR}/OrderedSet/OrderedSet.framework", - "${BUILT_PRODUCTS_DIR}/device_info/device_info.framework", "${BUILT_PRODUCTS_DIR}/flutter_downloader/flutter_downloader.framework", "${BUILT_PRODUCTS_DIR}/flutter_inappwebview/flutter_inappwebview.framework", "${BUILT_PRODUCTS_DIR}/integration_test/integration_test.framework", @@ -268,7 +267,6 @@ name = "[CP] Embed Pods Frameworks"; outputPaths = ( "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OrderedSet.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/device_info.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_downloader.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_inappwebview.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/integration_test.framework", diff --git a/ios/Classes/InAppBrowser/InAppBrowserManager.swift b/ios/Classes/InAppBrowser/InAppBrowserManager.swift index bd30a429..b2989b3c 100755 --- a/ios/Classes/InAppBrowser/InAppBrowserManager.swift +++ b/ios/Classes/InAppBrowser/InAppBrowserManager.swift @@ -37,27 +37,27 @@ public class InAppBrowserManager: NSObject, FlutterPlugin { switch call.method { case "openUrlRequest": - let uuid = arguments!["uuid"] as! String + let id = arguments!["id"] as! String let urlRequest = arguments!["urlRequest"] as! [String:Any?] let options = arguments!["options"] as! [String: Any?] let contextMenu = arguments!["contextMenu"] as! [String: Any] let windowId = arguments!["windowId"] as? Int64 let initialUserScripts = arguments!["initialUserScripts"] as? [[String: Any]] - openUrlRequest(uuid: uuid, urlRequest: urlRequest, options: options, contextMenu: contextMenu, windowId: windowId, initialUserScripts: initialUserScripts) + openUrlRequest(id: id, urlRequest: urlRequest, options: options, contextMenu: contextMenu, windowId: windowId, initialUserScripts: initialUserScripts) result(true) break case "openFile": - let uuid = arguments!["uuid"] as! String + let id = arguments!["id"] as! String let assetFilePath = arguments!["assetFilePath"] as! String let options = arguments!["options"] as! [String: Any?] let contextMenu = arguments!["contextMenu"] as! [String: Any] let windowId = arguments!["windowId"] as? Int64 let initialUserScripts = arguments!["initialUserScripts"] as? [[String: Any]] - openFile(uuid: uuid, assetFilePath: assetFilePath, options: options, contextMenu: contextMenu, windowId: windowId, initialUserScripts: initialUserScripts) + openFile(id: id, assetFilePath: assetFilePath, options: options, contextMenu: contextMenu, windowId: windowId, initialUserScripts: initialUserScripts) result(true) break case "openData": - let uuid = arguments!["uuid"] as! String + let id = arguments!["id"] as! String let options = arguments!["options"] as! [String: Any?] let data = arguments!["data"] as! String let mimeType = arguments!["mimeType"] as! String @@ -66,7 +66,7 @@ public class InAppBrowserManager: NSObject, FlutterPlugin { let contextMenu = arguments!["contextMenu"] as! [String: Any] let windowId = arguments!["windowId"] as? Int64 let initialUserScripts = arguments!["initialUserScripts"] as? [[String: Any]] - openData(uuid: uuid, options: options, data: data, mimeType: mimeType, encoding: encoding, baseUrl: baseUrl, + openData(id: id, options: options, data: data, mimeType: mimeType, encoding: encoding, baseUrl: baseUrl, contextMenu: contextMenu, windowId: windowId, initialUserScripts: initialUserScripts) result(true) break @@ -98,11 +98,11 @@ public class InAppBrowserManager: NSObject, FlutterPlugin { return webViewController } - public func openUrlRequest(uuid: String, urlRequest: [String:Any?], options: [String: Any?], + public func openUrlRequest(id: String, urlRequest: [String:Any?], options: [String: Any?], contextMenu: [String: Any], windowId: Int64?, initialUserScripts: [[String: Any]]?) { let webViewController = prepareInAppBrowserWebViewController(options: options) - webViewController.uuid = uuid + webViewController.id = id webViewController.initialUrlRequest = URLRequest.init(fromPluginMap: urlRequest) webViewController.contextMenu = contextMenu webViewController.windowId = windowId @@ -111,11 +111,11 @@ public class InAppBrowserManager: NSObject, FlutterPlugin { presentViewController(webViewController: webViewController) } - public func openFile(uuid: String, assetFilePath: String, options: [String: Any?], + public func openFile(id: String, assetFilePath: String, options: [String: Any?], contextMenu: [String: Any], windowId: Int64?, initialUserScripts: [[String: Any]]?) { let webViewController = prepareInAppBrowserWebViewController(options: options) - webViewController.uuid = uuid + webViewController.id = id webViewController.initialFile = assetFilePath webViewController.contextMenu = contextMenu webViewController.windowId = windowId @@ -124,11 +124,11 @@ public class InAppBrowserManager: NSObject, FlutterPlugin { presentViewController(webViewController: webViewController) } - public func openData(uuid: String, options: [String: Any?], data: String, mimeType: String, encoding: String, + public func openData(id: String, options: [String: Any?], data: String, mimeType: String, encoding: String, baseUrl: String, contextMenu: [String: Any], windowId: Int64?, initialUserScripts: [[String: Any]]?) { let webViewController = prepareInAppBrowserWebViewController(options: options) - webViewController.uuid = uuid + webViewController.id = id webViewController.initialData = data webViewController.initialMimeType = mimeType webViewController.initialEncoding = encoding diff --git a/ios/Classes/InAppBrowser/InAppBrowserWebViewController.swift b/ios/Classes/InAppBrowser/InAppBrowserWebViewController.swift index f81ed688..ce71af97 100755 --- a/ios/Classes/InAppBrowser/InAppBrowserWebViewController.swift +++ b/ios/Classes/InAppBrowser/InAppBrowserWebViewController.swift @@ -21,7 +21,7 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega var progressBar: UIProgressView! var tmpWindow: UIWindow? - var uuid: String = "" + var id: String = "" var windowId: Int64? var webView: InAppWebView! var channel: FlutterMethodChannel? @@ -39,7 +39,7 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega var methodCallDelegate: InAppWebViewMethodHandler? public override func loadView() { - channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_inappbrowser_" + uuid, binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger()) + channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_inappbrowser_" + id, binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger()) var userScripts: [UserScript] = [] for intialUserScript in initialUserScripts { diff --git a/ios/Classes/InAppWebView/FlutterWebViewController.swift b/ios/Classes/InAppWebView/FlutterWebViewController.swift index 12f7a326..8ddb3c43 100755 --- a/ios/Classes/InAppWebView/FlutterWebViewController.swift +++ b/ios/Classes/InAppWebView/FlutterWebViewController.swift @@ -121,7 +121,7 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView { self.myView!.alpha = 0.01 UIApplication.shared.keyWindow!.insertSubview(self.myView!, at: 0) - let arguments: [String: Any] = ["uuid": viewId] + let arguments: [String: Any] = ["id": viewId] channel!.invokeMethod("onHeadlessWebViewCreated", arguments: arguments) } } diff --git a/ios/Classes/InAppWebView/HeadlessInAppWebViewManager.swift b/ios/Classes/InAppWebView/HeadlessInAppWebViewManager.swift index 8e7a9df7..9bb1aa17 100644 --- a/ios/Classes/InAppWebView/HeadlessInAppWebViewManager.swift +++ b/ios/Classes/InAppWebView/HeadlessInAppWebViewManager.swift @@ -31,16 +31,16 @@ public class HeadlessInAppWebViewManager: NSObject, FlutterPlugin { public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { let arguments = call.arguments as? NSDictionary - let uuid: String = arguments!["uuid"] as! String + let id: String = arguments!["id"] as! String switch call.method { case "createHeadlessWebView": let params = arguments!["params"] as! [String: Any?] - createHeadlessWebView(uuid: uuid, params: params) + createHeadlessWebView(id: id, params: params) result(true) break case "disposeHeadlessWebView": - disposeHeadlessWebView(uuid: uuid) + disposeHeadlessWebView(id: id) result(true) break default: @@ -49,17 +49,17 @@ public class HeadlessInAppWebViewManager: NSObject, FlutterPlugin { } } - public func createHeadlessWebView(uuid: String, params: [String: Any?]) { + public func createHeadlessWebView(id: String, params: [String: Any?]) { let controller = FlutterWebViewController(registrar: HeadlessInAppWebViewManager.registrar!, withFrame: CGRect.zero, - viewIdentifier: uuid, + viewIdentifier: id, arguments: params as NSDictionary) - flutterWebViews[uuid] = controller + flutterWebViews[id] = controller } - public func disposeHeadlessWebView(uuid: String) { - if let _ = flutterWebViews[uuid] { - flutterWebViews.removeValue(forKey: uuid) + public func disposeHeadlessWebView(id: String) { + if let _ = flutterWebViews[id] { + flutterWebViews.removeValue(forKey: id) } } } diff --git a/ios/Classes/PlatformUtil.swift b/ios/Classes/PlatformUtil.swift new file mode 100644 index 00000000..e84c96ce --- /dev/null +++ b/ios/Classes/PlatformUtil.swift @@ -0,0 +1,63 @@ +// +// PlatformUtil.swift +// flutter_inappwebview +// +// Created by Lorenzo Pichilli on 01/03/21. +// + +import Foundation + +class PlatformUtil: NSObject, FlutterPlugin { + static var registrar: FlutterPluginRegistrar? + static var channel: FlutterMethodChannel? + + static func register(with registrar: FlutterPluginRegistrar) { + + } + + init(registrar: FlutterPluginRegistrar) { + super.init() + InAppWebViewStatic.registrar = registrar + InAppWebViewStatic.channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_inappwebview_platformutil", binaryMessenger: registrar.messenger()) + registrar.addMethodCallDelegate(self, channel: InAppWebViewStatic.channel!) + } + + public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + let arguments = call.arguments as? NSDictionary + + switch call.method { + case "getSystemVersion": + let device = UIDevice.current + result(device.systemVersion) + break + case "formatDate": + let date = arguments!["date"] as! Int64 + let format = arguments!["format"] as! String + let locale = PlatformUtil.getLocaleFromString(locale: arguments!["locale"] as? String) + let timezone = TimeZone.init(abbreviation: arguments!["timezone"] as? String ?? "UTC")! + result(PlatformUtil.formatDate(date: date, format: format, locale: locale, timezone: timezone)) + break + default: + result(FlutterMethodNotImplemented) + break + } + } + + static public func getLocaleFromString(locale: String?) -> Locale { + guard let locale = locale else { + return Locale.init(identifier: "en_US") + } + return Locale.init(identifier: locale) + } + + static public func getDateFromMilliseconds(date: Int64) -> Date { + return Date(timeIntervalSince1970: TimeInterval(Double(date)/1000)) + } + + static public func formatDate(date: Int64, format: String, locale: Locale, timezone: TimeZone) -> String { + let formatter = DateFormatter() + formatter.dateFormat = format + formatter.timeZone = timezone + return formatter.string(from: PlatformUtil.getDateFromMilliseconds(date: date)) + } +} diff --git a/ios/Classes/SafariViewController/ChromeSafariBrowserManager.swift b/ios/Classes/SafariViewController/ChromeSafariBrowserManager.swift index 1c633fb3..137d0105 100755 --- a/ios/Classes/SafariViewController/ChromeSafariBrowserManager.swift +++ b/ios/Classes/SafariViewController/ChromeSafariBrowserManager.swift @@ -32,11 +32,11 @@ public class ChromeSafariBrowserManager: NSObject, FlutterPlugin { switch call.method { case "open": - let uuid: String = arguments!["uuid"] as! String + let id: String = arguments!["id"] as! String let url = arguments!["url"] as! String let options = arguments!["options"] as! [String: Any?] let menuItemList = arguments!["menuItemList"] as! [[String: Any]] - open(uuid: uuid, url: url, options: options, menuItemList: menuItemList, result: result) + open(id: id, url: url, options: options, menuItemList: menuItemList, result: result) break case "isAvailable": if #available(iOS 9.0, *) { @@ -51,7 +51,7 @@ public class ChromeSafariBrowserManager: NSObject, FlutterPlugin { } } - public func open(uuid: String, url: String, options: [String: Any?], menuItemList: [[String: Any]], result: @escaping FlutterResult) { + public func open(id: String, url: String, options: [String: Any?], menuItemList: [[String: Any]], result: @escaping FlutterResult) { let absoluteUrl = URL(string: url)!.absoluteURL if #available(iOS 9.0, *) { @@ -75,7 +75,7 @@ public class ChromeSafariBrowserManager: NSObject, FlutterPlugin { safari = SafariViewController(url: absoluteUrl) } - safari.uuid = uuid + safari.id = id safari.menuItemList = menuItemList safari.prepareMethodChannel() safari.delegate = safari diff --git a/ios/Classes/SafariViewController/SafariViewController.swift b/ios/Classes/SafariViewController/SafariViewController.swift index 395f39a3..0dbea527 100755 --- a/ios/Classes/SafariViewController/SafariViewController.swift +++ b/ios/Classes/SafariViewController/SafariViewController.swift @@ -13,7 +13,7 @@ public class SafariViewController: SFSafariViewController, FlutterPlugin, SFSafa var channel: FlutterMethodChannel? var safariOptions: SafariBrowserOptions? - var uuid: String = "" + var id: String = "" var menuItemList: [[String: Any]] = [] public static func register(with registrar: FlutterPluginRegistrar) { @@ -25,7 +25,7 @@ public class SafariViewController: SFSafariViewController, FlutterPlugin, SFSafa } public func prepareMethodChannel() { - channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_chromesafaribrowser_" + uuid, binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger()) + channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_chromesafaribrowser_" + id, binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger()) SwiftFlutterPlugin.instance!.registrar!.addMethodCallDelegate(self, channel: channel!) } @@ -104,7 +104,7 @@ public class SafariViewController: SFSafariViewController, FlutterPlugin, SFSafa public func safariViewController(_ controller: SFSafariViewController, activityItemsFor URL: URL, title: String?) -> [UIActivity] { var uiActivities: [UIActivity] = [] menuItemList.forEach { (menuItem) in - let activity = CustomUIActivity(uuid: uuid, id: menuItem["id"] as! Int64, url: URL, title: title, label: menuItem["label"] as? String, type: nil, image: nil) + let activity = CustomUIActivity(viewId: id, id: menuItem["id"] as! Int64, url: URL, title: title, label: menuItem["label"] as? String, type: nil, image: nil) uiActivities.append(activity) } return uiActivities @@ -141,7 +141,7 @@ public class SafariViewController: SFSafariViewController, FlutterPlugin, SFSafa } class CustomUIActivity : UIActivity { - var uuid: String + var viewId: String var id: Int64 var url: URL var title: String? @@ -149,8 +149,8 @@ class CustomUIActivity : UIActivity { var label: String? var image: UIImage? - init(uuid: String, id: Int64, url: URL, title: String?, label: String?, type: UIActivity.ActivityType?, image: UIImage?) { - self.uuid = uuid + init(viewId: String, id: Int64, url: URL, title: String?, label: String?, type: UIActivity.ActivityType?, image: UIImage?) { + self.viewId = viewId self.id = id self.url = url self.title = title @@ -180,7 +180,7 @@ class CustomUIActivity : UIActivity { } override func perform() { - let channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_chromesafaribrowser_" + uuid, binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger()) + let channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_chromesafaribrowser_" + viewId, binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger()) let arguments: [String: Any?] = [ "url": url.absoluteString, diff --git a/ios/Classes/SwiftFlutterPlugin.swift b/ios/Classes/SwiftFlutterPlugin.swift index 3117e8cb..98977ee1 100755 --- a/ios/Classes/SwiftFlutterPlugin.swift +++ b/ios/Classes/SwiftFlutterPlugin.swift @@ -26,6 +26,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin { static var instance: SwiftFlutterPlugin? var registrar: FlutterPluginRegistrar? + var platformUtil: PlatformUtil? var inAppWebViewStatic: InAppWebViewStatic? var myCookieManager: Any? var myWebStorageManager: Any? @@ -43,6 +44,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin { self.registrar = registrar registrar.register(FlutterWebViewFactory(registrar: registrar) as FlutterPlatformViewFactory, withId: "com.pichillilorenzo/flutter_inappwebview") + platformUtil = PlatformUtil(registrar: registrar) inAppBrowserManager = InAppBrowserManager(registrar: registrar) headlessInAppWebViewManager = HeadlessInAppWebViewManager(registrar: registrar) chromeSafariBrowserManager = ChromeSafariBrowserManager(registrar: registrar) diff --git a/lib/src/_uuid_generator.dart b/lib/src/_uuid_generator.dart deleted file mode 100644 index c2bbf86e..00000000 --- a/lib/src/_uuid_generator.dart +++ /dev/null @@ -1,4 +0,0 @@ -import 'package:uuid/uuid.dart'; - -// ignore: non_constant_identifier_names -final UUID_GENERATOR = Uuid(); diff --git a/lib/src/chrome_safari_browser/chrome_safari_browser.dart b/lib/src/chrome_safari_browser/chrome_safari_browser.dart index b6fc4780..47818b2c 100755 --- a/lib/src/chrome_safari_browser/chrome_safari_browser.dart +++ b/lib/src/chrome_safari_browser/chrome_safari_browser.dart @@ -2,8 +2,8 @@ import 'dart:async'; import 'dart:collection'; import 'package:flutter/services.dart'; +import 'package:flutter_inappwebview/src/util.dart'; -import '../_uuid_generator.dart'; import 'chrome_safari_browser_options.dart'; class ChromeSafariBrowserAlreadyOpenedException implements Exception { @@ -37,7 +37,7 @@ class ChromeSafariBrowserNotOpenedException implements Exception { ///`android.support.customtabs.action.CustomTabsService` in your `AndroidManifest.xml` ///(you can read more about it here: https://developers.google.com/web/android/custom-tabs/best-practices#applications_targeting_android_11_api_level_30_or_above). class ChromeSafariBrowser { - late String uuid; + late String id; Map _menuItems = new HashMap(); bool _isOpened = false; late MethodChannel _channel; @@ -45,9 +45,9 @@ class ChromeSafariBrowser { const MethodChannel('com.pichillilorenzo/flutter_chromesafaribrowser'); ChromeSafariBrowser() { - uuid = UUID_GENERATOR.v4(); + id = ViewIdGenerator.generateId(); this._channel = - MethodChannel('com.pichillilorenzo/flutter_chromesafaribrowser_$uuid'); + MethodChannel('com.pichillilorenzo/flutter_chromesafaribrowser_$id'); this._channel.setMethodCallHandler(handleMethod); _isOpened = false; } @@ -93,7 +93,7 @@ class ChromeSafariBrowser { }); Map args = {}; - args.putIfAbsent('uuid', () => uuid); + args.putIfAbsent('id', () => id); args.putIfAbsent('url', () => url.toString()); args.putIfAbsent('options', () => options?.toMap() ?? {}); args.putIfAbsent('menuItemList', () => menuItemList); diff --git a/lib/src/cookie_manager.dart b/lib/src/cookie_manager.dart index 9b8c0b40..db3fc006 100755 --- a/lib/src/cookie_manager.dart +++ b/lib/src/cookie_manager.dart @@ -1,13 +1,12 @@ import 'dart:async'; import 'dart:io'; -import 'package:device_info/device_info.dart'; import 'package:flutter/services.dart'; -import 'package:intl/intl.dart'; import 'in_app_webview/in_app_webview_controller.dart'; import 'in_app_webview/in_app_webview_options.dart'; import 'in_app_webview/headless_in_app_webview.dart'; +import 'platform_util.dart'; import 'types.dart'; @@ -72,9 +71,8 @@ class CookieManager { assert(path.isNotEmpty); if (Platform.isIOS) { - DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); - IosDeviceInfo iosInfo = await deviceInfo.iosInfo; - var version = double.tryParse(iosInfo.systemVersion); + var platformUtil = PlatformUtil(); + var version = double.tryParse(await platformUtil.getSystemVersion()); if (version != null && version < 11.0) { await _setCookieWithJavaScript( url: url, @@ -121,7 +119,7 @@ class CookieManager { name + "=" + value + "; Domain=" + domain + "; Path=" + path; if (expiresDate != null) - cookieValue += "; Expires=" + _getCookieExpirationDate(expiresDate); + cookieValue += "; Expires=" + await _getCookieExpirationDate(expiresDate); if (maxAge != null) cookieValue += "; Max-Age=" + maxAge.toString(); @@ -169,9 +167,8 @@ class CookieManager { assert(url.toString().isNotEmpty); if (Platform.isIOS) { - DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); - IosDeviceInfo iosInfo = await deviceInfo.iosInfo; - var version = double.tryParse(iosInfo.systemVersion); + var platformUtil = PlatformUtil(); + var version = double.tryParse(await platformUtil.getSystemVersion()); if (version != null && version < 11.0) { return await _getCookiesWithJavaScript( url: url, webViewController: iosBelow11WebViewController); @@ -269,9 +266,8 @@ class CookieManager { assert(name.isNotEmpty); if (Platform.isIOS) { - DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); - IosDeviceInfo iosInfo = await deviceInfo.iosInfo; - var version = double.tryParse(iosInfo.systemVersion); + var platformUtil = PlatformUtil(); + var version = double.tryParse(await platformUtil.getSystemVersion()); if (version != null && version < 11.0) { List cookies = await _getCookiesWithJavaScript( url: url, webViewController: iosBelow11WebViewController); @@ -326,9 +322,8 @@ class CookieManager { assert(name.isNotEmpty); if (Platform.isIOS) { - DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); - IosDeviceInfo iosInfo = await deviceInfo.iosInfo; - var version = double.tryParse(iosInfo.systemVersion); + var platformUtil = PlatformUtil(); + var version = double.tryParse(await platformUtil.getSystemVersion()); if (version != null && version < 11.0) { await _setCookieWithJavaScript( url: url, @@ -371,9 +366,8 @@ class CookieManager { assert(url.toString().isNotEmpty); if (Platform.isIOS) { - DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); - IosDeviceInfo iosInfo = await deviceInfo.iosInfo; - var version = double.tryParse(iosInfo.systemVersion); + var platformUtil = PlatformUtil(); + var version = double.tryParse(await platformUtil.getSystemVersion()); if (version != null && version < 11.0) { List cookies = await _getCookiesWithJavaScript( url: url, webViewController: iosBelow11WebViewController); @@ -408,15 +402,13 @@ class CookieManager { String _getDomainName(Uri url) { String domain = url.host; - // ignore: unnecessary_null_comparison - if (domain == null) return ""; return domain.startsWith("www.") ? domain.substring(4) : domain; } - String _getCookieExpirationDate(int expiresDate) { + Future _getCookieExpirationDate(int expiresDate) async { + var platformUtil = PlatformUtil(); var dateTime = DateTime.fromMillisecondsSinceEpoch(expiresDate).toUtc(); - return DateFormat('EEE, d MMM yyyy hh:mm:ss', "en_US").format(dateTime) + - ' GMT'; + return await platformUtil.formatDate(date: dateTime, format: 'EEE, dd MMM yyyy hh:mm:ss z', locale: 'en_US', timezone: 'GMT'); } } diff --git a/lib/src/in_app_browser/in_app_browser.dart b/lib/src/in_app_browser/in_app_browser.dart index 0c11961d..f93f97e4 100755 --- a/lib/src/in_app_browser/in_app_browser.dart +++ b/lib/src/in_app_browser/in_app_browser.dart @@ -3,10 +3,10 @@ import 'dart:collection'; import 'dart:typed_data'; import 'package:flutter/services.dart'; +import 'package:flutter_inappwebview/src/util.dart'; import '../context_menu.dart'; import '../types.dart'; -import '../_uuid_generator.dart'; import '../in_app_webview/in_app_webview_controller.dart'; import '../in_app_webview/in_app_webview_options.dart'; @@ -41,7 +41,7 @@ class InAppBrowserNotOpenedException implements Exception { ///The [webViewController] field can be used to access the [InAppWebViewController] API. class InAppBrowser { ///Browser's UUID. - late String uuid; + late String id; ///Context menu used by the browser. It should be set before opening the browser. ContextMenu? contextMenu; @@ -62,13 +62,13 @@ class InAppBrowser { /// InAppBrowser({this.windowId, this.initialUserScripts}) { - uuid = UUID_GENERATOR.v4(); + id = ViewIdGenerator.generateId(); this._channel = - MethodChannel('com.pichillilorenzo/flutter_inappbrowser_$uuid'); + MethodChannel('com.pichillilorenzo/flutter_inappbrowser_$id'); this._channel.setMethodCallHandler(handleMethod); _isOpened = false; webViewController = new InAppWebViewController.fromInAppBrowser( - uuid, this._channel, this, this.initialUserScripts); + id, this._channel, this, this.initialUserScripts); } Future handleMethod(MethodCall call) async { @@ -98,7 +98,7 @@ class InAppBrowser { assert(urlRequest.url != null && urlRequest.url.toString().isNotEmpty); Map args = {}; - args.putIfAbsent('uuid', () => uuid); + args.putIfAbsent('id', () => id); args.putIfAbsent('urlRequest', () => urlRequest.toMap()); args.putIfAbsent('options', () => options?.toMap() ?? InAppBrowserClassOptions().toMap()); @@ -151,7 +151,7 @@ class InAppBrowser { assert(assetFilePath.isNotEmpty); Map args = {}; - args.putIfAbsent('uuid', () => uuid); + args.putIfAbsent('id', () => id); args.putIfAbsent('assetFilePath', () => assetFilePath); args.putIfAbsent('options', () => options?.toMap() ?? InAppBrowserClassOptions().toMap()); @@ -181,7 +181,7 @@ class InAppBrowser { this.throwIfAlreadyOpened(message: 'Cannot open data!'); Map args = {}; - args.putIfAbsent('uuid', () => uuid); + args.putIfAbsent('id', () => id); args.putIfAbsent('options', () => options?.toMap() ?? InAppBrowserClassOptions().toMap()); args.putIfAbsent('data', () => data); @@ -209,7 +209,7 @@ class InAppBrowser { Future show() async { this.throwIfNotOpened(); Map args = {}; - args.putIfAbsent('uuid', () => uuid); + args.putIfAbsent('id', () => id); await _channel.invokeMethod('show', args); } diff --git a/lib/src/in_app_localhost_server.dart b/lib/src/in_app_localhost_server.dart index c4817c52..83188744 100755 --- a/lib/src/in_app_localhost_server.dart +++ b/lib/src/in_app_localhost_server.dart @@ -2,7 +2,8 @@ import 'dart:io'; import 'dart:async'; import 'package:flutter/services.dart' show rootBundle; -import 'package:mime/mime.dart'; + +import 'mime_type_resolver.dart'; ///This class allows you to create a simple server on `http://localhost:[port]/` in order to be able to load your assets file on a server. The default [port] value is `8080`. class InAppLocalhostServer { @@ -54,8 +55,7 @@ class InAppLocalhostServer { var contentType = ['text', 'html']; if (!request.requestedUri.path.endsWith('/') && request.requestedUri.pathSegments.isNotEmpty) { - var mimeType = - lookupMimeType(request.requestedUri.path, headerBytes: body); + var mimeType = MimeTypeResolver.lookup(request.requestedUri.path); if (mimeType != null) { contentType = mimeType.split('/'); } diff --git a/lib/src/in_app_webview/headless_in_app_webview.dart b/lib/src/in_app_webview/headless_in_app_webview.dart index 3df7c02d..a56e6e37 100644 --- a/lib/src/in_app_webview/headless_in_app_webview.dart +++ b/lib/src/in_app_webview/headless_in_app_webview.dart @@ -2,10 +2,10 @@ import 'dart:collection'; import 'dart:typed_data'; import 'package:flutter/services.dart'; +import 'package:flutter_inappwebview/src/util.dart'; import '../context_menu.dart'; import '../types.dart'; -import '../_uuid_generator.dart'; import 'webview.dart'; import 'in_app_webview_controller.dart'; import 'in_app_webview_options.dart'; @@ -15,7 +15,7 @@ import 'in_app_webview_options.dart'; /// ///Remember to dispose it when you don't need it anymore. class HeadlessInAppWebView implements WebView { - late String uuid; + late String id; bool _isDisposed = true; static const MethodChannel _sharedChannel = const MethodChannel('com.pichillilorenzo/flutter_headless_inappwebview'); @@ -86,8 +86,8 @@ class HeadlessInAppWebView implements WebView { this.initialOptions, this.contextMenu, this.initialUserScripts}) { - uuid = UUID_GENERATOR.v4(); - webViewController = new InAppWebViewController(uuid, this); + id = ViewIdGenerator.generateId(); + webViewController = new InAppWebViewController(id, this); } Future handleMethod(MethodCall call) async { @@ -109,7 +109,7 @@ class HeadlessInAppWebView implements WebView { } _isDisposed = false; Map args = {}; - args.putIfAbsent('uuid', () => uuid); + args.putIfAbsent('id', () => id); args.putIfAbsent( 'params', () => { @@ -133,7 +133,7 @@ class HeadlessInAppWebView implements WebView { return; } Map args = {}; - args.putIfAbsent('uuid', () => uuid); + args.putIfAbsent('id', () => id); await _sharedChannel.invokeMethod('disposeHeadlessWebView', args); _isDisposed = true; } diff --git a/lib/src/mime_type_resolver.dart b/lib/src/mime_type_resolver.dart new file mode 100644 index 00000000..d28cc0e6 --- /dev/null +++ b/lib/src/mime_type_resolver.dart @@ -0,0 +1,1022 @@ +class MimeTypeResolver { + + /* + Extension map generated from http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/conf/mime.types?view=markup + using this JavaScript code: + + var extensionMap = {}; + var table = document.querySelector('#vc_file table'); + var rows = [].slice.call(table.querySelectorAll('tbody tr')); + for (var row of rows) { + var line = [].slice.call(row.querySelectorAll('td'))[1].textContent.trim(); + if (line.startsWith('#')) { + continue; + } + var parts = line.split(/\s+/); + var mime = parts[0].trim(); + parts.splice(0, 1); + for (var ext of parts) { + extensionMap[ext.trim()] = mime; + } + } + console.log(JSON.stringify(extensionMap, null, '\t')); + */ + static final Map extensionMap = { + "123": "application/vnd.lotus-1-2-3", + "ez": "application/andrew-inset", + "aw": "application/applixware", + "atom": "application/atom+xml", + "atomcat": "application/atomcat+xml", + "atomsvc": "application/atomsvc+xml", + "ccxml": "application/ccxml+xml", + "cdmia": "application/cdmi-capability", + "cdmic": "application/cdmi-container", + "cdmid": "application/cdmi-domain", + "cdmio": "application/cdmi-object", + "cdmiq": "application/cdmi-queue", + "cu": "application/cu-seeme", + "davmount": "application/davmount+xml", + "dbk": "application/docbook+xml", + "dssc": "application/dssc+der", + "xdssc": "application/dssc+xml", + "ecma": "application/ecmascript", + "emma": "application/emma+xml", + "epub": "application/epub+zip", + "exi": "application/exi", + "pfr": "application/font-tdpfr", + "gml": "application/gml+xml", + "gpx": "application/gpx+xml", + "gxf": "application/gxf", + "stk": "application/hyperstudio", + "ink": "application/inkml+xml", + "inkml": "application/inkml+xml", + "ipfix": "application/ipfix", + "jar": "application/java-archive", + "ser": "application/java-serialized-object", + "class": "application/java-vm", + "js": "application/javascript", + "json": "application/json", + "jsonml": "application/jsonml+json", + "lostxml": "application/lost+xml", + "hqx": "application/mac-binhex40", + "cpt": "application/mac-compactpro", + "mads": "application/mads+xml", + "mrc": "application/marc", + "mrcx": "application/marcxml+xml", + "ma": "application/mathematica", + "nb": "application/mathematica", + "mb": "application/mathematica", + "mathml": "application/mathml+xml", + "mbox": "application/mbox", + "mscml": "application/mediaservercontrol+xml", + "metalink": "application/metalink+xml", + "meta4": "application/metalink4+xml", + "mets": "application/mets+xml", + "mods": "application/mods+xml", + "m21": "application/mp21", + "mp21": "application/mp21", + "mp4s": "application/mp4", + "doc": "application/msword", + "dot": "application/msword", + "mxf": "application/mxf", + "bin": "application/octet-stream", + "dms": "application/octet-stream", + "lrf": "application/octet-stream", + "mar": "application/octet-stream", + "so": "application/octet-stream", + "dist": "application/octet-stream", + "distz": "application/octet-stream", + "pkg": "application/octet-stream", + "bpk": "application/octet-stream", + "dump": "application/octet-stream", + "elc": "application/octet-stream", + "deploy": "application/octet-stream", + "oda": "application/oda", + "opf": "application/oebps-package+xml", + "ogx": "application/ogg", + "omdoc": "application/omdoc+xml", + "onetoc": "application/onenote", + "onetoc2": "application/onenote", + "onetmp": "application/onenote", + "onepkg": "application/onenote", + "oxps": "application/oxps", + "xer": "application/patch-ops-error+xml", + "pdf": "application/pdf", + "pgp": "application/pgp-encrypted", + "asc": "application/pgp-signature", + "sig": "application/pgp-signature", + "prf": "application/pics-rules", + "p10": "application/pkcs10", + "p7m": "application/pkcs7-mime", + "p7c": "application/pkcs7-mime", + "p7s": "application/pkcs7-signature", + "p8": "application/pkcs8", + "ac": "application/pkix-attr-cert", + "cer": "application/pkix-cert", + "crl": "application/pkix-crl", + "pkipath": "application/pkix-pkipath", + "pki": "application/pkixcmp", + "pls": "application/pls+xml", + "ai": "application/postscript", + "eps": "application/postscript", + "ps": "application/postscript", + "cww": "application/prs.cww", + "pskcxml": "application/pskc+xml", + "rdf": "application/rdf+xml", + "rif": "application/reginfo+xml", + "rnc": "application/relax-ng-compact-syntax", + "rl": "application/resource-lists+xml", + "rld": "application/resource-lists-diff+xml", + "rs": "application/rls-services+xml", + "gbr": "application/rpki-ghostbusters", + "mft": "application/rpki-manifest", + "roa": "application/rpki-roa", + "rsd": "application/rsd+xml", + "rss": "application/rss+xml", + "rtf": "application/rtf", + "sbml": "application/sbml+xml", + "scq": "application/scvp-cv-request", + "scs": "application/scvp-cv-response", + "spq": "application/scvp-vp-request", + "spp": "application/scvp-vp-response", + "sdp": "application/sdp", + "setpay": "application/set-payment-initiation", + "setreg": "application/set-registration-initiation", + "shf": "application/shf+xml", + "smi": "application/smil+xml", + "smil": "application/smil+xml", + "rq": "application/sparql-query", + "srx": "application/sparql-results+xml", + "gram": "application/srgs", + "grxml": "application/srgs+xml", + "sru": "application/sru+xml", + "ssdl": "application/ssdl+xml", + "ssml": "application/ssml+xml", + "tei": "application/tei+xml", + "teicorpus": "application/tei+xml", + "tfi": "application/thraud+xml", + "tsd": "application/timestamped-data", + "plb": "application/vnd.3gpp.pic-bw-large", + "psb": "application/vnd.3gpp.pic-bw-small", + "pvb": "application/vnd.3gpp.pic-bw-var", + "tcap": "application/vnd.3gpp2.tcap", + "pwn": "application/vnd.3m.post-it-notes", + "aso": "application/vnd.accpac.simply.aso", + "imp": "application/vnd.accpac.simply.imp", + "acu": "application/vnd.acucobol", + "atc": "application/vnd.acucorp", + "acutc": "application/vnd.acucorp", + "air": "application/vnd.adobe.air-application-installer-package+zip", + "fcdt": "application/vnd.adobe.formscentral.fcdt", + "fxp": "application/vnd.adobe.fxp", + "fxpl": "application/vnd.adobe.fxp", + "xdp": "application/vnd.adobe.xdp+xml", + "xfdf": "application/vnd.adobe.xfdf", + "ahead": "application/vnd.ahead.space", + "azf": "application/vnd.airzip.filesecure.azf", + "azs": "application/vnd.airzip.filesecure.azs", + "azw": "application/vnd.amazon.ebook", + "acc": "application/vnd.americandynamics.acc", + "ami": "application/vnd.amiga.ami", + "apk": "application/vnd.android.package-archive", + "cii": "application/vnd.anser-web-certificate-issue-initiation", + "fti": "application/vnd.anser-web-funds-transfer-initiation", + "atx": "application/vnd.antix.game-component", + "mpkg": "application/vnd.apple.installer+xml", + "m3u8": "application/vnd.apple.mpegurl", + "swi": "application/vnd.aristanetworks.swi", + "iota": "application/vnd.astraea-software.iota", + "aep": "application/vnd.audiograph", + "mpm": "application/vnd.blueice.multipass", + "bmi": "application/vnd.bmi", + "rep": "application/vnd.businessobjects", + "cdxml": "application/vnd.chemdraw+xml", + "mmd": "application/vnd.chipnuts.karaoke-mmd", + "cdy": "application/vnd.cinderella", + "cla": "application/vnd.claymore", + "rp9": "application/vnd.cloanto.rp9", + "c4g": "application/vnd.clonk.c4group", + "c4d": "application/vnd.clonk.c4group", + "c4f": "application/vnd.clonk.c4group", + "c4p": "application/vnd.clonk.c4group", + "c4u": "application/vnd.clonk.c4group", + "c11amc": "application/vnd.cluetrust.cartomobile-config", + "c11amz": "application/vnd.cluetrust.cartomobile-config-pkg", + "csp": "application/vnd.commonspace", + "cdbcmsg": "application/vnd.contact.cmsg", + "cmc": "application/vnd.cosmocaller", + "clkx": "application/vnd.crick.clicker", + "clkk": "application/vnd.crick.clicker.keyboard", + "clkp": "application/vnd.crick.clicker.palette", + "clkt": "application/vnd.crick.clicker.template", + "clkw": "application/vnd.crick.clicker.wordbank", + "wbs": "application/vnd.criticaltools.wbs+xml", + "pml": "application/vnd.ctc-posml", + "ppd": "application/vnd.cups-ppd", + "car": "application/vnd.curl.car", + "pcurl": "application/vnd.curl.pcurl", + "dart": "application/vnd.dart", + "rdz": "application/vnd.data-vision.rdz", + "uvf": "application/vnd.dece.data", + "uvvf": "application/vnd.dece.data", + "uvd": "application/vnd.dece.data", + "uvvd": "application/vnd.dece.data", + "uvt": "application/vnd.dece.ttml+xml", + "uvvt": "application/vnd.dece.ttml+xml", + "uvx": "application/vnd.dece.unspecified", + "uvvx": "application/vnd.dece.unspecified", + "uvz": "application/vnd.dece.zip", + "uvvz": "application/vnd.dece.zip", + "fe_launch": "application/vnd.denovo.fcselayout-link", + "dna": "application/vnd.dna", + "mlp": "application/vnd.dolby.mlp", + "dpg": "application/vnd.dpgraph", + "dfac": "application/vnd.dreamfactory", + "kpxx": "application/vnd.ds-keypoint", + "ait": "application/vnd.dvb.ait", + "svc": "application/vnd.dvb.service", + "geo": "application/vnd.dynageo", + "mag": "application/vnd.ecowin.chart", + "nml": "application/vnd.enliven", + "esf": "application/vnd.epson.esf", + "msf": "application/vnd.epson.msf", + "qam": "application/vnd.epson.quickanime", + "slt": "application/vnd.epson.salt", + "ssf": "application/vnd.epson.ssf", + "es3": "application/vnd.eszigno3+xml", + "et3": "application/vnd.eszigno3+xml", + "ez2": "application/vnd.ezpix-album", + "ez3": "application/vnd.ezpix-package", + "fdf": "application/vnd.fdf", + "mseed": "application/vnd.fdsn.mseed", + "seed": "application/vnd.fdsn.seed", + "dataless": "application/vnd.fdsn.seed", + "gph": "application/vnd.flographit", + "ftc": "application/vnd.fluxtime.clip", + "fm": "application/vnd.framemaker", + "frame": "application/vnd.framemaker", + "maker": "application/vnd.framemaker", + "book": "application/vnd.framemaker", + "fnc": "application/vnd.frogans.fnc", + "ltf": "application/vnd.frogans.ltf", + "fsc": "application/vnd.fsc.weblaunch", + "oas": "application/vnd.fujitsu.oasys", + "oa2": "application/vnd.fujitsu.oasys2", + "oa3": "application/vnd.fujitsu.oasys3", + "fg5": "application/vnd.fujitsu.oasysgp", + "bh2": "application/vnd.fujitsu.oasysprs", + "ddd": "application/vnd.fujixerox.ddd", + "xdw": "application/vnd.fujixerox.docuworks", + "xbd": "application/vnd.fujixerox.docuworks.binder", + "fzs": "application/vnd.fuzzysheet", + "txd": "application/vnd.genomatix.tuxedo", + "ggb": "application/vnd.geogebra.file", + "ggt": "application/vnd.geogebra.tool", + "gex": "application/vnd.geometry-explorer", + "gre": "application/vnd.geometry-explorer", + "gxt": "application/vnd.geonext", + "g2w": "application/vnd.geoplan", + "g3w": "application/vnd.geospace", + "gmx": "application/vnd.gmx", + "kml": "application/vnd.google-earth.kml+xml", + "kmz": "application/vnd.google-earth.kmz", + "gqf": "application/vnd.grafeq", + "gqs": "application/vnd.grafeq", + "gac": "application/vnd.groove-account", + "ghf": "application/vnd.groove-help", + "gim": "application/vnd.groove-identity-message", + "grv": "application/vnd.groove-injector", + "gtm": "application/vnd.groove-tool-message", + "tpl": "application/vnd.groove-tool-template", + "vcg": "application/vnd.groove-vcard", + "hal": "application/vnd.hal+xml", + "zmm": "application/vnd.handheld-entertainment+xml", + "hbci": "application/vnd.hbci", + "les": "application/vnd.hhe.lesson-player", + "hpgl": "application/vnd.hp-hpgl", + "hpid": "application/vnd.hp-hpid", + "hps": "application/vnd.hp-hps", + "jlt": "application/vnd.hp-jlyt", + "pcl": "application/vnd.hp-pcl", + "pclxl": "application/vnd.hp-pclxl", + "sfd-hdstx": "application/vnd.hydrostatix.sof-data", + "mpy": "application/vnd.ibm.minipay", + "afp": "application/vnd.ibm.modcap", + "listafp": "application/vnd.ibm.modcap", + "list3820": "application/vnd.ibm.modcap", + "irm": "application/vnd.ibm.rights-management", + "sc": "application/vnd.ibm.secure-container", + "icc": "application/vnd.iccprofile", + "icm": "application/vnd.iccprofile", + "igl": "application/vnd.igloader", + "ivp": "application/vnd.immervision-ivp", + "ivu": "application/vnd.immervision-ivu", + "igm": "application/vnd.insors.igm", + "xpw": "application/vnd.intercon.formnet", + "xpx": "application/vnd.intercon.formnet", + "i2g": "application/vnd.intergeo", + "qbo": "application/vnd.intu.qbo", + "qfx": "application/vnd.intu.qfx", + "rcprofile": "application/vnd.ipunplugged.rcprofile", + "irp": "application/vnd.irepository.package+xml", + "xpr": "application/vnd.is-xpr", + "fcs": "application/vnd.isac.fcs", + "jam": "application/vnd.jam", + "rms": "application/vnd.jcp.javame.midlet-rms", + "jisp": "application/vnd.jisp", + "joda": "application/vnd.joost.joda-archive", + "ktz": "application/vnd.kahootz", + "ktr": "application/vnd.kahootz", + "karbon": "application/vnd.kde.karbon", + "chrt": "application/vnd.kde.kchart", + "kfo": "application/vnd.kde.kformula", + "flw": "application/vnd.kde.kivio", + "kon": "application/vnd.kde.kontour", + "kpr": "application/vnd.kde.kpresenter", + "kpt": "application/vnd.kde.kpresenter", + "ksp": "application/vnd.kde.kspread", + "kwd": "application/vnd.kde.kword", + "kwt": "application/vnd.kde.kword", + "htke": "application/vnd.kenameaapp", + "kia": "application/vnd.kidspiration", + "kne": "application/vnd.kinar", + "knp": "application/vnd.kinar", + "skp": "application/vnd.koan", + "skd": "application/vnd.koan", + "skt": "application/vnd.koan", + "skm": "application/vnd.koan", + "sse": "application/vnd.kodak-descriptor", + "lasxml": "application/vnd.las.las+xml", + "lbd": "application/vnd.llamagraphics.life-balance.desktop", + "lbe": "application/vnd.llamagraphics.life-balance.exchange+xml", + "apr": "application/vnd.lotus-approach", + "pre": "application/vnd.lotus-freelance", + "nsf": "application/vnd.lotus-notes", + "org": "application/vnd.lotus-organizer", + "scm": "application/vnd.lotus-screencam", + "lwp": "application/vnd.lotus-wordpro", + "portpkg": "application/vnd.macports.portpkg", + "mcd": "application/vnd.mcd", + "mc1": "application/vnd.medcalcdata", + "cdkey": "application/vnd.mediastation.cdkey", + "mwf": "application/vnd.mfer", + "mfm": "application/vnd.mfmp", + "flo": "application/vnd.micrografx.flo", + "igx": "application/vnd.micrografx.igx", + "mif": "application/vnd.mif", + "daf": "application/vnd.mobius.daf", + "dis": "application/vnd.mobius.dis", + "mbk": "application/vnd.mobius.mbk", + "mqy": "application/vnd.mobius.mqy", + "msl": "application/vnd.mobius.msl", + "plc": "application/vnd.mobius.plc", + "txf": "application/vnd.mobius.txf", + "mpn": "application/vnd.mophun.application", + "mpc": "application/vnd.mophun.certificate", + "xul": "application/vnd.mozilla.xul+xml", + "cil": "application/vnd.ms-artgalry", + "cab": "application/vnd.ms-cab-compressed", + "xls": "application/vnd.ms-excel", + "xlm": "application/vnd.ms-excel", + "xla": "application/vnd.ms-excel", + "xlc": "application/vnd.ms-excel", + "xlt": "application/vnd.ms-excel", + "xlw": "application/vnd.ms-excel", + "xlam": "application/vnd.ms-excel.addin.macroenabled.12", + "xlsb": "application/vnd.ms-excel.sheet.binary.macroenabled.12", + "xlsm": "application/vnd.ms-excel.sheet.macroenabled.12", + "xltm": "application/vnd.ms-excel.template.macroenabled.12", + "eot": "application/vnd.ms-fontobject", + "chm": "application/vnd.ms-htmlhelp", + "ims": "application/vnd.ms-ims", + "lrm": "application/vnd.ms-lrm", + "thmx": "application/vnd.ms-officetheme", + "cat": "application/vnd.ms-pki.seccat", + "stl": "application/vnd.ms-pki.stl", + "ppt": "application/vnd.ms-powerpoint", + "pps": "application/vnd.ms-powerpoint", + "pot": "application/vnd.ms-powerpoint", + "ppam": "application/vnd.ms-powerpoint.addin.macroenabled.12", + "pptm": "application/vnd.ms-powerpoint.presentation.macroenabled.12", + "sldm": "application/vnd.ms-powerpoint.slide.macroenabled.12", + "ppsm": "application/vnd.ms-powerpoint.slideshow.macroenabled.12", + "potm": "application/vnd.ms-powerpoint.template.macroenabled.12", + "mpp": "application/vnd.ms-project", + "mpt": "application/vnd.ms-project", + "docm": "application/vnd.ms-word.document.macroenabled.12", + "dotm": "application/vnd.ms-word.template.macroenabled.12", + "wps": "application/vnd.ms-works", + "wks": "application/vnd.ms-works", + "wcm": "application/vnd.ms-works", + "wdb": "application/vnd.ms-works", + "wpl": "application/vnd.ms-wpl", + "xps": "application/vnd.ms-xpsdocument", + "mseq": "application/vnd.mseq", + "mus": "application/vnd.musician", + "msty": "application/vnd.muvee.style", + "taglet": "application/vnd.mynfc", + "nlu": "application/vnd.neurolanguage.nlu", + "ntf": "application/vnd.nitf", + "nitf": "application/vnd.nitf", + "nnd": "application/vnd.noblenet-directory", + "nns": "application/vnd.noblenet-sealer", + "nnw": "application/vnd.noblenet-web", + "ngdat": "application/vnd.nokia.n-gage.data", + "n-gage": "application/vnd.nokia.n-gage.symbian.install", + "rpst": "application/vnd.nokia.radio-preset", + "rpss": "application/vnd.nokia.radio-presets", + "edm": "application/vnd.novadigm.edm", + "edx": "application/vnd.novadigm.edx", + "ext": "application/vnd.novadigm.ext", + "odc": "application/vnd.oasis.opendocument.chart", + "otc": "application/vnd.oasis.opendocument.chart-template", + "odb": "application/vnd.oasis.opendocument.database", + "odf": "application/vnd.oasis.opendocument.formula", + "odft": "application/vnd.oasis.opendocument.formula-template", + "odg": "application/vnd.oasis.opendocument.graphics", + "otg": "application/vnd.oasis.opendocument.graphics-template", + "odi": "application/vnd.oasis.opendocument.image", + "oti": "application/vnd.oasis.opendocument.image-template", + "odp": "application/vnd.oasis.opendocument.presentation", + "otp": "application/vnd.oasis.opendocument.presentation-template", + "ods": "application/vnd.oasis.opendocument.spreadsheet", + "ots": "application/vnd.oasis.opendocument.spreadsheet-template", + "odt": "application/vnd.oasis.opendocument.text", + "odm": "application/vnd.oasis.opendocument.text-master", + "ott": "application/vnd.oasis.opendocument.text-template", + "oth": "application/vnd.oasis.opendocument.text-web", + "xo": "application/vnd.olpc-sugar", + "dd2": "application/vnd.oma.dd2+xml", + "oxt": "application/vnd.openofficeorg.extension", + "pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation", + "sldx": "application/vnd.openxmlformats-officedocument.presentationml.slide", + "ppsx": "application/vnd.openxmlformats-officedocument.presentationml.slideshow", + "potx": "application/vnd.openxmlformats-officedocument.presentationml.template", + "xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + "xltx": "application/vnd.openxmlformats-officedocument.spreadsheetml.template", + "docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + "dotx": "application/vnd.openxmlformats-officedocument.wordprocessingml.template", + "mgp": "application/vnd.osgeo.mapguide.package", + "dp": "application/vnd.osgi.dp", + "esa": "application/vnd.osgi.subsystem", + "pdb": "application/vnd.palm", + "pqa": "application/vnd.palm", + "oprc": "application/vnd.palm", + "paw": "application/vnd.pawaafile", + "str": "application/vnd.pg.format", + "ei6": "application/vnd.pg.osasli", + "efif": "application/vnd.picsel", + "wg": "application/vnd.pmi.widget", + "plf": "application/vnd.pocketlearn", + "pbd": "application/vnd.powerbuilder6", + "box": "application/vnd.previewsystems.box", + "mgz": "application/vnd.proteus.magazine", + "qps": "application/vnd.publishare-delta-tree", + "ptid": "application/vnd.pvi.ptid1", + "qxd": "application/vnd.quark.quarkxpress", + "qxt": "application/vnd.quark.quarkxpress", + "qwd": "application/vnd.quark.quarkxpress", + "qwt": "application/vnd.quark.quarkxpress", + "qxl": "application/vnd.quark.quarkxpress", + "qxb": "application/vnd.quark.quarkxpress", + "bed": "application/vnd.realvnc.bed", + "mxl": "application/vnd.recordare.musicxml", + "musicxml": "application/vnd.recordare.musicxml+xml", + "cryptonote": "application/vnd.rig.cryptonote", + "cod": "application/vnd.rim.cod", + "rm": "application/vnd.rn-realmedia", + "rmvb": "application/vnd.rn-realmedia-vbr", + "link66": "application/vnd.route66.link66+xml", + "st": "application/vnd.sailingtracker.track", + "see": "application/vnd.seemail", + "sema": "application/vnd.sema", + "semd": "application/vnd.semd", + "semf": "application/vnd.semf", + "ifm": "application/vnd.shana.informed.formdata", + "itp": "application/vnd.shana.informed.formtemplate", + "iif": "application/vnd.shana.informed.interchange", + "ipk": "application/vnd.shana.informed.package", + "twd": "application/vnd.simtech-mindmapper", + "twds": "application/vnd.simtech-mindmapper", + "mmf": "application/vnd.smaf", + "teacher": "application/vnd.smart.teacher", + "sdkm": "application/vnd.solent.sdkm+xml", + "sdkd": "application/vnd.solent.sdkm+xml", + "dxp": "application/vnd.spotfire.dxp", + "sfs": "application/vnd.spotfire.sfs", + "sdc": "application/vnd.stardivision.calc", + "sda": "application/vnd.stardivision.draw", + "sdd": "application/vnd.stardivision.impress", + "smf": "application/vnd.stardivision.math", + "sdw": "application/vnd.stardivision.writer", + "vor": "application/vnd.stardivision.writer", + "sgl": "application/vnd.stardivision.writer-global", + "smzip": "application/vnd.stepmania.package", + "sm": "application/vnd.stepmania.stepchart", + "sxc": "application/vnd.sun.xml.calc", + "stc": "application/vnd.sun.xml.calc.template", + "sxd": "application/vnd.sun.xml.draw", + "std": "application/vnd.sun.xml.draw.template", + "sxi": "application/vnd.sun.xml.impress", + "sti": "application/vnd.sun.xml.impress.template", + "sxm": "application/vnd.sun.xml.math", + "sxw": "application/vnd.sun.xml.writer", + "sxg": "application/vnd.sun.xml.writer.global", + "stw": "application/vnd.sun.xml.writer.template", + "sus": "application/vnd.sus-calendar", + "susp": "application/vnd.sus-calendar", + "svd": "application/vnd.svd", + "sis": "application/vnd.symbian.install", + "sisx": "application/vnd.symbian.install", + "xsm": "application/vnd.syncml+xml", + "bdm": "application/vnd.syncml.dm+wbxml", + "xdm": "application/vnd.syncml.dm+xml", + "tao": "application/vnd.tao.intent-module-archive", + "pcap": "application/vnd.tcpdump.pcap", + "cap": "application/vnd.tcpdump.pcap", + "dmp": "application/vnd.tcpdump.pcap", + "tmo": "application/vnd.tmobile-livetv", + "tpt": "application/vnd.trid.tpt", + "mxs": "application/vnd.triscape.mxs", + "tra": "application/vnd.trueapp", + "ufd": "application/vnd.ufdl", + "ufdl": "application/vnd.ufdl", + "utz": "application/vnd.uiq.theme", + "umj": "application/vnd.umajin", + "unityweb": "application/vnd.unity", + "uoml": "application/vnd.uoml+xml", + "vcx": "application/vnd.vcx", + "vsd": "application/vnd.visio", + "vst": "application/vnd.visio", + "vss": "application/vnd.visio", + "vsw": "application/vnd.visio", + "vis": "application/vnd.visionary", + "vsf": "application/vnd.vsf", + "wbxml": "application/vnd.wap.wbxml", + "wmlc": "application/vnd.wap.wmlc", + "wmlsc": "application/vnd.wap.wmlscriptc", + "wtb": "application/vnd.webturbo", + "nbp": "application/vnd.wolfram.player", + "wpd": "application/vnd.wordperfect", + "wqd": "application/vnd.wqd", + "stf": "application/vnd.wt.stf", + "xar": "application/vnd.xara", + "xfdl": "application/vnd.xfdl", + "hvd": "application/vnd.yamaha.hv-dic", + "hvs": "application/vnd.yamaha.hv-script", + "hvp": "application/vnd.yamaha.hv-voice", + "osf": "application/vnd.yamaha.openscoreformat", + "osfpvg": "application/vnd.yamaha.openscoreformat.osfpvg+xml", + "saf": "application/vnd.yamaha.smaf-audio", + "spf": "application/vnd.yamaha.smaf-phrase", + "cmp": "application/vnd.yellowriver-custom-menu", + "zir": "application/vnd.zul", + "zirz": "application/vnd.zul", + "zaz": "application/vnd.zzazz.deck+xml", + "vxml": "application/voicexml+xml", + "wgt": "application/widget", + "hlp": "application/winhlp", + "wsdl": "application/wsdl+xml", + "wspolicy": "application/wspolicy+xml", + "7z": "application/x-7z-compressed", + "abw": "application/x-abiword", + "ace": "application/x-ace-compressed", + "dmg": "application/x-apple-diskimage", + "aab": "application/x-authorware-bin", + "x32": "application/x-authorware-bin", + "u32": "application/x-authorware-bin", + "vox": "application/x-authorware-bin", + "aam": "application/x-authorware-map", + "aas": "application/x-authorware-seg", + "bcpio": "application/x-bcpio", + "torrent": "application/x-bittorrent", + "blb": "application/x-blorb", + "blorb": "application/x-blorb", + "bz": "application/x-bzip", + "bz2": "application/x-bzip2", + "boz": "application/x-bzip2", + "cbr": "application/x-cbr", + "cba": "application/x-cbr", + "cbt": "application/x-cbr", + "cbz": "application/x-cbr", + "cb7": "application/x-cbr", + "vcd": "application/x-cdlink", + "cfs": "application/x-cfs-compressed", + "chat": "application/x-chat", + "pgn": "application/x-chess-pgn", + "nsc": "application/x-conference", + "cpio": "application/x-cpio", + "csh": "application/x-csh", + "deb": "application/x-debian-package", + "udeb": "application/x-debian-package", + "dgc": "application/x-dgc-compressed", + "dir": "application/x-director", + "dcr": "application/x-director", + "dxr": "application/x-director", + "cst": "application/x-director", + "cct": "application/x-director", + "cxt": "application/x-director", + "w3d": "application/x-director", + "fgd": "application/x-director", + "swa": "application/x-director", + "wad": "application/x-doom", + "ncx": "application/x-dtbncx+xml", + "dtb": "application/x-dtbook+xml", + "res": "application/x-dtbresource+xml", + "dvi": "application/x-dvi", + "evy": "application/x-envoy", + "eva": "application/x-eva", + "bdf": "application/x-font-bdf", + "gsf": "application/x-font-ghostscript", + "psf": "application/x-font-linux-psf", + "pcf": "application/x-font-pcf", + "snf": "application/x-font-snf", + "pfa": "application/x-font-type1", + "pfb": "application/x-font-type1", + "pfm": "application/x-font-type1", + "afm": "application/x-font-type1", + "arc": "application/x-freearc", + "spl": "application/x-futuresplash", + "gca": "application/x-gca-compressed", + "ulx": "application/x-glulx", + "gnumeric": "application/x-gnumeric", + "gramps": "application/x-gramps-xml", + "gtar": "application/x-gtar", + "hdf": "application/x-hdf", + "install": "application/x-install-instructions", + "iso": "application/x-iso9660-image", + "jnlp": "application/x-java-jnlp-file", + "latex": "application/x-latex", + "lzh": "application/x-lzh-compressed", + "lha": "application/x-lzh-compressed", + "mie": "application/x-mie", + "prc": "application/x-mobipocket-ebook", + "mobi": "application/x-mobipocket-ebook", + "application": "application/x-ms-application", + "lnk": "application/x-ms-shortcut", + "wmd": "application/x-ms-wmd", + "wmz": "application/x-msmetafile", + "xbap": "application/x-ms-xbap", + "mdb": "application/x-msaccess", + "obd": "application/x-msbinder", + "crd": "application/x-mscardfile", + "clp": "application/x-msclip", + "exe": "application/x-msdownload", + "dll": "application/x-msdownload", + "com": "application/x-msdownload", + "bat": "application/x-msdownload", + "msi": "application/x-msdownload", + "mvb": "application/x-msmediaview", + "m13": "application/x-msmediaview", + "m14": "application/x-msmediaview", + "wmf": "application/x-msmetafile", + "emf": "application/x-msmetafile", + "emz": "application/x-msmetafile", + "mny": "application/x-msmoney", + "pub": "application/x-mspublisher", + "scd": "application/x-msschedule", + "trm": "application/x-msterminal", + "wri": "application/x-mswrite", + "nc": "application/x-netcdf", + "cdf": "application/x-netcdf", + "nzb": "application/x-nzb", + "p12": "application/x-pkcs12", + "pfx": "application/x-pkcs12", + "p7b": "application/x-pkcs7-certificates", + "spc": "application/x-pkcs7-certificates", + "p7r": "application/x-pkcs7-certreqresp", + "rar": "application/x-rar-compressed", + "ris": "application/x-research-info-systems", + "sh": "application/x-sh", + "shar": "application/x-shar", + "swf": "application/x-shockwave-flash", + "xap": "application/x-silverlight-app", + "sql": "application/x-sql", + "sit": "application/x-stuffit", + "sitx": "application/x-stuffitx", + "srt": "application/x-subrip", + "sv4cpio": "application/x-sv4cpio", + "sv4crc": "application/x-sv4crc", + "t3": "application/x-t3vm-image", + "gam": "application/x-tads", + "tar": "application/x-tar", + "tcl": "application/x-tcl", + "tex": "application/x-tex", + "tfm": "application/x-tex-tfm", + "texinfo": "application/x-texinfo", + "texi": "application/x-texinfo", + "obj": "application/x-tgif", + "ustar": "application/x-ustar", + "src": "application/x-wais-source", + "der": "application/x-x509-ca-cert", + "crt": "application/x-x509-ca-cert", + "fig": "application/x-xfig", + "xlf": "application/x-xliff+xml", + "xpi": "application/x-xpinstall", + "xz": "application/x-xz", + "z1": "application/x-zmachine", + "z2": "application/x-zmachine", + "z3": "application/x-zmachine", + "z4": "application/x-zmachine", + "z5": "application/x-zmachine", + "z6": "application/x-zmachine", + "z7": "application/x-zmachine", + "z8": "application/x-zmachine", + "xaml": "application/xaml+xml", + "xdf": "application/xcap-diff+xml", + "xenc": "application/xenc+xml", + "xhtml": "application/xhtml+xml", + "xht": "application/xhtml+xml", + "xml": "application/xml", + "xsl": "application/xml", + "dtd": "application/xml-dtd", + "xop": "application/xop+xml", + "xpl": "application/xproc+xml", + "xslt": "application/xslt+xml", + "xspf": "application/xspf+xml", + "mxml": "application/xv+xml", + "xhvml": "application/xv+xml", + "xvml": "application/xv+xml", + "xvm": "application/xv+xml", + "yang": "application/yang", + "yin": "application/yin+xml", + "zip": "application/zip", + "adp": "audio/adpcm", + "au": "audio/basic", + "snd": "audio/basic", + "mid": "audio/midi", + "midi": "audio/midi", + "kar": "audio/midi", + "rmi": "audio/midi", + "m4a": "audio/mp4", + "mp4a": "audio/mp4", + "mpga": "audio/mpeg", + "mp2": "audio/mpeg", + "mp2a": "audio/mpeg", + "mp3": "audio/mpeg", + "m2a": "audio/mpeg", + "m3a": "audio/mpeg", + "oga": "audio/ogg", + "ogg": "audio/ogg", + "spx": "audio/ogg", + "opus": "audio/ogg", + "s3m": "audio/s3m", + "sil": "audio/silk", + "uva": "audio/vnd.dece.audio", + "uvva": "audio/vnd.dece.audio", + "eol": "audio/vnd.digital-winds", + "dra": "audio/vnd.dra", + "dts": "audio/vnd.dts", + "dtshd": "audio/vnd.dts.hd", + "lvp": "audio/vnd.lucent.voice", + "pya": "audio/vnd.ms-playready.media.pya", + "ecelp4800": "audio/vnd.nuera.ecelp4800", + "ecelp7470": "audio/vnd.nuera.ecelp7470", + "ecelp9600": "audio/vnd.nuera.ecelp9600", + "rip": "audio/vnd.rip", + "weba": "audio/webm", + "aac": "audio/x-aac", + "aif": "audio/x-aiff", + "aiff": "audio/x-aiff", + "aifc": "audio/x-aiff", + "caf": "audio/x-caf", + "flac": "audio/x-flac", + "mka": "audio/x-matroska", + "m3u": "audio/x-mpegurl", + "wax": "audio/x-ms-wax", + "wma": "audio/x-ms-wma", + "ram": "audio/x-pn-realaudio", + "ra": "audio/x-pn-realaudio", + "rmp": "audio/x-pn-realaudio-plugin", + "wav": "audio/x-wav", + "xm": "audio/xm", + "cdx": "chemical/x-cdx", + "cif": "chemical/x-cif", + "cmdf": "chemical/x-cmdf", + "cml": "chemical/x-cml", + "csml": "chemical/x-csml", + "xyz": "chemical/x-xyz", + "ttc": "font/collection", + "otf": "font/otf", + "ttf": "font/ttf", + "woff": "font/woff", + "woff2": "font/woff2", + "bmp": "image/bmp", + "cgm": "image/cgm", + "g3": "image/g3fax", + "gif": "image/gif", + "ief": "image/ief", + "jpeg": "image/jpeg", + "jpg": "image/jpeg", + "jpe": "image/jpeg", + "ktx": "image/ktx", + "png": "image/png", + "btif": "image/prs.btif", + "sgi": "image/sgi", + "svg": "image/svg+xml", + "svgz": "image/svg+xml", + "tiff": "image/tiff", + "tif": "image/tiff", + "psd": "image/vnd.adobe.photoshop", + "uvi": "image/vnd.dece.graphic", + "uvvi": "image/vnd.dece.graphic", + "uvg": "image/vnd.dece.graphic", + "uvvg": "image/vnd.dece.graphic", + "djvu": "image/vnd.djvu", + "djv": "image/vnd.djvu", + "sub": "text/vnd.dvb.subtitle", + "dwg": "image/vnd.dwg", + "dxf": "image/vnd.dxf", + "fbs": "image/vnd.fastbidsheet", + "fpx": "image/vnd.fpx", + "fst": "image/vnd.fst", + "mmr": "image/vnd.fujixerox.edmics-mmr", + "rlc": "image/vnd.fujixerox.edmics-rlc", + "mdi": "image/vnd.ms-modi", + "wdp": "image/vnd.ms-photo", + "npx": "image/vnd.net-fpx", + "wbmp": "image/vnd.wap.wbmp", + "xif": "image/vnd.xiff", + "webp": "image/webp", + "3ds": "image/x-3ds", + "ras": "image/x-cmu-raster", + "cmx": "image/x-cmx", + "fh": "image/x-freehand", + "fhc": "image/x-freehand", + "fh4": "image/x-freehand", + "fh5": "image/x-freehand", + "fh7": "image/x-freehand", + "ico": "image/x-icon", + "sid": "image/x-mrsid-image", + "pcx": "image/x-pcx", + "pic": "image/x-pict", + "pct": "image/x-pict", + "pnm": "image/x-portable-anymap", + "pbm": "image/x-portable-bitmap", + "pgm": "image/x-portable-graymap", + "ppm": "image/x-portable-pixmap", + "rgb": "image/x-rgb", + "tga": "image/x-tga", + "xbm": "image/x-xbitmap", + "xpm": "image/x-xpixmap", + "xwd": "image/x-xwindowdump", + "eml": "message/rfc822", + "mime": "message/rfc822", + "igs": "model/iges", + "iges": "model/iges", + "msh": "model/mesh", + "mesh": "model/mesh", + "silo": "model/mesh", + "dae": "model/vnd.collada+xml", + "dwf": "model/vnd.dwf", + "gdl": "model/vnd.gdl", + "gtw": "model/vnd.gtw", + "mts": "model/vnd.mts", + "vtu": "model/vnd.vtu", + "wrl": "model/vrml", + "vrml": "model/vrml", + "x3db": "model/x3d+binary", + "x3dbz": "model/x3d+binary", + "x3dv": "model/x3d+vrml", + "x3dvz": "model/x3d+vrml", + "x3d": "model/x3d+xml", + "x3dz": "model/x3d+xml", + "appcache": "text/cache-manifest", + "ics": "text/calendar", + "ifb": "text/calendar", + "css": "text/css", + "csv": "text/csv", + "html": "text/html", + "htm": "text/html", + "n3": "text/n3", + "txt": "text/plain", + "text": "text/plain", + "conf": "text/plain", + "def": "text/plain", + "list": "text/plain", + "log": "text/plain", + "in": "text/plain", + "dsc": "text/prs.lines.tag", + "rtx": "text/richtext", + "sgml": "text/sgml", + "sgm": "text/sgml", + "tsv": "text/tab-separated-values", + "t": "text/troff", + "tr": "text/troff", + "roff": "text/troff", + "man": "text/troff", + "me": "text/troff", + "ms": "text/troff", + "ttl": "text/turtle", + "uri": "text/uri-list", + "uris": "text/uri-list", + "urls": "text/uri-list", + "vcard": "text/vcard", + "curl": "text/vnd.curl", + "dcurl": "text/vnd.curl.dcurl", + "mcurl": "text/vnd.curl.mcurl", + "scurl": "text/vnd.curl.scurl", + "fly": "text/vnd.fly", + "flx": "text/vnd.fmi.flexstor", + "gv": "text/vnd.graphviz", + "3dml": "text/vnd.in3d.3dml", + "spot": "text/vnd.in3d.spot", + "jad": "text/vnd.sun.j2me.app-descriptor", + "wml": "text/vnd.wap.wml", + "wmls": "text/vnd.wap.wmlscript", + "s": "text/x-asm", + "asm": "text/x-asm", + "c": "text/x-c", + "cc": "text/x-c", + "cxx": "text/x-c", + "cpp": "text/x-c", + "h": "text/x-c", + "hh": "text/x-c", + "dic": "text/x-c", + "f": "text/x-fortran", + "for": "text/x-fortran", + "f77": "text/x-fortran", + "f90": "text/x-fortran", + "java": "text/x-java-source", + "nfo": "text/x-nfo", + "opml": "text/x-opml", + "p": "text/x-pascal", + "pas": "text/x-pascal", + "etx": "text/x-setext", + "sfv": "text/x-sfv", + "uu": "text/x-uuencode", + "vcs": "text/x-vcalendar", + "vcf": "text/x-vcard", + "3gp": "video/3gpp", + "3g2": "video/3gpp2", + "h261": "video/h261", + "h263": "video/h263", + "h264": "video/h264", + "jpgv": "video/jpeg", + "jpm": "video/jpm", + "jpgm": "video/jpm", + "mj2": "video/mj2", + "mjp2": "video/mj2", + "mp4": "video/mp4", + "mp4v": "video/mp4", + "mpg4": "video/mp4", + "mpeg": "video/mpeg", + "mpg": "video/mpeg", + "mpe": "video/mpeg", + "m1v": "video/mpeg", + "m2v": "video/mpeg", + "ogv": "video/ogg", + "qt": "video/quicktime", + "mov": "video/quicktime", + "uvh": "video/vnd.dece.hd", + "uvvh": "video/vnd.dece.hd", + "uvm": "video/vnd.dece.mobile", + "uvvm": "video/vnd.dece.mobile", + "uvp": "video/vnd.dece.pd", + "uvvp": "video/vnd.dece.pd", + "uvs": "video/vnd.dece.sd", + "uvvs": "video/vnd.dece.sd", + "uvv": "video/vnd.dece.video", + "uvvv": "video/vnd.dece.video", + "dvb": "video/vnd.dvb.file", + "fvt": "video/vnd.fvt", + "mxu": "video/vnd.mpegurl", + "m4u": "video/vnd.mpegurl", + "pyv": "video/vnd.ms-playready.media.pyv", + "uvu": "video/vnd.uvvu.mp4", + "uvvu": "video/vnd.uvvu.mp4", + "viv": "video/vnd.vivo", + "webm": "video/webm", + "f4v": "video/x-f4v", + "fli": "video/x-fli", + "flv": "video/x-flv", + "m4v": "video/x-m4v", + "mkv": "video/x-matroska", + "mk3d": "video/x-matroska", + "mks": "video/x-matroska", + "mng": "video/x-mng", + "asf": "video/x-ms-asf", + "asx": "video/x-ms-asf", + "vob": "video/x-ms-vob", + "wm": "video/x-ms-wm", + "wmv": "video/x-ms-wmv", + "wmx": "video/x-ms-wmx", + "wvx": "video/x-ms-wvx", + "avi": "video/x-msvideo", + "movie": "video/x-sgi-movie", + "smv": "video/x-smv", + "ice": "x-conference/x-cooltalk" + }; + + static String? lookup(String path) { + assert(path.isNotEmpty); + var extension = _ext(path); + return extensionMap[extension]; + } + + static String _ext(String path) { + var index = path.lastIndexOf('.'); + if (index < 0 || index + 1 >= path.length) return path; + return path.substring(index + 1).toLowerCase(); + } +} \ No newline at end of file diff --git a/lib/src/platform_util.dart b/lib/src/platform_util.dart new file mode 100644 index 00000000..d79007f9 --- /dev/null +++ b/lib/src/platform_util.dart @@ -0,0 +1,38 @@ +import 'package:flutter/services.dart'; + +class PlatformUtil { + static PlatformUtil? _instance; + static const MethodChannel _channel = const MethodChannel( + 'com.pichillilorenzo/flutter_inappwebview_platformutil'); + + static PlatformUtil instance() { + return (_instance != null) ? _instance! : _init(); + } + + static PlatformUtil _init() { + _channel.setMethodCallHandler(_handleMethod); + _instance = PlatformUtil(); + return _instance!; + } + + static Future _handleMethod(MethodCall call) async {} + + String? _cachedSystemVersion; + Future getSystemVersion() async { + if (_cachedSystemVersion != null) { + return _cachedSystemVersion!; + } + Map args = {}; + _cachedSystemVersion = await _channel.invokeMethod('getSystemVersion', args); + return _cachedSystemVersion!; + } + + Future formatDate({required DateTime date, required String format, String locale = "en_US", String timezone = "UTC"}) async { + Map args = {}; + args.putIfAbsent('date', () => date.millisecondsSinceEpoch); + args.putIfAbsent('format', () => format); + args.putIfAbsent('locale', () => locale); + args.putIfAbsent('timezone', () => timezone); + return await _channel.invokeMethod('formatDate', args); + } +} diff --git a/lib/src/util.dart b/lib/src/util.dart index 07a7aad5..c6bfc3c1 100644 --- a/lib/src/util.dart +++ b/lib/src/util.dart @@ -1,7 +1,42 @@ import 'dart:math'; +import 'dart:typed_data'; import 'package:flutter/material.dart'; +class ViewIdGenerator { + static int _count = 0; + + /// Math.Random()-based RNG. All platforms, fast, not cryptographically strong. Optional Seed passable. + static Uint8List mathRNG({int seed = -1}) { + var b = Uint8List(16); + + var rand = (seed == -1) ? Random() : Random(seed); + + for (var i = 0; i < 16; i++) { + b[i] = rand.nextInt(256); + } + + (seed == -1) ? b.shuffle() : b.shuffle(Random(seed)); + + return b; + } + + /// Crypto-Strong RNG. All platforms, unknown speed, cryptographically strong (theoretically) + static Uint8List cryptoRNG() { + var b = Uint8List(16); + var rand = Random.secure(); + for (var i = 0; i < 16; i++) { + b[i] = rand.nextInt(256); + } + return b; + } + + static String generateId() { + _count++; + return _count.toString() + cryptoRNG().map((e) => e.toString()).join(''); + } +} + extension UtilColor on Color { static Color? fromStringRepresentation(String colorValue) { if (colorValue.startsWith("#")) { diff --git a/pubspec.yaml b/pubspec.yaml index 7a5c387f..8ca5d6cf 100755 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -10,10 +10,6 @@ environment: dependencies: flutter: sdk: flutter - uuid: ^3.0.0-nullsafety.1 - mime: ^1.0.0 - intl: ^0.17.0 - device_info: ^2.0.0-nullsafety.2 dev_dependencies: flutter_test: