├── ndll
├── Android
│ └── .gitignore
├── Linux
│ └── .gitignore
├── Linux64
│ └── .gitignore
├── Mac
│ └── .gitignore
├── Mac64
│ └── .gitignore
├── Windows
│ └── .gitignore
└── iPhone
│ ├── .gitignore
│ ├── libwebviewex.iphonesim.a.hash
│ ├── libwebviewex.iphoneos-64.a.hash
│ ├── libwebviewex.iphoneos-v7.a.hash
│ ├── libwebviewex.iphonesim-64.a.hash
│ ├── libwebviewex.iphoneos-64.a
│ ├── libwebviewex.iphoneos-v7.a
│ ├── libwebviewex.iphonesim.a
│ └── libwebviewex.iphonesim-64.a
├── .gitignore
├── install.sh
├── assets
├── extensions_webview_close_hdpi.png
├── extensions_webview_close_ldpi.png
├── extensions_webview_close_mdpi.png
└── extensions_webview_close_xhdpi.png
├── dependencies
└── webview
│ ├── project.properties
│ ├── res
│ ├── drawable-hdpi
│ │ └── close.png
│ ├── drawable-ldpi
│ │ └── close.png
│ ├── drawable-mdpi
│ │ └── close.png
│ ├── drawable-xhdpi
│ │ └── close.png
│ ├── layout
│ │ ├── activity_web_view_fullscreen.xml
│ │ └── activity_web_view_floating.xml
│ └── values
│ │ └── styles.xml
│ ├── build.xml
│ ├── AndroidManifest.xml
│ ├── build.gradle
│ └── src
│ └── extensions
│ └── webview
│ ├── WebViewExtension.java
│ └── WebViewActivity.java
├── project
├── include
│ └── WebViewEx.h
├── build.xml
├── common
│ └── ExternalInterface.cpp
└── ios
│ └── WebViewEx.mm
├── haxelib.json
├── include.xml
├── extension
└── webview
│ ├── AndroidCallbackHelper.hx
│ └── WebView.hx
├── LICENSE.md
└── README.md
/ndll/Android/.gitignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ndll/Linux/.gitignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ndll/Linux64/.gitignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ndll/Mac/.gitignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ndll/Mac64/.gitignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ndll/Windows/.gitignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ndll/iPhone/.gitignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ndll/iPhone/libwebviewex.iphonesim.a.hash:
--------------------------------------------------------------------------------
1 | 3039e97fb50f4aab24820fd7c0bbd11a
--------------------------------------------------------------------------------
/ndll/iPhone/libwebviewex.iphoneos-64.a.hash:
--------------------------------------------------------------------------------
1 | a3d37be92020118efc118446b7927307
--------------------------------------------------------------------------------
/ndll/iPhone/libwebviewex.iphoneos-v7.a.hash:
--------------------------------------------------------------------------------
1 | 1e7e9307ee35cfa6a3bbd8432872fa95
--------------------------------------------------------------------------------
/ndll/iPhone/libwebviewex.iphonesim-64.a.hash:
--------------------------------------------------------------------------------
1 | 0b25b90d3c22386bce4fcbeaed1972e8
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | project/obj
2 | *.zip
3 | *.sublime-project
4 | *.sublime-workspace
5 | *.DS_Store
--------------------------------------------------------------------------------
/install.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | dir=`dirname "$0"`
3 | cd "$dir"
4 | haxelib remove extension-webview
5 | haxelib local extension-webview.zip
6 |
--------------------------------------------------------------------------------
/ndll/iPhone/libwebviewex.iphoneos-64.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HaxeExtension/extension-webview/HEAD/ndll/iPhone/libwebviewex.iphoneos-64.a
--------------------------------------------------------------------------------
/ndll/iPhone/libwebviewex.iphoneos-v7.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HaxeExtension/extension-webview/HEAD/ndll/iPhone/libwebviewex.iphoneos-v7.a
--------------------------------------------------------------------------------
/ndll/iPhone/libwebviewex.iphonesim.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HaxeExtension/extension-webview/HEAD/ndll/iPhone/libwebviewex.iphonesim.a
--------------------------------------------------------------------------------
/assets/extensions_webview_close_hdpi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HaxeExtension/extension-webview/HEAD/assets/extensions_webview_close_hdpi.png
--------------------------------------------------------------------------------
/assets/extensions_webview_close_ldpi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HaxeExtension/extension-webview/HEAD/assets/extensions_webview_close_ldpi.png
--------------------------------------------------------------------------------
/assets/extensions_webview_close_mdpi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HaxeExtension/extension-webview/HEAD/assets/extensions_webview_close_mdpi.png
--------------------------------------------------------------------------------
/ndll/iPhone/libwebviewex.iphonesim-64.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HaxeExtension/extension-webview/HEAD/ndll/iPhone/libwebviewex.iphonesim-64.a
--------------------------------------------------------------------------------
/assets/extensions_webview_close_xhdpi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HaxeExtension/extension-webview/HEAD/assets/extensions_webview_close_xhdpi.png
--------------------------------------------------------------------------------
/dependencies/webview/project.properties:
--------------------------------------------------------------------------------
1 | android.library=true
2 | target=android-::ANDROID_TARGET_SDK_VERSION::
3 | android.library.reference.1=../extension-api
4 |
--------------------------------------------------------------------------------
/dependencies/webview/res/drawable-hdpi/close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HaxeExtension/extension-webview/HEAD/dependencies/webview/res/drawable-hdpi/close.png
--------------------------------------------------------------------------------
/dependencies/webview/res/drawable-ldpi/close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HaxeExtension/extension-webview/HEAD/dependencies/webview/res/drawable-ldpi/close.png
--------------------------------------------------------------------------------
/dependencies/webview/res/drawable-mdpi/close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HaxeExtension/extension-webview/HEAD/dependencies/webview/res/drawable-mdpi/close.png
--------------------------------------------------------------------------------
/dependencies/webview/res/drawable-xhdpi/close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HaxeExtension/extension-webview/HEAD/dependencies/webview/res/drawable-xhdpi/close.png
--------------------------------------------------------------------------------
/project/include/WebViewEx.h:
--------------------------------------------------------------------------------
1 | #ifndef WebViewEx
2 | #define WebViewEx
3 |
4 | namespace webviewex {
5 | void init(value _onDestroyedCallback, value _onURLChangingCallback, bool withPopup);
6 | void navigate(const char *url);
7 | void loadHtml(const char *html);
8 | void destroy();
9 | }
10 |
11 | #endif
--------------------------------------------------------------------------------
/dependencies/webview/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/haxelib.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "extension-webview",
3 | "url": "https://github.com/openfl/extension-webview",
4 | "license": "MIT",
5 | "contributors":["singmajesty","fbricker"],
6 | "tags": ["webview","api","android", "ios"],
7 | "description": "WebView / OpenFL extension for Android + iOS.",
8 | "version": "1.2.4",
9 | "releasenote": "Add gradle support"
10 | }
11 |
--------------------------------------------------------------------------------
/include.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/extension/webview/AndroidCallbackHelper.hx:
--------------------------------------------------------------------------------
1 | package extension.webview;
2 |
3 | class AndroidCallbackHelper {
4 |
5 | public function new() {
6 |
7 | }
8 |
9 | public function onClose() {
10 | if (WebView.onClose!=null) {
11 | WebView.onClose();
12 | }
13 | }
14 |
15 | public function onURLChanging(url : String) {
16 | if (WebView.onURLChanging!=null) {
17 | WebView.onURLChanging(url);
18 | }
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/dependencies/webview/res/layout/activity_web_view_fullscreen.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/dependencies/webview/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/dependencies/webview/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/dependencies/webview/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | maven {
4 | url "https://repo1.maven.org/maven2/"
5 | }
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.1.0'
9 | }
10 | }
11 |
12 | apply plugin: 'com.android.library'
13 |
14 | android {
15 | sourceSets {
16 | main {
17 | manifest.srcFile 'AndroidManifest.xml'
18 | java.srcDirs = ['src']
19 | res.srcDirs = ['res']
20 | }
21 | }
22 | compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION)
23 | buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION
24 | }
25 |
26 | dependencies {
27 | compile project(':deps:extension-api')
28 | }
29 |
--------------------------------------------------------------------------------
/project/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/dependencies/webview/res/layout/activity_web_view_floating.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
11 |
15 |
16 |
17 |
22 |
23 |
--------------------------------------------------------------------------------
/project/common/ExternalInterface.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "WebViewEx.h"
5 |
6 | using namespace webviewex;
7 |
8 | #ifdef HX_WINDOWS
9 | typedef wchar_t OSChar;
10 | #define val_os_string val_wstring
11 | #else
12 | typedef char OSChar;
13 | #define val_os_string val_string
14 | #endif
15 |
16 | extern "C" {
17 | int webviewex_register_prims(){
18 | return 0;
19 | }
20 | }
21 |
22 | void webviewAPIInit (value _onDestroyedCallback, value _onURLChangingCallback, value withPopup) { init(_onDestroyedCallback, _onURLChangingCallback, val_bool(withPopup)); }
23 | DEFINE_PRIM (webviewAPIInit, 3);
24 |
25 | void webviewAPINavigate (value url) { navigate(val_string(url)); }
26 | DEFINE_PRIM (webviewAPINavigate, 1);
27 |
28 | void webviewAPILoadHtml (value html) { loadHtml(val_string(html)); }
29 | DEFINE_PRIM (webviewAPILoadHtml, 1);
30 |
31 | void webviewAPIDestroy(){ destroy(); }
32 | DEFINE_PRIM (webviewAPIDestroy, 0);
33 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | License
2 | =======
3 |
4 | The MIT License (MIT)
5 |
6 | Copyright (c) 2013 SempaiGames (http://www.sempaigames.com)
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a copy
9 | of this software and associated documentation files (the "Software"), to deal
10 | in the Software without restriction, including without limitation the rights
11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | copies of the Software, and to permit persons to whom the Software is
13 | furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in
16 | all copies or substantial portions of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | THE SOFTWARE.
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # extension-webview
2 |
3 | A minimalistic OpenFL extension for displaying native WebViews on iOS and Android outputs.
4 |
5 | ### Main Features
6 |
7 | * Full-screen and Popup mode.
8 | * Popup mode has a close button on the top-left corner.
9 | * Whitelist validation (the webview will close if the user goes to a non-whitelisted URL).
10 | * Blacklist validation (the webview will close if the user goes to a blacklisted URL).
11 | * onClose event (Android and iOS).
12 | * onURLChanging events for controling the WebView (Android and iOS).
13 | * On non-supported platforms, this extensions has no effect (makes nothing).
14 |
15 | ### Simple use Example
16 |
17 | ```haxe
18 | // This example show a simple sharing of a text using the Share Class.
19 |
20 | import extension.webview.WebView;
21 |
22 | class SimpleExample {
23 | function new(){
24 | WebView.onClose=onClose;
25 | WebView.onURLChanging=onURLChanging;
26 | }
27 |
28 | function onClose(){
29 | trace("WebView has been closed!");
30 | }
31 |
32 | function onURLChanging(url:String){
33 | trace("WebView is about to open: "+url);
34 | }
35 |
36 | function shareStuff(){
37 | WebView.open('http://www.puralax.com/help',true);
38 |
39 | // Example using whitelist:
40 | // WebView.open('http://www.puralax.com/help',true,['(http|https)://www.puralax.com/help(.*)','http://www.sempaigames.com/(.*)']);
41 |
42 | // Example using blacklist:
43 | // WebView.open('http://www.puralax.com/help',true,null,['(http|https)://(.*)facebook.com(.*)']);
44 | }
45 | }
46 |
47 | ```
48 |
49 | ### How to Install
50 |
51 | ```bash
52 | haxelib install extension-webview
53 | ```
54 |
55 | ### Thanks to...
56 |
57 | The original iOS implementation is based on Suat Eyrice's extension NME WebView (https://github.com/SuatEyrice/NMEWebview).
58 |
59 | ### License
60 |
61 | The MIT License (MIT) - [LICENSE.md](LICENSE.md)
62 |
63 | Copyright © 2013 SempaiGames (http://www.sempaigames.com)
64 |
65 | Author: Matías Rossi && Federico Bricker
66 |
--------------------------------------------------------------------------------
/dependencies/webview/src/extensions/webview/WebViewExtension.java:
--------------------------------------------------------------------------------
1 | package extensions.webview;
2 |
3 | import android.util.Log;
4 | import android.content.Intent;
5 | import org.haxe.extension.Extension;
6 | import org.haxe.lime.HaxeObject;
7 | import org.json.JSONArray;
8 | import org.json.JSONException;
9 | import org.json.JSONObject;
10 |
11 | public class WebViewExtension extends Extension {
12 |
13 | public static final String EXTRA_URL = "extensions.webviewex.EXTRA_URL";
14 | public static final String EXTRA_HTML = "extensions.webviewex.EXTRA_HTML";
15 | public static final String EXTRA_FLOATING = "extensions.webviewex.EXTRA_FLOATING";
16 | public static final String EXTRA_URL_WHITELIST = "extensions.webviewex.EXTRA_URL_WHITELIST";
17 | public static final String EXTRA_URL_BLACKLIST = "extensions.webviewex.EXTRA_URL_BLACKLIST";
18 | public static final String EXTRA_USE_WIDE_PORT = "extensions.webviewex.EXTRA_USE_WIDE_PORT";
19 | public static final String EXTRA_MEDIA_PLAYBACK_REQUIRES_USER_GESTURE = "extensions.webviewex.EXTRA_MEDIA_PLAYBACK_REQUIRES_USER_GESTURE";
20 | public static boolean active = false;
21 |
22 | public static HaxeObject callback;
23 |
24 | public static void open(String json) {
25 |
26 | try {
27 |
28 | JSONObject obj = new JSONObject(json);
29 | String url = obj.getString("url");
30 | boolean floating = obj.getBoolean("floating");
31 |
32 | JSONArray jsonUrlWhitelist = obj.getJSONArray("urlWhitelist");
33 | String[] urlWhitelist = new String[jsonUrlWhitelist.length()];
34 | for (int i=0; i
2 | #include
3 | #include
4 |
5 | typedef void (*OnUrlChangingFunctionType)(NSString *);
6 | typedef void (*OnCloseClickedFunctionType)();
7 |
8 | @interface WebViewDelegate : NSObject
9 | @property (nonatomic) OnUrlChangingFunctionType onUrlChanging;
10 | @property (nonatomic) OnCloseClickedFunctionType onCloseClicked;
11 | @end
12 |
13 | @implementation WebViewDelegate
14 | @synthesize onUrlChanging;
15 | @synthesize onCloseClicked;
16 |
17 | - (void)webView:(WKWebView *)instance decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
18 | NSString *url = [navigationAction.request.URL query];
19 | onUrlChanging([[navigationAction.request URL] absoluteString]);
20 |
21 | decisionHandler(WKNavigationActionPolicyAllow);
22 | }
23 |
24 | - (void) onCloseButtonClicked:(UIButton *)closeButton {
25 | onCloseClicked();
26 | }
27 | @end
28 |
29 | namespace webviewex {
30 | WKWebView *instance;
31 | UIButton *closeButton;
32 | WebViewDelegate *webViewDelegate;
33 | AutoGCRoot *onDestroyedCallback = 0;
34 | AutoGCRoot *onURLChangingCallback = 0;
35 | void init(value, value, bool);
36 | void navigate(const char *);
37 | void destroy();
38 | void onUrlChanging(NSString *);
39 |
40 | void init(value _onDestroyedCallback, value _onURLChangingCallback, bool withPopup) {
41 | if(instance != nil) destroy();
42 |
43 | onDestroyedCallback = new AutoGCRoot(_onDestroyedCallback);
44 | onURLChangingCallback = new AutoGCRoot(_onURLChangingCallback);
45 |
46 | webViewDelegate = [[WebViewDelegate alloc] init];
47 | webViewDelegate.onUrlChanging = &onUrlChanging;
48 | webViewDelegate.onCloseClicked = &destroy;
49 |
50 | CGRect screen = [[UIScreen mainScreen] bounds];
51 | CGFloat screenScale = [[UIScreen mainScreen] scale];
52 |
53 | NSString *dpi = @"mdpi";
54 | int padding = 58;
55 |
56 | if(screenScale > 1.0) {
57 | dpi = @"xhdpi";
58 | padding = 59;
59 | }
60 |
61 | padding /= 4;
62 | if(!withPopup) padding = 0;
63 |
64 | WKWebViewConfiguration *webViewConfiguration = [[WKWebViewConfiguration alloc] init];
65 | webViewConfiguration.allowsInlineMediaPlayback = YES;
66 | webViewConfiguration.ignoresViewportScaleLimits = YES;
67 |
68 | instance = [[WKWebView alloc] initWithFrame:CGRectMake(padding, padding, screen.size.width - (padding * 2), screen.size.height - (padding * 2)) configuration: webViewConfiguration];
69 | [webViewConfiguration release];
70 |
71 | instance.navigationDelegate = webViewDelegate;
72 |
73 | [[[UIApplication sharedApplication] keyWindow] addSubview:instance];
74 |
75 | if (withPopup) {
76 | UIImage *closeImage = [[UIImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource: [NSString stringWithFormat:@"assets/assets/extensions_webview_close_%@.png", dpi] ofType: nil]];
77 | closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
78 | [closeButton setImage:closeImage forState:UIControlStateNormal];
79 | closeButton.adjustsImageWhenHighlighted = NO;
80 | closeButton.frame = CGRectMake(0, 0, padding*2, padding*2);
81 | [closeButton addTarget:webViewDelegate action:@selector(onCloseButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
82 | [[[UIApplication sharedApplication] keyWindow] addSubview:closeButton];
83 | }
84 | }
85 |
86 | void navigate (const char *url) {
87 | NSURL *_url = [[NSURL alloc] initWithString: [[NSString alloc] initWithUTF8String:url]];
88 | NSURLRequest *req = [[NSURLRequest alloc] initWithURL:_url];
89 | [instance loadRequest:req];
90 | }
91 |
92 | void loadHtml (const char *html){
93 | [instance loadHTMLString:[NSString stringWithUTF8String:html] baseURL: nil];
94 | }
95 |
96 | void destroy(){
97 | if(instance==nil) return;
98 | val_call0(onDestroyedCallback->get());
99 | [instance stopLoading];
100 | [instance removeFromSuperview];
101 | if(closeButton != nil) {
102 | [closeButton removeFromSuperview];
103 | }
104 | [instance release];
105 | instance=nil;
106 | }
107 |
108 | void onUrlChanging (NSString *url) {
109 | val_call1(onURLChangingCallback->get(), alloc_string([url cStringUsingEncoding:NSUTF8StringEncoding]));
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/extension/webview/WebView.hx:
--------------------------------------------------------------------------------
1 | package extension.webview;
2 |
3 | import haxe.Json;
4 | #if (openfl < "4.0.0")
5 | import openfl.utils.JNI;
6 | #else
7 | import lime.system.JNI;
8 | #end
9 |
10 | class WebView {
11 |
12 | private static var initialized :Bool = false;
13 |
14 | private static var APIInit:Dynamic=null;
15 | private static var APISetCallback:Dynamic=null;
16 | private static var APINavigate:Dynamic=null;
17 | private static var APIDestroy:Dynamic=null;
18 | private static var APILoadHtml:Dynamic=null;
19 |
20 | #if ios
21 | private static var listener:WebViewListener;
22 | #end
23 |
24 | #if android
25 | private static var _open :String -> Void = null;
26 | private static var _openHtml :String -> Void = null;
27 | #end
28 |
29 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
31 |
32 | public static var onClose:Void->Void=null;
33 | public static var onURLChanging:String->Void=null;
34 |
35 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
36 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
37 |
38 | public static function open (
39 | url: String = null,
40 | floating :Bool = false,
41 | ?urlWhitelist :Array,
42 | ?urlBlacklist :Array,
43 | ?useWideViewPort :Bool = false, // Android only
44 | ?mediaPlaybackRequiresUserGesture :Bool = true // Android only
45 | ) :Void {
46 | init();
47 | if(urlWhitelist!=null) urlWhitelist.push(url);
48 |
49 | #if android
50 | if (urlWhitelist==null) {
51 | urlWhitelist = [];
52 | }
53 | if (urlBlacklist==null) {
54 | urlBlacklist = [];
55 | }
56 | var obj = {
57 | url : url,
58 | floating : floating,
59 | urlWhitelist : urlWhitelist,
60 | urlBlacklist : urlBlacklist,
61 | useWideViewPort : useWideViewPort,
62 | mediaPlaybackRequiresUserGesture : mediaPlaybackRequiresUserGesture
63 | }
64 | _open(Json.stringify(obj));
65 | #elseif ios
66 | if (listener == null) listener = new WebViewListener(urlWhitelist, urlBlacklist);
67 | APICall("init", [listener, floating]);
68 | navigate(url);
69 | #end
70 | }
71 |
72 | public static function openHtml(
73 | html:String,
74 | floating:Bool=false,
75 | ?useWideViewPort :Bool = false, // Android only
76 | ?mediaPlaybackRequiresUserGesture :Bool = true // Android only
77 | ) :Void {
78 | init();
79 | #if android
80 | var obj = {
81 | html : html,
82 | floating : floating,
83 | useWideViewPort : useWideViewPort,
84 | mediaPlaybackRequiresUserGesture : mediaPlaybackRequiresUserGesture
85 | }
86 | _openHtml(Json.stringify(obj));
87 | #elseif ios
88 | if (listener == null) listener = new WebViewListener(null, null);
89 | APICall("init", [listener, floating]);
90 | APICall("loadHtml", [html]);
91 | #end
92 | }
93 |
94 | #if ios
95 | public static function navigate(url:String):Void {
96 | if (url==null) return;
97 | if (listener != null) APICall("navigate", [url]);
98 | }
99 |
100 | public static function close():Void {
101 | if (listener != null) APICall("destroy");
102 | }
103 | #end
104 |
105 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
106 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
107 |
108 | private static function init():Void {
109 | if(initialized == true) return;
110 | initialized = true;
111 | try {
112 | #if android
113 | _open = JNI.createStaticMethod("extensions/webview/WebViewExtension", "open", "(Ljava/lang/String;)V");
114 | _openHtml = JNI.createStaticMethod("extensions/webview/WebViewExtension", "openHtml", "(Ljava/lang/String;)V");
115 | var _callbackFunc = JNI.createStaticMethod("extensions/webview/WebViewExtension", "setCallback", "(Lorg/haxe/lime/HaxeObject;)V");
116 | _callbackFunc(new AndroidCallbackHelper());
117 |
118 | #elseif ios
119 | APIInit = cpp.Lib.load("webviewex","webviewAPIInit", 3);
120 | APINavigate = cpp.Lib.load("webviewex","webviewAPINavigate", 1);
121 | APILoadHtml = cpp.Lib.load("webviewex","webviewAPILoadHtml", 1);
122 | APIDestroy = cpp.Lib.load("webviewex","webviewAPIDestroy", 0);
123 | #end
124 |
125 | } catch(e:Dynamic) {
126 | trace("INIT Exception: "+e);
127 | }
128 | }
129 |
130 | private static function APICall(method:String, args:Array = null):Void {
131 | init();
132 | try{
133 | #if android
134 | if (method == "init") {
135 | try {
136 | APIInit(args[1] == true);
137 | } catch (e :Dynamic) {
138 | APIInit(args[1] == true);
139 | }
140 | }
141 | if (method == "callback") APISetCallback(args[0]);
142 | if (method == "navigate") APINavigate(args[0]);
143 | if (method == "destroy") APIDestroy();
144 | #elseif ios
145 | if (method == "init") APIInit(args[0].onClose, args[0].onURLChanging, args[1]);
146 | if (method == "navigate") APINavigate(args[0]);
147 | if (method == "loadHtml") APILoadHtml(args[0]);
148 | if (method == "destroy") APIDestroy();
149 | #end
150 | } catch(e:Dynamic) {
151 | trace("APICall Exception [" + method + ", " + args + "]: "+e);
152 | }
153 | }
154 |
155 | }
156 |
157 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
158 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
159 | #if ios
160 | class WebViewListener {
161 |
162 | public var urlWhitelist :Array;
163 | public var urlBlacklist :Array;
164 |
165 | public function new(urlWhitelist :Array, urlBlacklist :Array) {
166 | this.urlBlacklist=urlBlacklist;
167 | this.urlWhitelist=urlWhitelist;
168 | }
169 |
170 | public function onClose():Void {
171 | if(WebView.onClose!=null) WebView.onClose();
172 | }
173 |
174 | private function find(urls :Array, url:String):Bool{
175 | for(regex in urls){
176 | var r = new EReg(regex,"");
177 | if(r.match(url)) return true;
178 | }
179 | return false;
180 | }
181 |
182 | public function onURLChanging(url:Dynamic):Void {
183 | if(urlWhitelist!=null){
184 | if(!find(urlWhitelist,url)){
185 | WebView.close();
186 | return;
187 | }
188 | }
189 | if(urlBlacklist!=null){
190 | if(find(urlBlacklist,url)){
191 | WebView.close();
192 | return;
193 | }
194 | }
195 | if(WebView.onURLChanging!=null) WebView.onURLChanging(url);
196 | }
197 | }
198 | #end
199 |
--------------------------------------------------------------------------------
/dependencies/webview/src/extensions/webview/WebViewActivity.java:
--------------------------------------------------------------------------------
1 | package extensions.webview;
2 |
3 | import java.util.regex.PatternSyntaxException;
4 |
5 | import android.os.Bundle;
6 | import android.app.Activity;
7 | import android.content.res.Configuration;
8 | import android.util.Log;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.view.Window;
12 | import android.webkit.WebView;
13 | import android.webkit.WebSettings;
14 | import android.webkit.WebViewClient;
15 | import android.widget.FrameLayout;
16 | import org.haxe.lime.HaxeObject;
17 |
18 | public class WebViewActivity extends Activity {
19 |
20 | private static final String TAG = "WebViewActivity";
21 |
22 | protected FrameLayout webViewPlaceholder;
23 | protected WebView webView;
24 |
25 | protected String url;
26 | protected String html;
27 | protected boolean floating;
28 | protected String[] urlWhitelist;
29 | protected String[] urlBlacklist;
30 | protected boolean useWideViewPort;
31 | protected boolean mediaPlaybackRequiresUserGesture;
32 | protected HaxeObject callback;
33 |
34 | protected int layoutResource;
35 |
36 | @Override
37 | public void onCreate(Bundle savedInstanceState)
38 | {
39 | super.onCreate(savedInstanceState);
40 |
41 | // Load parameters from intent
42 | Bundle extras = getIntent().getExtras();
43 | url = extras.getString(WebViewExtension.EXTRA_URL, "about:blank");
44 | html = extras.getString(WebViewExtension.EXTRA_HTML, "null");
45 | floating = extras.getBoolean(WebViewExtension.EXTRA_FLOATING);
46 | urlWhitelist = extras.getStringArray(WebViewExtension.EXTRA_URL_WHITELIST);
47 | urlBlacklist = extras.getStringArray(WebViewExtension.EXTRA_URL_BLACKLIST);
48 | useWideViewPort = extras.getBoolean(WebViewExtension.EXTRA_USE_WIDE_PORT);
49 | mediaPlaybackRequiresUserGesture = extras.getBoolean(WebViewExtension.EXTRA_MEDIA_PLAYBACK_REQUIRES_USER_GESTURE);
50 | callback = WebViewExtension.callback;
51 |
52 | getWindow().requestFeature(Window.FEATURE_NO_TITLE);
53 |
54 | if (floating) {
55 | layoutResource = R.layout.activity_web_view_floating;
56 | } else {
57 | layoutResource = R.layout.activity_web_view_fullscreen;
58 | }
59 |
60 | // Initialize the UI
61 | initUI();
62 | }
63 |
64 | protected void initUI()
65 | {
66 | // Load layout from resources
67 | setContentView(layoutResource);
68 |
69 | // Retrieve UI elements
70 | webViewPlaceholder = ((FrameLayout)findViewById(R.id.webViewPlaceholder));
71 |
72 | // Initialize the WebView if necessary
73 | if (webView == null)
74 | {
75 | // Create the webview
76 | webView = new WebView(this);
77 | WebSettings webSettings = webView.getSettings();
78 | webSettings.setJavaScriptEnabled(true);
79 | webSettings.setDomStorageEnabled(true);
80 | webView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
81 | webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
82 | webView.setScrollbarFadingEnabled(true);
83 | webSettings.setLoadsImagesAutomatically(true);
84 |
85 | webSettings.setUseWideViewPort(useWideViewPort);
86 | if (android.os.Build.VERSION.SDK_INT>16) {
87 | //TODO: need to call this using reflection
88 | //webSettings.setMediaPlaybackRequiresUserGesture(mediaPlaybackRequiresUserGesture);
89 | }
90 |
91 | // Add the callback to handle new page loads
92 | webView.setWebViewClient(
93 |
94 | new WebViewClient() {
95 |
96 | @Override
97 | public boolean shouldOverrideUrlLoading (WebView view, String url) {
98 |
99 | Log.d(TAG, "shouldOverrideUrlLoading(): url = " + url);
100 |
101 | callback.call("onURLChanging", new Object[] {url});
102 |
103 | if (WebViewActivity.this.urlWhitelist == null) {
104 |
105 | Log.d(TAG, "urlWhitelist is null");
106 |
107 | } else if (WebViewActivity.this.urlWhitelist.length == 0) {
108 |
109 | Log.d(TAG, "urlWhitelist is empty");
110 |
111 | } else {
112 |
113 | boolean whitelisted = false;
114 |
115 | for (String whitelistedUrl : WebViewActivity.this.urlWhitelist) {
116 |
117 | try {
118 |
119 | if (url.matches(whitelistedUrl)) {
120 |
121 | Log.d(TAG, "URL matches with whitelist entry: '" + whitelistedUrl + "'.");
122 | whitelisted = true;
123 |
124 | }
125 |
126 | } catch (PatternSyntaxException ex) {
127 |
128 | Log.e(TAG, "Regular expression '" + whitelistedUrl + "' is not valid.");
129 |
130 | }
131 |
132 | }
133 |
134 | if (! whitelisted) {
135 |
136 | Log.d(TAG, "URL is not whitelisted. Closing view...");
137 | // call onClose( with args ) ???
138 | finish();
139 | return true;
140 |
141 | }
142 |
143 | }
144 |
145 | if (WebViewActivity.this.urlBlacklist == null) {
146 |
147 | Log.d(TAG, "urlBlacklist is null");
148 |
149 | } else for (String blacklistedUrl : WebViewActivity.this.urlBlacklist) {
150 |
151 | try {
152 |
153 | if (url.matches(blacklistedUrl)) {
154 |
155 | Log.d(TAG, "URL matches with blacklist entry: '" + blacklistedUrl + "'. Closing view...");
156 | // call onClose( with args ) ???
157 | finish();
158 | return true;
159 |
160 | }
161 |
162 | } catch (PatternSyntaxException ex) {
163 |
164 | Log.e(TAG, "Regular expression '" + blacklistedUrl + "' is not valid.");
165 |
166 | }
167 |
168 | }
169 |
170 | return false;
171 | }
172 |
173 | }
174 |
175 | );
176 |
177 | // Load the page
178 | callback.call("onURLChanging", new Object[] {url});
179 | if(url=="about:blank" && html!="null") webView.loadData(html, "text/html", null);
180 | else webView.loadUrl(url);
181 | }
182 |
183 | // Attach the WebView to its placeholder
184 | webViewPlaceholder.addView(webView);
185 | }
186 |
187 | @Override
188 | public void onConfigurationChanged(Configuration newConfig)
189 | {
190 |
191 | Log.d(TAG, "onConfigurationChanged (newConfig = " + newConfig.toString() + ")");
192 |
193 | if (webView != null)
194 | {
195 | // Remove the WebView from the old placeholder
196 | webViewPlaceholder.removeView(webView);
197 | }
198 |
199 | super.onConfigurationChanged(newConfig);
200 |
201 | // Reinitialize the UI
202 | initUI();
203 | }
204 |
205 | @Override
206 | protected void onSaveInstanceState(Bundle outState)
207 | {
208 | super.onSaveInstanceState(outState);
209 |
210 | // Save the state of the WebView
211 | webView.saveState(outState);
212 | }
213 |
214 | @Override
215 | protected void onRestoreInstanceState(Bundle savedInstanceState)
216 | {
217 | super.onRestoreInstanceState(savedInstanceState);
218 |
219 | // Restore the state of the WebView
220 | webView.restoreState(savedInstanceState);
221 | }
222 |
223 | @Override
224 | public void onBackPressed() {
225 | if (webView.canGoBack())
226 | webView.goBack();
227 | else
228 | super.onBackPressed();
229 | }
230 |
231 | public void onClosePressed(View view) {
232 | callback.call("onClose", new Object[] {});
233 | finish();
234 | }
235 |
236 | @Override
237 | public void finish(){
238 | super.finish();
239 | WebViewExtension.active=false;
240 | webView.clearHistory();
241 | webView.loadUrl("about:blank");
242 | webViewPlaceholder.removeView(webView);
243 | }
244 |
245 |
246 | }
247 |
--------------------------------------------------------------------------------