diff --git a/buildSrc/ios.gradle b/buildSrc/ios.gradle index edf17664361..831137ee70f 100644 --- a/buildSrc/ios.gradle +++ b/buildSrc/ios.gradle @@ -378,7 +378,7 @@ IOS.font.x86_64.linkFlags = ["-arch_only", archX86_64, "-syslibroot", sdkPath(iP IOS.font.x86_64.lib = "javafx_font_${archX86_64}" IOS.webview = [:] -IOS.webview.lib = "javafx_ios_webnode" +IOS.webview.lib = "webview" IOS.webview.javahInclude = ["javafx/scene/web/*"] IOS.webview.variants = ["arm", "arm64", "x86", "x86_64"]; @@ -388,7 +388,7 @@ IOS.webview.arm.compiler = compiler IOS.webview.arm.ccFlags = [ccFlags, "-arch", archArm, "-isysroot", sdkPath(iPhoneOS)].flatten() IOS.webview.arm.linker = linker IOS.webview.arm.linkFlags = ["-arch_only", archArm, "-syslibroot", sdkPath(iPhoneOS), linkFlags].flatten() -IOS.webview.arm.lib = "javafx_ios_webnode_${archArm}" +IOS.webview.arm.lib = "webview_${archArm}" IOS.webview.arm64 = [:] IOS.webview.arm64.nativeSource = file("${project("web").projectDir}/src/ios/native") @@ -396,7 +396,7 @@ IOS.webview.arm64.compiler = compiler IOS.webview.arm64.ccFlags = [ccFlags, "-arch", archArm64, "-isysroot", sdkPath(iPhoneOS)].flatten() IOS.webview.arm64.linker = linker IOS.webview.arm64.linkFlags = ["-arch_only", archArm64, "-syslibroot", sdkPath(iPhoneOS), linkFlags].flatten() -IOS.webview.arm64.lib = "javafx_ios_webnode_${archArm64}" +IOS.webview.arm64.lib = "webview_${archArm64}" IOS.webview.x86 = [:] IOS.webview.x86.nativeSource = [IOS.webview.arm.nativeSource].flatten() @@ -404,7 +404,7 @@ IOS.webview.x86.compiler = compiler IOS.webview.x86.ccFlags = [ccFlags, "-arch", archX86, "-isysroot", sdkPath(iPhoneSim)].flatten() IOS.webview.x86.linker = linker IOS.webview.x86.linkFlags = ["-arch_only", archX86, "-syslibroot", sdkPath(iPhoneSim), linkFlags].flatten() -IOS.webview.x86.lib = "javafx_ios_webnode_${archX86}" +IOS.webview.x86.lib = "webview_${archX86}" IOS.webview.x86_64 = [:] IOS.webview.x86_64.nativeSource = [IOS.webview.arm.nativeSource].flatten() @@ -412,7 +412,7 @@ IOS.webview.x86_64.compiler = compiler IOS.webview.x86_64.ccFlags = [ccFlags, "-arch", archX86_64, "-isysroot", sdkPath(iPhoneSim)].flatten() IOS.webview.x86_64.linker = linker IOS.webview.x86_64.linkFlags = ["-arch_only", archX86_64, "-syslibroot", sdkPath(iPhoneSim), linkFlags].flatten() -IOS.webview.x86_64.lib = "javafx_ios_webnode_${archX86_64}" +IOS.webview.x86_64.lib = "webview_${archX86_64}" IOS.media = [:] IOS.media.lib = "jfxmedia" diff --git a/modules/javafx.web/src/ios/java/com/sun/javafx/sg/prism/web/NGWebView.java b/modules/javafx.web/src/ios/java/com/sun/javafx/sg/prism/web/NGWebView.java new file mode 100644 index 00000000000..1c3026bc07c --- /dev/null +++ b/modules/javafx.web/src/ios/java/com/sun/javafx/sg/prism/web/NGWebView.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.javafx.sg.prism.web; + +import com.sun.javafx.geom.BaseBounds; +import com.sun.javafx.geom.RectBounds; +import com.sun.javafx.sg.prism.NGGroup; +import com.sun.prism.Graphics; + +public final class NGWebView extends NGGroup { + private volatile float width, height; + + public void resize(float w, float h) { + if (width != w || height != h) { + width = w; + height = h; + geometryChanged(); + } + } + + // Invoked on JavaFX User Thread. + public void update() { + } + + public void requestRender() { + visualsChanged(); + } + + private final RectBounds destBounds = new RectBounds(); + + @Override + protected void doRender(Graphics g) { + renderContent(g); + } + + @Override + public void setTransformedBounds(BaseBounds bounds, boolean byTransformChangeOnly) { + super.setTransformedBounds(bounds, byTransformChangeOnly); + } + + // Invoked on Render Thread. + @Override + protected void renderContent(Graphics g) { + if (g == null || width <= 0 || height <= 0) { + return; + } + g.getTransformNoClone().transform(transformedBounds, destBounds); + } + + @Override public boolean hasOverlappingContents() { + return false; + } + + @Override protected boolean hasVisuals() { + return true; + } +} diff --git a/modules/javafx.web/src/ios/java/javafx/scene/web/ExportedJavaObject.java b/modules/javafx.web/src/ios/java/javafx/scene/web/ExportedJavaObject.java index ae803ae9d27..26a715d91d6 100644 --- a/modules/javafx.web/src/ios/java/javafx/scene/web/ExportedJavaObject.java +++ b/modules/javafx.web/src/ios/java/javafx/scene/web/ExportedJavaObject.java @@ -256,7 +256,7 @@ private String callWorker(String methodName, String args) throws CallException { } private Method[] getPublicMethods(final Class clz) { - Method[] m = clz.getMethods(); + Method[] m = clz.getDeclaredMethods(); ArrayList am = new ArrayList(); for (int i = 0; i < m.length; i++) { if (Modifier.isPublic(m[i].getModifiers())){ diff --git a/modules/javafx.web/src/ios/java/javafx/scene/web/JS2JavaBridge.java b/modules/javafx.web/src/ios/java/javafx/scene/web/JS2JavaBridge.java index bcd52115997..765bb4ccc37 100644 --- a/modules/javafx.web/src/ios/java/javafx/scene/web/JS2JavaBridge.java +++ b/modules/javafx.web/src/ios/java/javafx/scene/web/JS2JavaBridge.java @@ -121,10 +121,10 @@ private void populateObject(String jsName, ExportedJavaObject jsObj) { sb = sb.append(getJavaBridge()).append(".exportJSObject(").append( getJavaBridge()).append("['").append(jsName).append("'])"); - Integer jsId = (Integer) webEngine.executeScript(sb.toString()); - if (jsId != null) { - exportedObjectsByJSIds.put(jsId.toString(), jsObj); - jsIdsByExportedObjects.put(jsObj, jsId.toString()); + String jsId = String.valueOf(webEngine.executeScript(sb.toString())); + if (!jsId.equals("null")) { + exportedObjectsByJSIds.put(jsId, jsObj); + jsIdsByExportedObjects.put(jsObj, jsId); } else { System.out.println("[JVDBG] Error, jsId = null for "+jsName); @@ -204,12 +204,14 @@ void populateJavaObjects() { @Override public void onLoadStarted() { - populateJavaObjects(); + objectIdCounter.set(0); + exportedObjectsByJavaObject.clear(); // TODO: free all unnamed ExportedJavaObjects } @Override public void onLoadFinished() { + populateJavaObjects(); } @Override diff --git a/modules/javafx.web/src/ios/java/javafx/scene/web/WebEngine.java b/modules/javafx.web/src/ios/java/javafx/scene/web/WebEngine.java index 7a1f15c3db1..b72a7408eae 100644 --- a/modules/javafx.web/src/ios/java/javafx/scene/web/WebEngine.java +++ b/modules/javafx.web/src/ios/java/javafx/scene/web/WebEngine.java @@ -562,18 +562,26 @@ public void loadContent(String content) { */ public void loadContent(String content, String contentType) { checkThread(); + LoadWorker lw = (LoadWorker) getLoadWorker(); + if (lw != null) { + lw.cancelAndReset(); + } _loadContent(view.get().getNativeHandle(), content); } /* Loads the given content directly */ private native void _loadContent(long handle, String content); + /* Reloads the current content directly */ + private native void _reload(long handle); + /** * Reloads the current page, whether loaded from URL or directly from a String in * one of the {@code loadContent} methods. */ public void reload() { checkThread(); + _reload(view.get().getNativeHandle()); } /** @@ -603,11 +611,12 @@ public Object executeScript(String script) { b.append(escapeScript(script)); b.append("')"); String retVal = _executeScript(view.get().getNativeHandle(), b.toString()); - - try { - return js2javaBridge.decode(retVal); - } catch (Exception ex) { - System.err.println("Couldn't parse arguments. " + ex); + if (retVal != null) { + try { + return js2javaBridge.decode(retVal); + } catch (Exception ex) { + System.err.println("Couldn't parse arguments. " + ex); + } } return null; } @@ -860,9 +869,9 @@ void setPageListener(PageListener listener) { updateState(Worker.State.SCHEDULED); updateState(Worker.State.RUNNING); pageListener.onLoadStarted(); + pageListener.onLoadFinished(); updateProgress(1.0); updateState(Worker.State.SUCCEEDED); - pageListener.onLoadFinished(); } } } @@ -894,7 +903,7 @@ Document getCurrentDocument () { document = builder.parse(new InputSource(new StringReader(pageContent))); } catch (Exception e) { - e.printStackTrace(); + System.err.println("Error parsing html: " + e.getLocalizedMessage()); } return document; } @@ -903,13 +912,13 @@ void notifyLoadFinished(String loc, String content) { synchronized (loadedLock) { this.pageContent = ""+content+""; loaded = true; - updateProgress(1.0); - updateState(Worker.State.SUCCEEDED); - location.set(loc); - document.invalidate(true); if (pageListener != null) { pageListener.onLoadFinished(); } + updateProgress(1.0); + location.set(loc); + document.invalidate(true); + updateState(Worker.State.SUCCEEDED); } } diff --git a/modules/javafx.web/src/ios/java/javafx/scene/web/WebView.java b/modules/javafx.web/src/ios/java/javafx/scene/web/WebView.java index 35c06a9325d..093c23bb133 100644 --- a/modules/javafx.web/src/ios/java/javafx/scene/web/WebView.java +++ b/modules/javafx.web/src/ios/java/javafx/scene/web/WebView.java @@ -26,6 +26,7 @@ package javafx.scene.web; +import javafx.application.Platform; import javafx.css.CssMetaData; import javafx.css.StyleableBooleanProperty; import javafx.css.StyleableDoubleProperty; @@ -45,6 +46,7 @@ import com.sun.java.scene.web.WebViewHelper; import com.sun.javafx.sg.prism.NGNode; +import com.sun.javafx.sg.prism.web.NGWebView; import com.sun.javafx.tk.TKPulseListener; import com.sun.javafx.tk.Toolkit; import java.util.ArrayList; @@ -103,9 +105,11 @@ public boolean doComputeContains(Node node, double localX, double localY) { @Override public void doPickNodeLocal(Node node, PickRay localPickRay, PickResultChooser result) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + // Not supported yet } }); + + System.loadLibrary("webview"); } private static final boolean DEFAULT_CONTEXT_MENU_ENABLED = true; @@ -122,6 +126,7 @@ public void doPickNodeLocal(Node node, PickRay localPickRay, PickResultChooser r private final WebEngine engine; // pointer to native WebViewImpl private final long handle; + private boolean nativeVisible = true; /** * The stage pulse listener registered with the toolkit. @@ -340,7 +345,7 @@ public void changed(ObservableValue observable, Bounds oldValu @Override public void changed(ObservableValue observable, Boolean oldValue, Boolean newValue) { - _setVisible(handle, newValue); + setNativeVisible(handle, newValue); } }); } @@ -1029,11 +1034,13 @@ && getScene().getWindow() != null if (reallyVisible) { if (NodeHelper.isDirty(this, DirtyBits.WEBVIEW_VIEW)) { SceneHelper.setAllowPGAccess(true); - //getPGWebView().update(); // creates new render queues + final NGWebView peer = NodeHelper.getPeer(this); + peer.update(); // creates new render queues SceneHelper.setAllowPGAccess(false); } + setNativeVisible(handle, true); } else { - _setVisible(handle, false); + setNativeVisible(handle, false); } } @@ -1042,13 +1049,16 @@ && getScene().getWindow() != null } // Node stuff + { + // To initialize the class helper at the beginning each constructor of this class + WebViewHelper.initHelper(this); + } /* * Note: This method MUST only be called via its accessor method. */ private NGNode doCreatePeer() { - // return new NGWebView(); - return null; // iOS doesn't need this method. + return new NGWebView(); } /* @@ -1072,13 +1082,13 @@ private boolean doComputeContains(double localX, double localY) { * Note: This method MUST only be called via its accessor method. */ private void doUpdatePeer() { - //PGWebView peer = getPGWebView(); + final NGWebView peer = NodeHelper.getPeer(this); if (NodeHelper.isDirty(this, DirtyBits.NODE_GEOMETRY)) { - //peer.resize((float)getWidth(), (float)getHeight()); + peer.resize((float)getWidth(), (float)getHeight()); } if (NodeHelper.isDirty(this, DirtyBits.WEBVIEW_VIEW)) { - //peer.requestRender(); + peer.requestRender(); } } @@ -1107,21 +1117,34 @@ long getNativeHandle() { return handle; } + private void setNativeVisible(long handle, boolean v) { + if (nativeVisible != v) { + nativeVisible = v; + _setVisible(handle, v); + } + } // native callbacks private void notifyLoadStarted() { - engine.notifyLoadStarted(); + checkThreadAndRun(engine::notifyLoadStarted); } private void notifyLoadFinished(String loc, String content) { - engine.notifyLoadFinished(loc, content); + checkThreadAndRun(() -> engine.notifyLoadFinished(loc, content)); } private void notifyLoadFailed() { - engine.notifyLoadFailed(); + checkThreadAndRun(engine::notifyLoadFailed); } private void notifyJavaCall(String arg) { - engine.notifyJavaCall(arg); + checkThreadAndRun(() -> engine.notifyJavaCall(arg)); } + private static void checkThreadAndRun(Runnable runnable) { + if (Platform.isFxApplicationThread()) { + runnable.run(); + } else { + Platform.runLater(runnable); + } + } /* Inits native WebView and returns its pointer in the given array */ private native void _initWebView(long[] nativeHandle); diff --git a/modules/javafx.web/src/ios/native/WebViewImpl.h b/modules/javafx.web/src/ios/native/WebViewImpl.h index 55d68ede241..0b2621b1f05 100644 --- a/modules/javafx.web/src/ios/native/WebViewImpl.h +++ b/modules/javafx.web/src/ios/native/WebViewImpl.h @@ -24,6 +24,7 @@ */ #import +#import #import #import @@ -37,13 +38,12 @@ #define ptr_to_jlong(a) ((jlong)(int)(a)) #endif -@interface WebViewImpl : NSObject { - UIWebView *webView; +@interface WebViewImpl : NSObject { + WKWebView *webView; UILabel *loadingLabel; CGFloat width; CGFloat height; CATransform3D transform; - NSString *jsResult; BOOL hidden; JavaVM *jvm; @@ -65,9 +65,9 @@ - (void)setHeight:(CGFloat)value; - (void)loadUrl:(NSString *)value; - (void)loadContent:(NSString *)content; +- (void)reload; - (void)executeScript:(NSString *)script; -- (NSString *)getScriptResult; -- (UIWebView *)getWebView; +- (WKWebView *)getWebView; - (UILabel *)getLoadingLabel; - (UIWindow *)getWindow; - (void) setFXTransform diff --git a/modules/javafx.web/src/ios/native/WebViewImpl.m b/modules/javafx.web/src/ios/native/WebViewImpl.m index 65fa66d7dce..ad76a464f5a 100644 --- a/modules/javafx.web/src/ios/native/WebViewImpl.m +++ b/modules/javafx.web/src/ios/native/WebViewImpl.m @@ -36,7 +36,7 @@ #define PATH_DELIMITER '/' -jint JNI_OnLoad_ios_webnode(JavaVM* vm, void * reserved) { +jint JNI_OnLoad_webview(JavaVM* vm, void * reserved) { #ifdef JNI_VERSION_1_8 //min. returned JNI_VERSION required by JDK8 for builtin libraries JNIEnv *env; @@ -53,10 +53,8 @@ jstring createJString(JNIEnv *env, NSString *nsStr) { if (nsStr == nil) { return NULL; } - jsize resLength = [nsStr length]; - jchar resBuffer[resLength]; - [nsStr getCharacters:(unichar *)resBuffer]; - return (*env)->NewString(env, resBuffer, resLength); + const char *cString = [nsStr UTF8String]; + return (*env)->NewStringUTF(env, cString); } @@ -95,12 +93,28 @@ - (void)loadContent:(NSString *)content { [webView loadHTMLString:content baseURL:nil]; } -- (void)executeScript:(NSString *) script { - jsResult = [webView stringByEvaluatingJavaScriptFromString:script]; +- (void)reload { + [webView reload]; } -- (NSString *)getScriptResult { - return jsResult; +- (void)executeScript:(NSMutableDictionary *) info { + __block NSString *resultString = nil; + __block BOOL finished = NO; + [webView evaluateJavaScript:[info objectForKey:@"Script"] completionHandler:^(id result, NSError *error) { + if (error == nil) { + if (result != nil) { + resultString = [NSString stringWithFormat:@"%@", result]; + } + } else { + NSLog(@"evaluateJavaScript error in executeScript: %@", error); + } + NSMutableDictionary *resultDictionary = [info objectForKey:@"ResultDictionary"]; + [resultDictionary setValue:resultString forKey:@"Result"]; + finished = YES; + }]; + while (!finished) { + [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; + } } - (WebViewImpl *)create:(JNIEnv *)env :(jobject)object { @@ -110,7 +124,6 @@ - (WebViewImpl *)create:(JNIEnv *)env :(jobject)object { jObject = (*env)->NewGlobalRef(env, object); jclass cls = (*env)->GetObjectClass(env, object); jmidLoadStarted = (*env)->GetMethodID(env, cls, "notifyLoadStarted", "()V"); - // jmidLoadFinished = (*env)->GetMethodID(env, cls, "notifyLoadFinished", "()V"); jmidLoadFinished = (*env)->GetMethodID(env, cls, "notifyLoadFinished", "(Ljava/lang/String;Ljava/lang/String;)V"); jmidLoadFailed = (*env)->GetMethodID(env, cls, "notifyLoadFailed", "()V"); jmidJavaCall = (*env)->GetMethodID(env, cls, "notifyJavaCall", "(Ljava/lang/String;)V"); @@ -132,9 +145,9 @@ - (void) initWebViewImpl { height = screenBounds.size.height; } - webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, width, height)]; + webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, width, height)]; webView.userInteractionEnabled = YES; - [webView setDelegate:self]; + webView.navigationDelegate = self; //[webView.layer setAnchorPoint:CGPointMake(0.0f, 0.0f)]; loadingLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, height/2, width, 40)]; @@ -143,6 +156,13 @@ - (void) initWebViewImpl { window = [self getWindow]; //known as mainWindow in glass windowView = [[window rootViewController] view]; //known as mainWindowHost in glass + + if (windowView) { + [windowView addSubview:webView]; + // [windowView addSubview:loadingLabel]; + } else { + NSLog(@"WebViewImpl ERROR: main Window is NIL"); + } } - (JNIEnv *)getJNIEnv { @@ -156,7 +176,7 @@ - (JNIEnv *)getJNIEnv { - (void)releaseJNIEnv:(JNIEnv *)env { } -- (UIWebView *)getWebView { +- (WKWebView *)getWebView { return webView; } @@ -174,7 +194,7 @@ - (UIWindow *)getWindow { } - (void) dealloc { - webView.delegate = nil; + webView.navigationDelegate = nil; [webView release]; [loadingLabel release]; JNIEnv *env = [self getJNIEnv]; @@ -185,9 +205,10 @@ - (void) dealloc { [super dealloc]; } -- (BOOL)webView:(UIWebView *)wv shouldStartLoadWithRequest:(NSURLRequest *)request - navigationType:(UIWebViewNavigationType)navigationType { - NSString *url = [[request URL] absoluteString]; +- (void)webView:(WKWebView *)wv decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction + decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { + + NSString *url = [navigationAction.request.URL absoluteString]; if ([url hasPrefix:JAVA_CALL_PREFIX]) { JNIEnv *env = [self getJNIEnv]; if (env != NULL) { @@ -196,13 +217,13 @@ - (BOOL)webView:(UIWebView *)wv shouldStartLoadWithRequest:(NSURLRequest *)reque (*env)->DeleteLocalRef(env, jUrl); [self releaseJNIEnv:env]; } - return NO; + decisionHandler(WKNavigationActionPolicyCancel); + } else { + decisionHandler(WKNavigationActionPolicyAllow); } - return YES; } -- (void)webViewDidStartLoad:(UIWebView *)webView{ - [windowView addSubview:loadingLabel]; +- (void)webView:(WKWebView *)wv didStartProvisionalNavigation:(WKNavigation *)navigation { loadingLabel.hidden = hidden; [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; @@ -213,29 +234,30 @@ - (void)webViewDidStartLoad:(UIWebView *)webView{ } } -- (void)webViewDidFinishLoad:(UIWebView *)wv{ - NSString *inner = [wv stringByEvaluatingJavaScriptFromString: - @"document.documentElement.innerHTML"]; - NSString *currentUrl = wv.request.URL.absoluteString; - +- (void)webView:(WKWebView *)wv didFinishNavigation:(WKNavigation *)navigation { loadingLabel.hidden = YES; [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; - if (windowView) { - [windowView addSubview:wv]; - } else { - NSLog(@"WebViewImpl ERROR: main Window is NIL"); - } - - JNIEnv *env = [self getJNIEnv]; - if (env != NULL) { - jstring jInner = createJString(env, inner); - jstring jUrl = createJString(env, currentUrl); - (*env)->CallVoidMethod(env, jObject, jmidLoadFinished, jUrl, jInner); - [self releaseJNIEnv:env]; - } + __block NSString *resultString = nil; + [wv evaluateJavaScript:@"document.documentElement.innerHTML" completionHandler:^(id result, NSError *error) { + if (error == nil) { + if (result != nil) { + resultString = [NSString stringWithFormat:@"%@", result]; + } + JNIEnv *env = [self getJNIEnv]; + if (env != NULL) { + jstring jInner = createJString(env, resultString); + NSString *currentUrl = [wv.URL absoluteString]; + jstring jUrl = createJString(env, currentUrl); + (*env)->CallVoidMethod(env, jObject, jmidLoadFinished, jUrl, jInner); + [self releaseJNIEnv:env]; + } + } else { + NSLog(@"evaluateJavaScript error in didFinishNavigation: %@", error); + } + }]; } -- (void)webView:(UIWebView *)wv didFailLoadWithError:(NSError *)error { +- (void)webView:(WKWebView *)wv didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error { NSLog(@"WebViewImpl ERROR: didFailLoadWithError"); NSLog(@" this error => %@ ", [error userInfo] ); JNIEnv *env = [self getJNIEnv]; @@ -247,13 +269,16 @@ - (void)webView:(UIWebView *)wv didFailLoadWithError:(NSError *)error { - (void) updateWebView { CGRect bounds = webView.bounds; + bounds.origin = CGPointMake(transform.m41, transform.m42); bounds.size.width = width; bounds.size.height = height; - CGPoint center = CGPointMake(/*transform.m41 +*/ width/2, /* transform.m42 +*/ height/2); - [webView setCenter:center]; - [webView setBounds:bounds]; - [loadingLabel setCenter:center]; - [loadingLabel setBounds:bounds]; + [webView setFrame:bounds]; +// [loadingLabel setCenter:center]; +// [loadingLabel setBounds:bounds]; + // add subview again if is not present + if (![webView isDescendantOfView:windowView]) { + [windowView addSubview:webView]; + } } - (void) updateTransform { @@ -477,6 +502,19 @@ unsigned int lastIndexOf(char searchChar,NSString * string) { } } + /* + * Class: javafx_scene_web_WebEngine + * Method: _reload + * Signature: (J)V + */ + JNIEXPORT void JNICALL + Java_javafx_scene_web_WebEngine__1reload(JNIEnv *env, jobject cl, jlong handle) { + WebViewImpl *wvi = jlong_to_ptr(handle); + if (wvi) { + [wvi reload]; + } + } + /* * Class: javafx_scene_web_WebEngine * Method: _executeScript @@ -485,7 +523,7 @@ unsigned int lastIndexOf(char searchChar,NSString * string) { JNIEXPORT jstring JNICALL Java_javafx_scene_web_WebEngine__1executeScript(JNIEnv *env, jobject cl, jlong handle, jstring script) { NSString *string = @""; - if (script!= NULL) + if (script != NULL) { const jchar* jstrChars = (*env)->GetStringChars(env, script, NULL); string = [[[NSString alloc] initWithCharacters: jstrChars length: (*env)->GetStringLength(env, script)] autorelease]; @@ -494,9 +532,12 @@ unsigned int lastIndexOf(char searchChar,NSString * string) { WebViewImpl *wvi = jlong_to_ptr(handle); if (wvi) { - [wvi performSelectorOnMainThread:@selector(executeScript:) withObject:string waitUntilDone:YES]; + NSMutableDictionary *resultDictionary = [NSMutableDictionary dictionaryWithCapacity:1]; + NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys: + resultDictionary, @"ResultDictionary", string, @"Script", nil]; + [wvi performSelectorOnMainThread:@selector(executeScript:) withObject:info waitUntilDone:YES]; - NSString *result = [wvi getScriptResult]; + NSString *result = [resultDictionary objectForKey:@"Result"]; if (result != nil) { jsize resLength = [result length]; diff --git a/modules/javafx.web/src/ios/resources/javafx/scene/web/init.js b/modules/javafx.web/src/ios/resources/javafx/scene/web/init.js index aaa9608681d..cef29c7acc0 100644 --- a/modules/javafx.web/src/ios/resources/javafx/scene/web/init.js +++ b/modules/javafx.web/src/ios/resources/javafx/scene/web/init.js @@ -39,7 +39,10 @@ var JavaBridge = { }, call: function(method, args) { var cbId = cbId = ++JavaBridge.callbackCnt; - JavaBridge.callbacks[cbId] = {'success': false, 'result': null}; + // TODO: set 'success': false, and process callBack, but so far it happens + // too late. As an alternative, use JSObject::call to send values from the + // Java class back to JavaScript. + JavaBridge.callbacks[cbId] = {'success': true, 'result': null}; if (args !== null && args instanceof Array) {//we always encode args as an Array ... for (var i = 0; i < args.length; i++) {