diff --git a/.travis.yml b/.travis.yml index 6ee9b0d..8fff2a5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,9 +23,9 @@ deploy: provider: releases api_key: $GH_TOKEN file: - - /home/travis/build/CodeBrig/Journey/build/libs/journey-browser-0.3.3.jar - - /home/travis/build/CodeBrig/Journey/jcef/binary_distrib/jcef-distrib-linux64.zip - - /Users/travis/build/CodeBrig/Journey/jcef/binary_distrib/jcef-distrib-macintosh64.zip + - "$TRAVIS_BUILD_DIR/build/libs/journey-browser-0.4.0.jar" + - "$TRAVIS_BUILD_DIR/jcef/binary_distrib/jcef-distrib-linux64.zip" + - "$TRAVIS_BUILD_DIR/jcef/binary_distrib/jcef-distrib-macintosh64.zip" skip_cleanup: true on: tags: true diff --git a/README.md b/README.md index 3d9b13c..8f57763 100644 --- a/README.md +++ b/README.md @@ -26,10 +26,10 @@ repositories { } dependencies { - compile 'com.github.codebrig:journey:0.3.3-online' + compile 'com.github.codebrig:journey:0.4.0-online' //or use the offline version (includes native CEF files for all platforms; ~300MB) - //compile 'com.github.codebrig:journey:0.3.3-offline' + //compile 'com.github.codebrig:journey:0.4.0-offline' } ``` @@ -46,10 +46,10 @@ dependencies { com.github.codebrig journey - 0.3.3-online + 0.4.0-online - + ``` @@ -92,7 +92,7 @@ public class JourneyBrowser { ### Linux (64bit) ```sh -curl -L -O https://github.com/CodeBrig/Journey/releases/download/0.3.3-75-assets/jcef-distrib-linux64.zip +curl -L -O https://github.com/CodeBrig/Journey/releases/download/0.4.0-78-assets/jcef-distrib-linux64.zip unzip jcef-distrib-linux64.zip export LD_LIBRARY_PATH=/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64:$(pwd)/linux64/bin/lib/linux64 @@ -101,7 +101,7 @@ java -cp "linux64/bin/*" tests.detailed.MainFrame ### macOS (64bit) ```sh -curl -L -O https://github.com/CodeBrig/Journey/releases/download/0.3.3-69-assets/jcef-distrib-macintosh64.zip +curl -L -O https://github.com/CodeBrig/Journey/releases/download/0.4.0-69-assets/jcef-distrib-macintosh64.zip unzip jcef-distrib-macintosh64.zip mv ./macosx64/bin/jcef_app.app . @@ -114,7 +114,7 @@ java -cp "$JAVA_PATH:$JAVA_PATH/*" -Djava.library.path=$JAVA_PATH tests.detailed ### Windows (64bit) [PowerShell] ``` [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -wget https://github.com/CodeBrig/Journey/releases/download/0.3.3-75-assets/jcef-distrib-windows64.zip -OutFile jcef-distrib-windows64.zip +wget https://github.com/CodeBrig/Journey/releases/download/0.4.0-78-assets/jcef-distrib-windows64.zip -OutFile jcef-distrib-windows64.zip Expand-Archive jcef-distrib-windows64.zip . java -cp "./win64/bin;./win64/bin/*" "-Djava.library.path=./win64/bin/lib/win64" tests.detailed.MainFrame @@ -124,6 +124,7 @@ java -cp "./win64/bin;./win64/bin/*" "-Djava.library.path=./win64/bin/lib/win64" | Journey Version | JCEF Version (Linux) | JCEF Version (macOS) | JCEF Version (Windows) | |---------------------|----------------------|----------------------|----------------------| +| 0.4.0 (2019-11-30) | [78.2.7.237](https://bitbucket.org/chromiumembedded/java-cef/commits/1e3a9146226d3df8a7f0c9c03989d220ac26ca49) (2019-11-14) | [69.0.3497.100](https://bitbucket.org/chromiumembedded/java-cef/commits/235e3a844380b72761643324e1d9b7713cae3b63) (2018-11-01) | [78.2.7.237](https://bitbucket.org/chromiumembedded/java-cef/commits/1e3a9146226d3df8a7f0c9c03989d220ac26ca49) (2019-11-14) | | 0.3.3 (2019-07-13) | [75.0.13.220](https://bitbucket.org/chromiumembedded/java-cef/commits/13ae2d6074bc00a31888fb752dd45f9cf254725d) (2019-07-09) | [69.0.3497.100](https://bitbucket.org/chromiumembedded/java-cef/commits/235e3a844380b72761643324e1d9b7713cae3b63) (2018-11-01) | [75.0.13.220](https://bitbucket.org/chromiumembedded/java-cef/commits/13ae2d6074bc00a31888fb752dd45f9cf254725d) (2019-07-09) | | 0.2.18 (2019-06-30)
0.2.17 (2019-06-12) | [73.1.11.216](https://bitbucket.org/chromiumembedded/java-cef/commits/6b140efeef4e566b6a68025b1dcea9b2da6e6e57) (2019-05-21) | [69.0.3497.100](https://bitbucket.org/chromiumembedded/java-cef/commits/235e3a844380b72761643324e1d9b7713cae3b63) (2018-11-01) | [73.1.11.216](https://bitbucket.org/chromiumembedded/java-cef/commits/6b140efeef4e566b6a68025b1dcea9b2da6e6e57) (2019-05-21) | | 0.2.16 (2019-06-10) | [73.1.11.215](https://bitbucket.org/chromiumembedded/java-cef/commits/d348788e3347fa4d2a421773463f7dd62da60991) (2019-05-10) | [69.0.3497.100](https://bitbucket.org/chromiumembedded/java-cef/commits/235e3a844380b72761643324e1d9b7713cae3b63) (2018-11-01) | [73.1.11.215](https://bitbucket.org/chromiumembedded/java-cef/commits/d348788e3347fa4d2a421773463f7dd62da60991) (2019-05-10) | diff --git a/build.gradle b/build.gradle index 99488a3..a1cf879 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'java' +version '0.4.0' group 'com.codebrig' -version '0.3.3' sourceCompatibility = 1.8 archivesBaseName = 'journey-browser' @@ -13,13 +13,15 @@ ext { '67': '67.0.3396.62', '69': '69.0.3497.100', '73': '73.1.11.216', - '75': '75.0.13.220' + '75': '75.0.13.220', + '78': '78.2.7.237' ] jcefCommit = [ '67': '1fda5d8f948670d08ef86bc4e8637b8581995ce9', '69': '235e3a844380b72761643324e1d9b7713cae3b63', '73': '6b140efeef4e566b6a68025b1dcea9b2da6e6e57', - '75': '13ae2d6074bc00a31888fb752dd45f9cf254725d' + '75': '13ae2d6074bc00a31888fb752dd45f9cf254725d', + '78': '1e3a9146226d3df8a7f0c9c03989d220ac26ca49' ] } @@ -71,7 +73,7 @@ jar { } task initEnvironment { - def chromiumMajorVersion = "75" + def chromiumMajorVersion = "78" if (System.getenv("TRAVIS_OS_NAME") == "osx") { chromiumMajorVersion = "73" } @@ -151,7 +153,7 @@ task patchJCEF { task checkoutJCEF { doFirst { - def chromiumMajorVersion = "75" + def chromiumMajorVersion = "78" if (System.getenv("TRAVIS_OS_NAME") == "osx") { chromiumMajorVersion = "73" } diff --git a/src/main/java/com/codebrig/journey/JourneyBrowserView.java b/src/main/java/com/codebrig/journey/JourneyBrowserView.java index e409e1e..c1dcd6f 100644 --- a/src/main/java/com/codebrig/journey/JourneyBrowserView.java +++ b/src/main/java/com/codebrig/journey/JourneyBrowserView.java @@ -20,10 +20,10 @@ * Wraps CefApp/CefClient/CefBrowser and extends JComponent for ease of implementation. * * @author Brandon Fergerson - * @version 0.3.3 + * @version 0.4.0 * @since 0.1.1 */ -@SuppressWarnings({"JavaReflectionInvocation", "WeakerAccess"}) +@SuppressWarnings({"WeakerAccess", "unused"}) public class JourneyBrowserView extends JComponent { public static final String ABOUT_BLANK = "about:blank"; diff --git a/src/main/java/com/codebrig/journey/JourneyLoader.java b/src/main/java/com/codebrig/journey/JourneyLoader.java index 4db40cb..8b963e3 100644 --- a/src/main/java/com/codebrig/journey/JourneyLoader.java +++ b/src/main/java/com/codebrig/journey/JourneyLoader.java @@ -20,7 +20,7 @@ * Downloads and loads the necessary CEF files for the current OS. * * @author Brandon Fergerson - * @version 0.3.3 + * @version 0.4.0 * @since 0.1.1 */ @SuppressWarnings({"WeakerAccess", "unused", "JavaReflectionMemberAccess"}) @@ -32,7 +32,7 @@ public class JourneyLoader extends URLClassLoader { public static final String PROJECT_URL = BUILD.getString("project_url"); public static File NATIVE_DIRECTORY = new File((System.getProperty("os.name").toLowerCase().startsWith("mac")) ? "/tmp" : System.getProperty("java.io.tmpdir"), - "journey-" + (System.getProperty("os.name").toLowerCase().startsWith("mac") ? "69" : "75")); + "journey-" + (System.getProperty("os.name").toLowerCase().startsWith("mac") ? "69" : "78")); private static JourneyLoader JOURNEY_CLASS_LOADER; private static JourneyLoaderListener JOURNEY_LOADER_LISTENER = new JourneyLoaderAdapter() { @@ -58,7 +58,7 @@ public static void setup() throws RuntimeException { if (System.getProperty("os.name").toLowerCase().startsWith("mac")) { jcefVersion = "69.0.3497.100"; } else { - jcefVersion = "75.0.13.220"; + jcefVersion = "78.2.7.237"; } JOURNEY_LOADER_LISTENER.journeyLoaderStarted(VERSION, jcefVersion); if (!NATIVE_DIRECTORY.exists()) NATIVE_DIRECTORY.mkdirs(); diff --git a/src/main/java/com/codebrig/journey/JourneySettings.java b/src/main/java/com/codebrig/journey/JourneySettings.java index 5efe8ea..0bdfff5 100644 --- a/src/main/java/com/codebrig/journey/JourneySettings.java +++ b/src/main/java/com/codebrig/journey/JourneySettings.java @@ -7,10 +7,10 @@ * Note: This doesn't use a real proxy because CefSettings exposes configuration through fields instead of methods. * * @author Brandon Fergerson - * @version 0.3.3 + * @version 0.4.0 * @since 0.2.0 */ -@SuppressWarnings("WeakerAccess") +@SuppressWarnings({"WeakerAccess", "unused"}) public class JourneySettings { public static Class CEF_SETTINGS_CLASS = JourneyLoader.getJourneyClassLoader().loadClass("org.cef.CefSettings"); @@ -210,15 +210,12 @@ public void setIgnoreCertificateErrors(boolean ignore_certificate_errors) { // } // } - public static enum LogSeverity { + public enum LogSeverity { LOGSEVERITY_DEFAULT, LOGSEVERITY_VERBOSE, LOGSEVERITY_INFO, LOGSEVERITY_WARNING, LOGSEVERITY_ERROR, LOGSEVERITY_DISABLE; - - private LogSeverity() { - } } } diff --git a/src/main/java/com/codebrig/journey/proxy/CefAppProxy.java b/src/main/java/com/codebrig/journey/proxy/CefAppProxy.java index 8d449d7..653f1ef 100644 --- a/src/main/java/com/codebrig/journey/proxy/CefAppProxy.java +++ b/src/main/java/com/codebrig/journey/proxy/CefAppProxy.java @@ -8,7 +8,7 @@ * Javadoc taken from: https://bitbucket.org/chromiumembedded/java-cef * * @author Brandon Fergerson - * @version 0.3.3 + * @version 0.4.0 * @since 0.2.0 */ @SuppressWarnings("unused") diff --git a/src/main/java/com/codebrig/journey/proxy/CefBrowserProxy.java b/src/main/java/com/codebrig/journey/proxy/CefBrowserProxy.java index afdb460..31995e9 100644 --- a/src/main/java/com/codebrig/journey/proxy/CefBrowserProxy.java +++ b/src/main/java/com/codebrig/journey/proxy/CefBrowserProxy.java @@ -11,7 +11,7 @@ * Javadoc taken from: https://bitbucket.org/chromiumembedded/java-cef * * @author Brandon Fergerson - * @version 0.3.3 + * @version 0.4.0 * @since 0.2.0 */ @SuppressWarnings("unused") diff --git a/src/main/java/com/codebrig/journey/proxy/CefClientProxy.java b/src/main/java/com/codebrig/journey/proxy/CefClientProxy.java index 60e0e6b..cffc58f 100644 --- a/src/main/java/com/codebrig/journey/proxy/CefClientProxy.java +++ b/src/main/java/com/codebrig/journey/proxy/CefClientProxy.java @@ -1,5 +1,7 @@ package com.codebrig.journey.proxy; +import com.codebrig.journey.proxy.browser.CefMessageRouterProxy; +import com.codebrig.journey.proxy.handler.CefJSDialogHandlerProxy; import com.codebrig.journey.proxy.handler.CefLifeSpanHandlerProxy; import org.joor.Reflect; @@ -11,7 +13,7 @@ * Javadoc taken from: https://bitbucket.org/chromiumembedded/java-cef * * @author Brandon Fergerson - * @version 0.3.3 + * @version 0.4.0 * @since 0.2.0 */ @SuppressWarnings("unused") @@ -20,6 +22,10 @@ public interface CefClientProxy extends Reflect.ProxyObject { Reflect.ProxyArgumentsConverter PROXY_ARGUMENTS_CONVERTER = (methodName, args) -> { if ("addLifeSpanHandler".equals(methodName)) { args[0] = ((Reflect.ProxyInvocationHandler) Proxy.getInvocationHandler(args[0])).getUnderlyingObject(); + } else if ("addJSDialogHandler".equals(methodName)) { + args[0] = ((Reflect.ProxyInvocationHandler) Proxy.getInvocationHandler(args[0])).getUnderlyingObject(); + } else if ("addMessageRouter".equals(methodName)) { + args[0] = ((Reflect.ProxyInvocationHandler) Proxy.getInvocationHandler(args[0])).getUnderlyingObject(); } }; @@ -28,6 +34,8 @@ public interface CefClientProxy extends Reflect.ProxyObject { return Reflect.on(returnValue).as(CefBrowserProxy.class); } else if ("addLifeSpanHandler".equals(methodName)) { return Reflect.on(returnValue).as(CefClientProxy.class); + } else if ("addJSDialogHandler".equals(methodName)) { + return Reflect.on(returnValue).as(CefClientProxy.class); } return returnValue; }; @@ -38,6 +46,10 @@ public interface CefClientProxy extends Reflect.ProxyObject { CefClientProxy addLifeSpanHandler(CefLifeSpanHandlerProxy handler); + CefClientProxy addJSDialogHandler(CefJSDialogHandlerProxy handler); + + void addMessageRouter(CefMessageRouterProxy messageRouter); + void removeContextMenuHandler(); void removeDialogHandler(); diff --git a/src/main/java/com/codebrig/journey/proxy/browser/CefFrameProxy.java b/src/main/java/com/codebrig/journey/proxy/browser/CefFrameProxy.java index 7269af3..7bcc309 100644 --- a/src/main/java/com/codebrig/journey/proxy/browser/CefFrameProxy.java +++ b/src/main/java/com/codebrig/journey/proxy/browser/CefFrameProxy.java @@ -8,7 +8,7 @@ * Javadoc taken from: https://bitbucket.org/chromiumembedded/java-cef * * @author Brandon Fergerson - * @version 0.3.3 + * @version 0.4.0 * @since 0.2.18 */ @SuppressWarnings("unused") diff --git a/src/main/java/com/codebrig/journey/proxy/browser/CefMessageRouterProxy.java b/src/main/java/com/codebrig/journey/proxy/browser/CefMessageRouterProxy.java new file mode 100644 index 0000000..3b76dac --- /dev/null +++ b/src/main/java/com/codebrig/journey/proxy/browser/CefMessageRouterProxy.java @@ -0,0 +1,95 @@ +package com.codebrig.journey.proxy.browser; + +import com.codebrig.journey.JourneyLoader; +import com.codebrig.journey.proxy.CefBrowserProxy; +import com.codebrig.journey.proxy.handler.CefMessageRouterHandlerProxy; +import org.joor.Reflect; +import org.joor.Reflect.ProxyArgumentsConverter; +import org.joor.Reflect.ProxyValueConverter; + +import java.lang.reflect.Proxy; + +/** + * Journey local proxy for CefMessageRouter. + *

+ * Javadoc taken from: https://bitbucket.org/chromiumembedded/java-cef + * + * @author Dhruvit Raithatha + * @version 0.4.0 + * @since 0.4.0 + */ +public interface CefMessageRouterProxy extends Reflect.ProxyObject { + + ProxyArgumentsConverter PROXY_ARGUMENTS_CONVERTER = (methodName, args) -> { + if ("addHandler".equals(methodName)) { + args[0] = ((Reflect.ProxyInvocationHandler) Proxy.getInvocationHandler(args[0])).getUnderlyingObject(); + } else if ("removeHandler".equals(methodName)) { + args[0] = ((Reflect.ProxyInvocationHandler) Proxy.getInvocationHandler(args[0])).getUnderlyingObject(); + } else if ("cancelPending".equals(methodName)) { + args[0] = ((Reflect.ProxyInvocationHandler) Proxy.getInvocationHandler(args[0])).getUnderlyingObject(); + } else if ("getPendingCount".equals(methodName)) { + args[0] = ((Reflect.ProxyInvocationHandler) Proxy.getInvocationHandler(args[0])).getUnderlyingObject(); + } + }; + + ProxyValueConverter PROXY_VALUE_CONVERTER = (methodName, returnValue) -> returnValue; + + /** + * Must be called if the CefMessageRouterProxy instance isn't used any more + */ + void dispose(); + + /** + * Add a new query handler. If |first| is true it will be added as the first + * handler, otherwise it will be added as the last handler. Returns true if the + * handler is added successfully or false if the handler has already been added. + * Must be called on the browser process UI thread. The Handler object must + * either outlive the router or be removed before deletion. + * + * @param handler the according handler to be added + * @param first if If set to true it will be added as the first handler + * @return true if the handler is added successfully + */ + boolean addHandler(CefMessageRouterHandlerProxy handler, boolean first); + + /** + * Remove an existing query handler. Any pending queries associated with the + * handler will be canceled. Handler.OnQueryCanceled will be called and the + * associated JavaScript onFailure callback will be executed with an error code + * of -1. Returns true if the handler is removed successfully or false if the + * handler is not found. Must be called on the browser process UI thread. + * + * @param handler the according handler to be removed + * @return true if the handler is removed successfully + */ + boolean removeHandler(CefMessageRouterHandlerProxy handler); + + /** + * Cancel all pending queries associated with either |browser| or |handler|. If + * both |browser| and |handler| are NULL all pending queries will be canceled. + * Handler::OnQueryCanceled will be called and the associated JavaScript + * onFailure callback will be executed in all cases with an error code of -1. + * + * @param browser may be empty + * @param handler may be empty + */ + void cancelPending(CefBrowserProxy browser, CefMessageRouterHandlerProxy handler); + + /** + * Returns the number of queries currently pending for the specified |browser| + * and/or |handler|. Either or both values may be empty. Must be called on the + * browser process UI thread. + * + * @param browser may be empty + * @param handler may be empty + * @return the number of queries currently pending + */ + int getPendingCount(CefBrowserProxy browser, CefMessageRouterHandlerProxy handler); + + static CefMessageRouterProxy createRouter() { + JourneyLoader classLoader = JourneyLoader.getJourneyClassLoader(); + Object realCefMessageRouter = Reflect.onClass(classLoader.loadClass("org.cef.browser.CefMessageRouter")) + .call("create").get(); + return Reflect.on(realCefMessageRouter).as(CefMessageRouterProxy.class); + } +} diff --git a/src/main/java/com/codebrig/journey/proxy/callback/CefJSDialogCallbackProxy.java b/src/main/java/com/codebrig/journey/proxy/callback/CefJSDialogCallbackProxy.java new file mode 100644 index 0000000..c4b9c37 --- /dev/null +++ b/src/main/java/com/codebrig/journey/proxy/callback/CefJSDialogCallbackProxy.java @@ -0,0 +1,28 @@ +package com.codebrig.journey.proxy.callback; + +import org.joor.Reflect; + +/** + * Journey local proxy for CefJSDialogCallback. + *

+ * Javadoc taken from: https://bitbucket.org/chromiumembedded/java-cef + * + * @author Brandon Fergerson + * @version 0.4.0 + * @since 0.4.0 + */ +public interface CefJSDialogCallbackProxy { + + Reflect.ProxyArgumentsConverter PROXY_ARGUMENTS_CONVERTER = (methodName, args) -> { + }; + + Reflect.ProxyValueConverter PROXY_VALUE_CONVERTER = (methodName, returnValue) -> returnValue; + + /** + * Continue the JS dialog request. + * + * @param success Set to true if the OK button was pressed. + * @param userInput The value should be specified for prompt dialogs. + */ + void Continue(boolean success, String userInput); +} \ No newline at end of file diff --git a/src/main/java/com/codebrig/journey/proxy/callback/CefNativeProxy.java b/src/main/java/com/codebrig/journey/proxy/callback/CefNativeProxy.java new file mode 100644 index 0000000..3e11432 --- /dev/null +++ b/src/main/java/com/codebrig/journey/proxy/callback/CefNativeProxy.java @@ -0,0 +1,38 @@ +package com.codebrig.journey.proxy.callback; + +import org.joor.Reflect; + +/** + * Journey local proxy for CefNative. + *

+ * Javadoc taken from: https://bitbucket.org/chromiumembedded/java-cef + * + * @author Dhruvit Raithatha + * @version 0.4.0 + * @since 0.4.0 + */ +public interface CefNativeProxy extends Reflect.ProxyObject { + + Reflect.ProxyArgumentsConverter PROXY_ARGUMENTS_CONVERTER = (methodName, args) -> { + }; + + Reflect.ProxyValueConverter PROXY_VALUE_CONVERTER = (methodName, returnValue) -> returnValue; + + /** + * Method is called by the native code to store a reference + * to an implemented native JNI counterpart. + * + * @param identifer The name of the interface class (e.g. CefFocusHandler). + * @param nativeRef The reference to the native code. + */ + void setNativeRef(String identifer, long nativeRef); + + /** + * Method is called by the native code to get the reference + * to an previous stored identifier. + * + * @param identifer The name of the interface class (e.g. CefFocusHandler). + * @return The stored reference value of the native code. + */ + long getNativeRef(String identifer); +} \ No newline at end of file diff --git a/src/main/java/com/codebrig/journey/proxy/callback/CefQueryCallbackProxy.java b/src/main/java/com/codebrig/journey/proxy/callback/CefQueryCallbackProxy.java new file mode 100644 index 0000000..0f4ac20 --- /dev/null +++ b/src/main/java/com/codebrig/journey/proxy/callback/CefQueryCallbackProxy.java @@ -0,0 +1,37 @@ +package com.codebrig.journey.proxy.callback; + +import org.joor.Reflect; + +/** + * Journey local proxy for CefQueryCallback. + *

+ * Javadoc taken from: https://bitbucket.org/chromiumembedded/java-cef + * + * @author Dhruvit Raithatha + * @version 0.4.0 + * @since 0.4.0 + */ +public interface CefQueryCallbackProxy extends Reflect.ProxyObject { + + Reflect.ProxyArgumentsConverter PROXY_ARGUMENTS_CONVERTER = (methodName, args) -> { + }; + + Reflect.ProxyValueConverter PROXY_VALUE_CONVERTER = (methodName, returnValue) -> returnValue; + + /** + * Notify the associated JavaScript onSuccess callback that the query has + * completed successfully. + * + * @param response Response passed to JavaScript. + */ + void success(String response); + + /** + * Notify the associated JavaScript onFailure callback that the query has + * failed. + * + * @param errorCode Error code passed to JavaScript. + * @param errorMessage Error message passed to JavaScript. + */ + void failure(int errorCode, String errorMessage); +} diff --git a/src/main/java/com/codebrig/journey/proxy/handler/CefJSDialogHandlerProxy.java b/src/main/java/com/codebrig/journey/proxy/handler/CefJSDialogHandlerProxy.java new file mode 100644 index 0000000..502385f --- /dev/null +++ b/src/main/java/com/codebrig/journey/proxy/handler/CefJSDialogHandlerProxy.java @@ -0,0 +1,114 @@ +package com.codebrig.journey.proxy.handler; + +import com.codebrig.journey.JourneyLoader; +import com.codebrig.journey.proxy.CefBrowserProxy; +import com.codebrig.journey.proxy.callback.CefJSDialogCallbackProxy; +import com.codebrig.journey.proxy.misc.BoolRefProxy; +import org.joor.Reflect; + +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +/** + * Journey local proxy for CefJSDialogHandler. + *

+ * Javadoc taken from: https://bitbucket.org/chromiumembedded/java-cef + * + * @author Brandon Fergerson + * @version 0.4.0 + * @since 0.4.0 + */ +public interface CefJSDialogHandlerProxy { + + Reflect.ProxyArgumentsConverter PROXY_ARGUMENTS_CONVERTER = (methodName, args) -> { + if ("onJSDialog".equals(methodName)) { + args[0] = Reflect.on(args[0]).as(CefBrowserProxy.class); + args[2] = JSDialogType.valueOf(args[2].toString()); + args[5] = Reflect.on(args[5]).as(CefJSDialogCallbackProxy.class); + args[6] = Reflect.on(args[6]).as(BoolRefProxy.class); + } + }; + + Reflect.ProxyValueConverter PROXY_VALUE_CONVERTER = (methodName, returnValue) -> returnValue; + + /** + * Supported JavaScript dialog types. + */ + enum JSDialogType { + JSDIALOGTYPE_ALERT, + JSDIALOGTYPE_CONFIRM, + JSDIALOGTYPE_PROMPT, + } + + /** + * Called to run a JavaScript dialog. Set suppressMessage to true and + * return false to suppress the message (suppressing messages is preferable + * to immediately executing the callback as this is used to detect presumably + * malicious behavior like spamming alert messages in onbeforeunload). Set + * suppressMessage to false and return false to use the default + * implementation (the default implementation will show one modal dialog at a + * time and suppress any additional dialog requests until the displayed dialog + * is dismissed). Return true if the application will use a custom dialog or + * if the callback has been executed immediately. Custom dialogs may be either + * modal or modeless. If a custom dialog is used the application must execute + * callback once the custom dialog is dismissed. + * + * @param browser The corresponding browser. + * @param originUrl The originating url. + * @param dialogType the dialog type. + * @param messageText the text to be displayed. + * @param defaultPromptText value will be specified for prompt dialogs only. + * @param callback execute callback once the custom dialog is dismissed. + * @param suppressMessage set to true to suppress displaying the message. + * @return false to use the default dialog implementation. Return true if the + * application will use a custom dialog. + */ + boolean onJSDialog(CefBrowserProxy browser, String originUrl, JSDialogType dialogType, + String messageText, String defaultPromptText, CefJSDialogCallbackProxy callback, + BoolRefProxy suppressMessage); + + /** + * Called to run a dialog asking the user if they want to leave a page. Return + * false to use the default dialog implementation. Return true if the + * application will use a custom dialog or if the callback has been executed + * immediately. Custom dialogs may be either modal or modeless. If a custom + * dialog is used the application must execute callback once the custom + * dialog is dismissed. + * + * @param browser The corresponding browser. + * @param messageText The text to be displayed. + * @param isReload true if the page is reloaded. + * @param callback execute callback once the custom dialog is dismissed. + * @return false to use the default dialog implementation. Return true if the + * application will use a custom dialog. + */ + boolean onBeforeUnloadDialog(CefBrowserProxy browser, String messageText, boolean isReload, + CefJSDialogCallbackProxy callback); + + /** + * Called to cancel any pending dialogs and reset any saved dialog state. Will + * be called due to events like page navigation irregardless of whether any + * dialogs are currently pending. + */ + void onResetDialogState(CefBrowserProxy browser); + + /** + * Called when the default implementation dialog is closed. + */ + void onDialogClosed(CefBrowserProxy browser); + + static CefJSDialogHandlerProxy createHandler(CefJSDialogHandlerProxy handler) { + Object instance = Proxy.newProxyInstance(JourneyLoader.getJourneyClassLoader(), + new Class[]{JourneyLoader.getJourneyClassLoader().loadClass("org.cef.handler.CefJSDialogHandler")}, + new Reflect.ProxyInvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, Object[] args) { + ((Reflect.ProxyArgumentsConverter) Reflect.on(handler).field("PROXY_ARGUMENTS_CONVERTER").get()) + .convertArguments(method.getName(), args); + return ((Reflect.ProxyValueConverter) Reflect.on(handler).field("PROXY_VALUE_CONVERTER").get()) + .convertValue(method.getName(), Reflect.on(handler).call(method.getName(), args).get()); + } + }); + return Reflect.on(instance).as(CefJSDialogHandlerProxy.class); + } +} diff --git a/src/main/java/com/codebrig/journey/proxy/handler/CefLifeSpanHandlerProxy.java b/src/main/java/com/codebrig/journey/proxy/handler/CefLifeSpanHandlerProxy.java index 53cca95..e874526 100644 --- a/src/main/java/com/codebrig/journey/proxy/handler/CefLifeSpanHandlerProxy.java +++ b/src/main/java/com/codebrig/journey/proxy/handler/CefLifeSpanHandlerProxy.java @@ -14,7 +14,7 @@ * Javadoc taken from: https://bitbucket.org/chromiumembedded/java-cef * * @author Brandon Fergerson - * @version 0.3.3 + * @version 0.4.0 * @since 0.2.17 */ @SuppressWarnings("unused") diff --git a/src/main/java/com/codebrig/journey/proxy/handler/CefMessageRouterHandlerProxy.java b/src/main/java/com/codebrig/journey/proxy/handler/CefMessageRouterHandlerProxy.java new file mode 100644 index 0000000..0cb464a --- /dev/null +++ b/src/main/java/com/codebrig/journey/proxy/handler/CefMessageRouterHandlerProxy.java @@ -0,0 +1,79 @@ +package com.codebrig.journey.proxy.handler; + +import com.codebrig.journey.JourneyLoader; +import com.codebrig.journey.proxy.CefBrowserProxy; +import com.codebrig.journey.proxy.browser.CefFrameProxy; +import com.codebrig.journey.proxy.callback.CefNativeProxy; +import com.codebrig.journey.proxy.callback.CefQueryCallbackProxy; +import org.joor.Reflect; + +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +/** + * Journey local proxy for CefMessageRouterHandler. + *

+ * Javadoc taken from: https://bitbucket.org/chromiumembedded/java-cef + * + * @author Dhruvit Raithatha + * @version 0.4.0 + * @since 0.4.0 + */ +public interface CefMessageRouterHandlerProxy extends CefNativeProxy { + + Reflect.ProxyArgumentsConverter PROXY_ARGUMENTS_CONVERTER = (methodName, args) -> { + if ("onQuery".equals(methodName)) { + args[0] = Reflect.on(args[0]).as(CefBrowserProxy.class); + args[1] = Reflect.on(args[1]).as(CefFrameProxy.class); + args[5] = Reflect.on(args[5]).as(CefQueryCallbackProxy.class); + } else if ("onQueryCanceled".equals(methodName)) { + args[0] = Reflect.on(args[0]).as(CefBrowserProxy.class); + args[1] = Reflect.on(args[1]).as(CefFrameProxy.class); + } + }; + + Reflect.ProxyValueConverter PROXY_VALUE_CONVERTER = (methodName, returnValue) -> returnValue; + + /** + * Called when the browser receives a JavaScript query. + * + * @param browser The corresponding browser. + * @param frame The frame generating the event. Instance only valid within the scope of this + * method. + * @param queryId The unique ID for the query. + * @param persistent True if the query is persistent. + * @param callback Object used to continue or cancel the query asynchronously. + * @return True to handle the query or false to propagate the query to other registered + * handlers, if any. If no handlers return true from this method then the query will be + * automatically canceled with an error code of -1 delivered to the JavaScript onFailure + * callback. + */ + boolean onQuery(CefBrowserProxy browser, CefFrameProxy frame, long queryId, String request, + boolean persistent, CefQueryCallbackProxy callback); + + /** + * Called when a pending JavaScript query is canceled. + * + * @param browser The corresponding browser. + * @param frame The frame generating the event. Instance only valid within the scope of this + * method. + * @param queryId The unique ID for the query. + */ + void onQueryCanceled(CefBrowserProxy browser, CefFrameProxy frame, long queryId); + + static CefMessageRouterHandlerProxy createHandler(CefMessageRouterHandlerProxy handler) { + Object instance = Proxy.newProxyInstance(JourneyLoader.getJourneyClassLoader(), + new Class[]{JourneyLoader.getJourneyClassLoader() + .loadClass("org.cef.handler.CefMessageRouterHandler")}, + new Reflect.ProxyInvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, Object[] args) { + ((Reflect.ProxyArgumentsConverter) Reflect.on(handler).field("PROXY_ARGUMENTS_CONVERTER").get()) + .convertArguments(method.getName(), args); + return ((Reflect.ProxyValueConverter) Reflect.on(handler).field("PROXY_VALUE_CONVERTER").get()) + .convertValue(method.getName(), Reflect.on(handler).call(method.getName(), args).get()); + } + }); + return Reflect.on(instance).as(CefMessageRouterHandlerProxy.class); + } +} diff --git a/src/main/java/com/codebrig/journey/proxy/misc/BoolRefProxy.java b/src/main/java/com/codebrig/journey/proxy/misc/BoolRefProxy.java new file mode 100644 index 0000000..a2a26c8 --- /dev/null +++ b/src/main/java/com/codebrig/journey/proxy/misc/BoolRefProxy.java @@ -0,0 +1,24 @@ +package com.codebrig.journey.proxy.misc; + +import org.joor.Reflect; + +/** + * Journey local proxy for BoolRef. + *

+ * Javadoc taken from: https://bitbucket.org/chromiumembedded/java-cef + * + * @author Brandon Fergerson + * @version 0.4.0 + * @since 0.4.0 + */ +public interface BoolRefProxy { + + Reflect.ProxyArgumentsConverter PROXY_ARGUMENTS_CONVERTER = (methodName, args) -> { + }; + + Reflect.ProxyValueConverter PROXY_VALUE_CONVERTER = (methodName, returnValue) -> returnValue; + + void set(boolean value); + + boolean get(); +} diff --git a/src/test/java/com/codebrig/journey/JourneyBrowser.java b/src/test/java/com/codebrig/journey/JourneyBrowser.java index 6ccc4b9..5ee6b33 100644 --- a/src/test/java/com/codebrig/journey/JourneyBrowser.java +++ b/src/test/java/com/codebrig/journey/JourneyBrowser.java @@ -1,19 +1,66 @@ package com.codebrig.journey; -import com.codebrig.journey.JourneyBrowserView; +import com.codebrig.journey.proxy.CefBrowserProxy; +import com.codebrig.journey.proxy.browser.CefFrameProxy; +import com.codebrig.journey.proxy.browser.CefMessageRouterProxy; +import com.codebrig.journey.proxy.callback.CefQueryCallbackProxy; +import com.codebrig.journey.proxy.handler.CefMessageRouterHandlerProxy; import javax.swing.*; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.io.File; public class JourneyBrowser { - public static void main(String[] args) throws Exception { - JourneyBrowserView browser = new JourneyBrowserView("https://google.com"); + public static void main(String[] args) { + File jsTest = new File("src/test/resources/JSTest.html"); + JourneyBrowserView browser = new JourneyBrowserView("file:///" + jsTest.getAbsolutePath()); + + CefMessageRouterProxy messageRouter = CefMessageRouterProxy.createRouter(); + messageRouter.addHandler(CefMessageRouterHandlerProxy.createHandler(new CefMessageRouterHandlerProxy() { + + private long N_CefHandle = 0; + + @Override + public boolean onQuery(CefBrowserProxy browser, CefFrameProxy frame, long queryId, String request, + boolean persistent, CefQueryCallbackProxy callback) { + if ("javaVersion".equals(request)) { + callback.success(System.getProperty("java.version")); + return true; + } else if ("showDevTools".equals(request)) { + CefBrowserProxy devTools = browser.getDevTools(); + Component uiComponent = devTools.getUIComponent(); + JFrame devFrame = new JFrame("DevToolsWindow"); + devFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + devFrame.setSize(1000, 600); + devFrame.getContentPane().add(BorderLayout.CENTER, uiComponent); + devFrame.setVisible(true); + return true; + } else { + return false; + } + } + + @Override + public void onQueryCanceled(CefBrowserProxy browser, CefFrameProxy frame, long queryId) { + } + + @Override + public void setNativeRef(String identifer, long nativeRef) { + N_CefHandle = nativeRef; + } + + @Override + public long getNativeRef(String identifer) { + return N_CefHandle; + } + }), true); + browser.getCefClient().addMessageRouter(messageRouter); + JFrame frame = new JFrame(); frame.getContentPane().add(browser, BorderLayout.CENTER); - frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); frame.addWindowListener(new WindowAdapter() { @Override @@ -23,6 +70,14 @@ public void windowClosing(WindowEvent e) { } }); + frame.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + browser.getCefApp().dispose(); + frame.dispose(); + } + }); + frame.setTitle("Journey"); frame.setSize(1000, 600); frame.setVisible(true); diff --git a/src/test/java/com/codebrig/journey/JourneyBrowserTest.java b/src/test/java/com/codebrig/journey/JourneyBrowserTest.java index 39f8700..4b33889 100644 --- a/src/test/java/com/codebrig/journey/JourneyBrowserTest.java +++ b/src/test/java/com/codebrig/journey/JourneyBrowserTest.java @@ -7,7 +7,7 @@ public class JourneyBrowserTest { @Test - public void createBrowser() throws Exception { + public void createBrowser() { JourneyBrowserView browser = new JourneyBrowserView("https://google.com"); assertNotNull(browser.getCefBrowser()); } diff --git a/src/test/resources/JSTest.html b/src/test/resources/JSTest.html new file mode 100644 index 0000000..b62248d --- /dev/null +++ b/src/test/resources/JSTest.html @@ -0,0 +1,35 @@ + + + + + + +Java Version: +
+
+Google +
+
+

+ +
+ +