Make Browser JavaScript part more robust when the widget is disposed
[gpl/argeo-suite.git] / swt / org.argeo.app.swt / src / org / argeo / app / swt / js / SwtBrowserJsPart.java
index ec359c6865de427b7532d7978afef4147f9dd7a5..6782f5dd22a03c6d371d914340cd226805b371f8 100644 (file)
@@ -1,5 +1,6 @@
 package org.argeo.app.swt.js;
 
+import java.net.URI;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
@@ -8,7 +9,9 @@ import java.util.concurrent.CompletionStage;
 import java.util.function.Function;
 
 import org.argeo.api.cms.CmsLog;
+import org.argeo.api.cms.ux.CmsView;
 import org.argeo.app.ux.js.JsClient;
+import org.argeo.cms.swt.CmsSwtUtils;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.browser.Browser;
 import org.eclipse.swt.browser.BrowserFunction;
@@ -39,12 +42,14 @@ public class SwtBrowserJsPart implements JsClient {
        private List<PreReadyToDo> preReadyToDos = new ArrayList<>();
 
        public SwtBrowserJsPart(Composite parent, int style, String url) {
+               CmsView cmsView = CmsSwtUtils.getCmsView(parent);
                this.browser = new Browser(parent, 0);
                if (parent.getLayout() instanceof GridLayout)
                        browser.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
                // TODO other layouts
 
-               browser.setUrl(url);
+               URI u = cmsView.toBackendUri(url);
+               browser.setUrl(u.toString());
                browser.addProgressListener(new ProgressListener() {
                        static final long serialVersionUID = 1L;
 
@@ -85,21 +90,15 @@ public class SwtBrowserJsPart implements JsClient {
        }
 
        /**
-        * To be overridden with calls to {@link #loadExtension( Supplier<Boolean> toDo
-        * = () -> { boolean success = browser.execute(); return success; }; String)}.
+        * To be overridden with calls to {@link #loadExtension(String)}.
         */
        protected void loadExtensions() {
 
        }
 
        protected void loadExtension(String url) {
-//                     String js = """
-//                                     var script = document.createElement("script");
-//                                     script.src = '%s';
-//                                     document.head.appendChild(script);
-//                                     """;
-//                     browser.evaluate(String.format(Locale.ROOT, js, url));
-               browser.evaluate(String.format(Locale.ROOT, "import('%s')", url));
+               URI u = CmsSwtUtils.getCmsView(getControl()).toBackendUri(url);
+               browser.evaluate(String.format(Locale.ROOT, "import('%s')", u.toString()));
        }
 
        public CompletionStage<Boolean> getReadyStage() {
@@ -115,10 +114,8 @@ public class SwtBrowserJsPart implements JsClient {
                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 initialisation.");
-               // wait for the context to be ready
-//             boolean ready = readyStage.join();
-//             if (!ready)
-//                     throw new IllegalStateException("Component is not initialised.");
+               if (browser.isDisposed())
+                       return null;
                Object result = browser.evaluate(String.format(Locale.ROOT, js, args));
                return result;
        }
@@ -127,6 +124,8 @@ public class SwtBrowserJsPart implements JsClient {
        public void execute(String js, Object... args) {
                String jsToExecute = String.format(Locale.ROOT, js, args);
                if (readyStage.isDone()) {
+                       if (browser.isDisposed())
+                               return;
                        boolean success = browser.execute(jsToExecute);
                        if (!success)
                                throw new RuntimeException("JavaScript execution failed.");
@@ -157,6 +156,8 @@ public class SwtBrowserJsPart implements JsClient {
         * instead.
         */
        protected void doExecute(String js, Object... args) {
+               if (browser.isDisposed())
+                       return;
                browser.execute(String.format(Locale.ROOT, js, args));
        }
 
@@ -174,9 +175,11 @@ public class SwtBrowserJsPart implements JsClient {
 
                @Override
                public void run() {
+                       if (browser.isDisposed())
+                               return;
                        boolean success = browser.execute(js);
-                       if (!success)
-                               throw new IllegalStateException("Pre-ready JavaScript failed: " + js);
+                       if (!success && log.isTraceEnabled())
+                               log.error("Pre-ready JavaScript failed: " + js);
                }
        }