Vector layers and styling
[gpl/argeo-suite.git] / swt / org.argeo.app.swt / src / org / argeo / app / swt / js / SwtBrowserJsPart.java
index f479f962d5ecbba6922058202efe6c561e8b4dbe..ec359c6865de427b7532d7978afef4147f9dd7a5 100644 (file)
@@ -1,16 +1,14 @@
 package org.argeo.app.swt.js;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 import java.util.Locale;
-import java.util.StringJoiner;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CompletionStage;
 import java.util.function.Function;
-import java.util.function.Supplier;
 
 import org.argeo.api.cms.CmsLog;
+import org.argeo.app.ux.js.JsClient;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.browser.Browser;
 import org.eclipse.swt.browser.BrowserFunction;
@@ -26,7 +24,7 @@ import org.eclipse.swt.widgets.Display;
  * A part using a {@link Browser} and remote JavaScript components on the client
  * side.
  */
-public class SwtBrowserJsPart {
+public class SwtBrowserJsPart implements JsClient {
        private final static CmsLog log = CmsLog.getLog(SwtBrowserJsPart.class);
 
        private final static String GLOBAL_THIS_ = "globalThis.";
@@ -38,7 +36,7 @@ public class SwtBrowserJsPart {
         * Tasks that were requested before the context was ready. Typically
         * configuration methods on the part while the user interfaces is being build.
         */
-       private List<Supplier<Boolean>> preReadyToDos = new ArrayList<>();
+       private List<PreReadyToDo> preReadyToDos = new ArrayList<>();
 
        public SwtBrowserJsPart(Composite parent, int style, String url) {
                this.browser = new Browser(parent, 0);
@@ -56,10 +54,8 @@ public class SwtBrowserJsPart {
                                        init();
                                        loadExtensions();
                                        // execute todos in order
-                                       for (Supplier<Boolean> toDo : preReadyToDos) {
-                                               boolean success = toDo.get();
-                                               if (!success)
-                                                       throw new IllegalStateException("Post-initalisation JavaScript execution failed");
+                                       for (PreReadyToDo toDo : preReadyToDos) {
+                                               toDo.run();
                                        }
                                        preReadyToDos.clear();
                                        readyStage.complete(true);
@@ -88,7 +84,10 @@ public class SwtBrowserJsPart {
        protected void init() {
        }
 
-       /** To be overridden with calls to {@link #loadExtension(String)}. */
+       /**
+        * To be overridden with calls to {@link #loadExtension( Supplier<Boolean> toDo
+        * = () -> { boolean success = browser.execute(); return success; }; String)}.
+        */
        protected void loadExtensions() {
 
        }
@@ -103,7 +102,7 @@ public class SwtBrowserJsPart {
                browser.evaluate(String.format(Locale.ROOT, "import('%s')", url));
        }
 
-       protected CompletionStage<Boolean> getReadyStage() {
+       public CompletionStage<Boolean> getReadyStage() {
                return readyStage.minimalCompletionStage();
        }
 
@@ -111,20 +110,11 @@ public class SwtBrowserJsPart {
         * JAVASCRIPT ACCESS
         */
 
-       /**
-        * Execute this JavaScript on the client side after making sure that the page
-        * has been loaded and the map object has been created.
-        * 
-        * @param js   the JavaScript code, possibly formatted according to
-        *             {@link String#format}, with {@link Locale#ROOT} as locale (for
-        *             stability of decimal separator, as expected by JavaScript.
-        * @param args the optional arguments of
-        *             {@link String#format(String, Object...)}
-        */
-       protected Object evaluate(String js, Object... args) {
+       @Override
+       public Object evaluate(String js, Object... args) {
                assert browser.getDisplay().equals(Display.findDisplay(Thread.currentThread())) : "Not the proper UI thread.";
                if (!readyStage.isDone())
-                       throw new IllegalStateException("Methods returning a result can only be called after UI initilaisation.");
+                       throw new IllegalStateException("Methods returning a result can only be called after UI initialisation.");
                // wait for the context to be ready
 //             boolean ready = readyStage.join();
 //             if (!ready)
@@ -133,22 +123,21 @@ public class SwtBrowserJsPart {
                return result;
        }
 
-       protected void execute(String js, Object... args) {
+       @Override
+       public void execute(String js, Object... args) {
+               String jsToExecute = String.format(Locale.ROOT, js, args);
                if (readyStage.isDone()) {
-                       boolean success = browser.execute(String.format(Locale.ROOT, js, args));
+                       boolean success = browser.execute(jsToExecute);
                        if (!success)
                                throw new RuntimeException("JavaScript execution failed.");
                } else {
-                       Supplier<Boolean> toDo = () -> {
-                               boolean success = browser.execute(String.format(Locale.ROOT, js, args));
-                               return success;
-                       };
+                       PreReadyToDo toDo = new PreReadyToDo(jsToExecute);
                        preReadyToDos.add(toDo);
                }
        }
 
-       /** @return the globally usable function name. */
-       protected String createJsFunction(String name, Function<Object[], Object> toDo) {
+       @Override
+       public String createJsFunction(String name, Function<Object[], Object> toDo) {
                // browser functions must be directly on window (RAP specific)
                new BrowserFunction(browser, name) {
 
@@ -171,51 +160,24 @@ public class SwtBrowserJsPart {
                browser.execute(String.format(Locale.ROOT, js, args));
        }
 
-       protected Object callMethod(String jsObject, String methodCall, Object... args) {
-               return evaluate(jsObject + '.' + methodCall, args);
-       }
-
-       protected void executeMethod(String jsObject, String methodCall, Object... args) {
-               execute(jsObject + '.' + methodCall, args);
-       }
-
-       protected String getJsVarName(String name) {
+       @Override
+       public String getJsVarName(String name) {
                return GLOBAL_THIS_ + name;
        }
 
-       protected static String toJsArray(int... arr) {
-               return Arrays.toString(arr);
-       }
-
-       protected static String toJsArray(long... arr) {
-               return Arrays.toString(arr);
-       }
+       class PreReadyToDo implements Runnable {
+               private String js;
 
-       protected static String toJsArray(double... arr) {
-               return Arrays.toString(arr);
-       }
-
-       protected static String toJsArray(String... arr) {
-               return toJsArray((Object[]) arr);
-       }
-
-       protected static String toJsArray(Object... arr) {
-               StringJoiner sj = new StringJoiner(",", "[", "]");
-               for (Object o : arr) {
-                       sj.add(toJsValue(o));
+               public PreReadyToDo(String js) {
+                       this.js = js;
                }
-               return sj.toString();
-       }
 
-       protected static String toJsValue(Object o) {
-               if (o instanceof CharSequence)
-                       return '\"' + o.toString() + '\"';
-               else if (o instanceof Number)
-                       return o.toString();
-               else if (o instanceof Boolean)
-                       return o.toString();
-               else
-                       return '\"' + o.toString() + '\"';
+               @Override
+               public void run() {
+                       boolean success = browser.execute(js);
+                       if (!success)
+                               throw new IllegalStateException("Pre-ready JavaScript failed: " + js);
+               }
        }
 
        /*