You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by jt...@apache.org on 2017/09/03 12:48:55 UTC

[22/24] incubator-netbeans-html4j git commit: [INFRA-15006] Initial donation of HTML/Java NetBeans API. Equivalent to the content of html4j-donation-review.zip donated as part of ApacheNetBeansDonation1.zip with SHA256 being 7f2ca0f61953a190613c9a0fbcc1b

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-fx/src/test/java/org/netbeans/html/boot/fx/FXJavaScriptTest.java
----------------------------------------------------------------------
diff --git a/boot-fx/src/test/java/org/netbeans/html/boot/fx/FXJavaScriptTest.java b/boot-fx/src/test/java/org/netbeans/html/boot/fx/FXJavaScriptTest.java
new file mode 100644
index 0000000..f531d4c
--- /dev/null
+++ b/boot-fx/src/test/java/org/netbeans/html/boot/fx/FXJavaScriptTest.java
@@ -0,0 +1,124 @@
+/**
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+package org.netbeans.html.boot.fx;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executors;
+import net.java.html.BrwsrCtx;
+import net.java.html.boot.BrowserBuilder;
+import org.netbeans.html.boot.spi.Fn;
+import org.netbeans.html.json.tck.KOTest;
+import org.testng.Assert;
+import static org.testng.Assert.assertNotSame;
+import static org.testng.Assert.assertSame;
+import org.testng.annotations.Factory;
+
+/**
+ *
+ * @author Jaroslav Tulach
+ */
+public class FXJavaScriptTest {
+    private static Class<?> browserClass;
+    private static Fn.Presenter browserPresenter;
+    
+    public FXJavaScriptTest() {
+    }
+
+    @Factory public static Object[] compatibilityTests() throws Exception {
+        final BrowserBuilder bb = BrowserBuilder.newBrowser().loadClass(FXJavaScriptTest.class).
+            loadPage("empty.html").
+            invoke("initialized");
+
+        Executors.newSingleThreadExecutor().submit(new Runnable() {
+            @Override
+            public void run() {
+                bb.showAndWait();
+            }
+        });
+
+        List<Object> res = new ArrayList<Object>();
+        Class<? extends Annotation> test = 
+            loadClass().getClassLoader().loadClass(KOTest.class.getName()).
+            asSubclass(Annotation.class);
+
+        Class[] arr = (Class[]) loadClass().getDeclaredMethod("tests").invoke(null);
+        for (Class c : arr) {
+            for (Method m : c.getMethods()) {
+                if (m.getAnnotation(test) != null) {
+                    res.add(new KOFx(browserPresenter, m));
+                }
+            }
+        }
+        return res.toArray();
+    }
+
+    static synchronized Class<?> loadClass() throws InterruptedException {
+        while (browserClass == null) {
+            FXJavaScriptTest.class.wait();
+        }
+        return browserClass;
+    }
+    
+    public static synchronized void ready(Class<?> browserCls) throws Exception {
+        browserClass = browserCls;
+        browserPresenter = Fn.activePresenter();
+        FXJavaScriptTest.class.notifyAll();
+    }
+    
+    public static void initialized() throws Exception {
+        BrwsrCtx b1 = BrwsrCtx.findDefault(FXJavaScriptTest.class);
+        TestingProvider.assertCalled("Our context created");
+        assertNotSame(b1, BrwsrCtx.EMPTY, "Browser context is not empty");
+        BrwsrCtx b2 = BrwsrCtx.findDefault(FXJavaScriptTest.class);
+        assertSame(b1, b2, "Browser context remains stable");
+        Assert.assertSame(
+            FXJavaScriptTest.class.getClassLoader(),
+            ClassLoader.getSystemClassLoader(),
+            "No special classloaders"
+        );
+        FXJavaScriptTest.ready(FxJavaScriptTst.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-fx/src/test/java/org/netbeans/html/boot/fx/FXPresenterTst.java
----------------------------------------------------------------------
diff --git a/boot-fx/src/test/java/org/netbeans/html/boot/fx/FXPresenterTst.java b/boot-fx/src/test/java/org/netbeans/html/boot/fx/FXPresenterTst.java
new file mode 100644
index 0000000..8a93ad3
--- /dev/null
+++ b/boot-fx/src/test/java/org/netbeans/html/boot/fx/FXPresenterTst.java
@@ -0,0 +1,103 @@
+/**
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+package org.netbeans.html.boot.fx;
+
+import java.util.logging.Handler;
+import java.util.logging.LogRecord;
+import net.java.html.js.JavaScriptBody;
+import static org.testng.Assert.*;
+import org.testng.annotations.Test;
+
+/**
+ *
+ * @author Jaroslav Tulach
+ */
+public class FXPresenterTst {
+    @Test public void showClassLoader() {
+        R run = new R();
+        callback(run);
+        assertEquals(run.cnt, 1, "Can call even private implementation classes");
+    }
+    
+    @Test public void checkConsoleLogging() {
+        class H extends Handler {
+            LogRecord record;
+            
+            @Override
+            public void publish(LogRecord record) {
+                assert this.record == null;
+                this.record = record;
+            }
+
+            @Override
+            public void flush() {
+            }
+
+            @Override
+            public void close() throws SecurityException {
+            }
+        }
+        H h = new H();
+        FXConsole.LOG.addHandler(h);
+
+        log("Ahoj");
+        
+        assert h.record != null : "Some log record obtained";
+        assert "Ahoj".equals(h.record.getMessage()) : "It is our Ahoj: " + h.record.getMessage();
+    }
+    
+    @JavaScriptBody(args = { "r" }, javacall = true, body = "r.@java.lang.Runnable::run()();")
+    private static native void callback(Runnable r);
+
+    @JavaScriptBody(args = { "msg" }, body = "console.log(msg);")
+    private static native void log(String msg);
+
+    private static class R implements Runnable {
+        int cnt;
+
+        @Override
+        public void run() {
+            cnt++;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-fx/src/test/java/org/netbeans/html/boot/fx/FxJavaScriptTst.java
----------------------------------------------------------------------
diff --git a/boot-fx/src/test/java/org/netbeans/html/boot/fx/FxJavaScriptTst.java b/boot-fx/src/test/java/org/netbeans/html/boot/fx/FxJavaScriptTst.java
new file mode 100644
index 0000000..5a1a042
--- /dev/null
+++ b/boot-fx/src/test/java/org/netbeans/html/boot/fx/FxJavaScriptTst.java
@@ -0,0 +1,55 @@
+/**
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+package org.netbeans.html.boot.fx;
+
+import org.netbeans.html.json.tck.JavaScriptTCK;
+
+/**
+ *
+ * @author Jaroslav Tulach
+ */
+public final class FxJavaScriptTst extends JavaScriptTCK {
+    public static Class[] tests() {
+        return testClasses();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-fx/src/test/java/org/netbeans/html/boot/fx/KOFx.java
----------------------------------------------------------------------
diff --git a/boot-fx/src/test/java/org/netbeans/html/boot/fx/KOFx.java b/boot-fx/src/test/java/org/netbeans/html/boot/fx/KOFx.java
new file mode 100644
index 0000000..6d12324
--- /dev/null
+++ b/boot-fx/src/test/java/org/netbeans/html/boot/fx/KOFx.java
@@ -0,0 +1,125 @@
+/**
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+package org.netbeans.html.boot.fx;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import javafx.application.Platform;
+import org.netbeans.html.boot.impl.FnContext;
+import org.netbeans.html.boot.spi.Fn;
+import org.testng.IHookCallBack;
+import org.testng.IHookable;
+import org.testng.ITest;
+import org.testng.ITestResult;
+import org.testng.annotations.Test;
+
+/**
+ *
+ * @author Jaroslav Tulach
+ */
+public final class KOFx implements ITest, IHookable, Runnable {
+    private final Fn.Presenter p;
+    private final Method m;
+    private Object result;
+    private Object inst;
+
+    KOFx(Fn.Presenter p, Method m) {
+        this.p = p;
+        this.m = m;
+    }
+
+    @Override
+    public String getTestName() {
+        return m.getName();
+    }
+
+    @Test
+    public synchronized void executeTest() throws Exception {
+        if (result == null) {
+            Platform.runLater(this);
+            wait();
+        }
+        if (result instanceof Exception) {
+            throw (Exception)result;
+        }
+        if (result instanceof Error) {
+            throw (Error)result;
+        }
+    }
+
+    @Override
+    public synchronized void run() {
+        boolean notify = true;
+        try {
+            FnContext.currentPresenter(p);
+            if (inst == null) {
+                inst = m.getDeclaringClass().newInstance();
+            }
+            result = m.invoke(inst);
+            if (result == null) {
+                result = this;
+            }
+        } catch (InvocationTargetException ex) {
+            Throwable r = ex.getTargetException();
+            if (r instanceof InterruptedException) {
+                notify = false;
+                Platform.runLater(this);
+                return;
+            }
+            result = r;
+        } catch (Exception ex) {
+            result = ex;
+        } finally {
+            if (notify) {
+                notifyAll();
+            }
+            FnContext.currentPresenter(null);
+        }
+    }
+
+    @Override
+    public void run(IHookCallBack ihcb, ITestResult itr) {
+        ihcb.runTestMethod(itr);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-fx/src/test/java/org/netbeans/html/boot/fx/ReloadTest.java
----------------------------------------------------------------------
diff --git a/boot-fx/src/test/java/org/netbeans/html/boot/fx/ReloadTest.java b/boot-fx/src/test/java/org/netbeans/html/boot/fx/ReloadTest.java
new file mode 100644
index 0000000..5a704f5
--- /dev/null
+++ b/boot-fx/src/test/java/org/netbeans/html/boot/fx/ReloadTest.java
@@ -0,0 +1,157 @@
+/**
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+package org.netbeans.html.boot.fx;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import javafx.application.Platform;
+import net.java.html.BrwsrCtx;
+import net.java.html.boot.BrowserBuilder;
+import net.java.html.js.JavaScriptBody;
+import org.netbeans.html.boot.spi.Fn;
+import static org.testng.Assert.*;
+import org.testng.annotations.Test;
+
+/**
+ *
+ * @author Jaroslav Tulach
+ */
+public class ReloadTest {
+    private static Runnable whenInitialized;
+    
+    public ReloadTest() {
+    }
+
+    @JavaScriptBody(args = { "a", "b"  }, body = "return a + b;")
+    private static native int plus(int a, int b);
+    
+    @Test public void checkReload() throws Throwable {
+        final Throwable[] arr = { null };
+        
+        final BrowserBuilder bb = BrowserBuilder.newBrowser().loadClass(ReloadTest.class).
+                loadPage("empty.html").
+                invoke("initialized");
+        
+        class ShowBrowser implements Runnable {
+            @Override
+            public void run() {
+                bb.showAndWait();
+            }
+        }
+        
+        class WhenInitialized implements Runnable {
+            CountDownLatch cdl = new CountDownLatch(1);
+            AbstractFXPresenter p;
+            BrwsrCtx ctx;
+            
+            @Override
+            public void run() {
+                try {
+                    whenInitialized = null;
+                    doCheckReload();
+                    p = (AbstractFXPresenter) Fn.activePresenter();
+                    assertNotNull(p, "Presenter is defined");
+                    ctx = BrwsrCtx.findDefault(WhenInitialized.class);
+                } catch (Throwable ex) {
+                    arr[0] = ex;
+                } finally {
+                    cdl.countDown();
+                }
+            }
+        }
+        WhenInitialized when = new WhenInitialized();
+        whenInitialized = when;
+        Executors.newSingleThreadExecutor().submit(new ShowBrowser());
+        when.cdl.await();
+        if (arr[0] != null) throw arr[0];
+        
+        class ReloadPage implements Runnable {
+            final CountDownLatch cdl = new CountDownLatch(1);
+            private final AbstractFXPresenter p;
+
+            public ReloadPage(AbstractFXPresenter p) {
+                this.p = p;
+            }
+
+            @Override
+            public void run() {
+                p.engine.reload();
+                cdl.countDown();
+            }
+        }
+        ReloadPage relPage = new ReloadPage(when.p);
+        
+        class SecondInit implements Runnable {
+            CountDownLatch cdl = new CountDownLatch(1);
+            
+            @Override
+            public void run() {
+                try {
+                    whenInitialized = null;
+                    doCheckReload();
+                } catch (Throwable ex) {
+                    arr[0] = ex;
+                } finally {
+                    cdl.countDown();
+                }
+                
+            }
+        }
+        SecondInit second = new SecondInit();
+        whenInitialized = second;
+        
+        Platform.runLater(relPage);
+        
+        second.cdl.await();
+        if (arr[0] != null) throw arr[0];
+    }
+    
+    final void doCheckReload() throws Exception {
+        int res = plus(30, 12);
+        assertEquals(res, 42, "Meaning of world computed");
+    }
+    
+    public static synchronized void initialized() throws Exception {
+        whenInitialized.run();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-fx/src/test/java/org/netbeans/html/boot/fx/TestingProvider.java
----------------------------------------------------------------------
diff --git a/boot-fx/src/test/java/org/netbeans/html/boot/fx/TestingProvider.java b/boot-fx/src/test/java/org/netbeans/html/boot/fx/TestingProvider.java
new file mode 100644
index 0000000..a79baef
--- /dev/null
+++ b/boot-fx/src/test/java/org/netbeans/html/boot/fx/TestingProvider.java
@@ -0,0 +1,65 @@
+/**
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+package org.netbeans.html.boot.fx;
+
+import org.netbeans.html.context.spi.Contexts;
+import org.openide.util.lookup.ServiceProvider;
+import static org.testng.Assert.assertTrue;
+
+/**
+ *
+ * @author Jaroslav Tulach
+ */
+@ServiceProvider(service = Contexts.Provider.class)
+public final class TestingProvider implements Contexts.Provider {
+    
+    static void assertCalled(String msg) {
+        assertTrue(Boolean.getBoolean(TestingProvider.class.getName()), msg);
+    }
+
+    @Override
+    public void fillContext(Contexts.Builder context, Class<?> requestor) {
+        System.setProperty(TestingProvider.class.getName(), "true");
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-fx/src/test/java/org/netbeans/html/boot/fx/TitleTest.java
----------------------------------------------------------------------
diff --git a/boot-fx/src/test/java/org/netbeans/html/boot/fx/TitleTest.java b/boot-fx/src/test/java/org/netbeans/html/boot/fx/TitleTest.java
new file mode 100644
index 0000000..8b09be3
--- /dev/null
+++ b/boot-fx/src/test/java/org/netbeans/html/boot/fx/TitleTest.java
@@ -0,0 +1,146 @@
+/**
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+package org.netbeans.html.boot.fx;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.stage.Stage;
+import net.java.html.BrwsrCtx;
+import net.java.html.boot.BrowserBuilder;
+import net.java.html.js.JavaScriptBody;
+import org.netbeans.html.boot.spi.Fn;
+import static org.testng.Assert.*;
+import org.testng.annotations.Test;
+
+/**
+ *
+ * @author Jaroslav Tulach
+ */
+public class TitleTest {
+    private static Runnable whenInitialized;
+    
+    public TitleTest() {
+    }
+
+    @JavaScriptBody(args = { "a", "b"  }, body = "return a + b;")
+    private static native int plus(int a, int b);
+    
+    @Test public void checkReload() throws Throwable {
+        final Throwable[] arr = { null };
+        
+        final BrowserBuilder bb = BrowserBuilder.newBrowser().loadClass(TitleTest.class).
+                loadPage("empty.html").
+                invoke("initialized");
+        
+        class ShowBrowser implements Runnable {
+            @Override
+            public void run() {
+                bb.showAndWait();
+            }
+        }
+        
+        class WhenInitialized implements Runnable {
+            CountDownLatch cdl = new CountDownLatch(1);
+            AbstractFXPresenter p;
+            BrwsrCtx ctx;
+            
+            @Override
+            public void run() {
+                try {
+                    whenInitialized = null;
+                    doCheckReload();
+                    p = (AbstractFXPresenter) Fn.activePresenter();
+                    assertNotNull(p, "Presenter is defined");
+                    ctx = BrwsrCtx.findDefault(WhenInitialized.class);
+                } catch (Throwable ex) {
+                    arr[0] = ex;
+                } finally {
+                    cdl.countDown();
+                }
+            }
+        }
+        WhenInitialized when = new WhenInitialized();
+        whenInitialized = when;
+        Executors.newSingleThreadExecutor().submit(new ShowBrowser());
+        when.cdl.await();
+        if (arr[0] != null) throw arr[0];
+        
+        Stage s = FXBrwsr.findStage();
+        assertEquals(s.getTitle(), "FX Presenter Harness");
+        
+        final CountDownLatch propChange = new CountDownLatch(1);
+        s.titleProperty().addListener(new ChangeListener<String>() {
+            @Override
+            public void changed(ObservableValue<? extends String> ov, String t, String t1) {
+                propChange.countDown();
+            }
+        });
+        
+        when.ctx.execute(new Runnable() {
+            @Override
+            public void run() {
+                changeTitle("New title");
+            }
+        });
+
+        propChange.await(5, TimeUnit.SECONDS);
+        assertEquals(s.getTitle(), "New title");
+    }
+    
+    final void doCheckReload() throws Exception {
+        int res = plus(30, 12);
+        assertEquals(res, 42, "Meaning of world computed");
+    }
+    
+    public static synchronized void initialized() throws Exception {
+        whenInitialized.run();
+    }
+    
+    @JavaScriptBody(args = { "s" }, body = 
+        "document.getElementsByTagName('title')[0].innerHTML = s;"
+    )
+    static native void changeTitle(String s);
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-fx/src/test/java/org/sample/app/pkg/SampleApp.java
----------------------------------------------------------------------
diff --git a/boot-fx/src/test/java/org/sample/app/pkg/SampleApp.java b/boot-fx/src/test/java/org/sample/app/pkg/SampleApp.java
new file mode 100644
index 0000000..ab83113
--- /dev/null
+++ b/boot-fx/src/test/java/org/sample/app/pkg/SampleApp.java
@@ -0,0 +1,62 @@
+/**
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+package org.sample.app.pkg;
+
+import net.java.html.boot.BrowserBuilder;
+import org.netbeans.html.boot.fx.FXBrwsrTest;
+
+public class SampleApp implements Runnable {
+
+    public static void main() {
+        BrowserBuilder.newBrowser()
+            .loadPage("org/netbeans/html/boot/fx/empty.html") // NOI18N
+            .loadFinished(new SampleApp())
+            .showAndWait();
+    }
+
+    @Override
+    public void run() {
+        FXBrwsrTest.computeCalleeClassName();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-fx/src/test/resources/net/java/html/boot/fx/wnd.js
----------------------------------------------------------------------
diff --git a/boot-fx/src/test/resources/net/java/html/boot/fx/wnd.js b/boot-fx/src/test/resources/net/java/html/boot/fx/wnd.js
new file mode 100644
index 0000000..acd0f9e
--- /dev/null
+++ b/boot-fx/src/test/resources/net/java/html/boot/fx/wnd.js
@@ -0,0 +1,49 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+if (typeof wnd !== 'undefined') {
+    throw 'Window should not be defined yet: ' + wnd;
+}
+
+wnd = {
+};
+

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-fx/src/test/resources/org/netbeans/html/boot/fx/empty.html
----------------------------------------------------------------------
diff --git a/boot-fx/src/test/resources/org/netbeans/html/boot/fx/empty.html b/boot-fx/src/test/resources/org/netbeans/html/boot/fx/empty.html
new file mode 100644
index 0000000..c292ab3
--- /dev/null
+++ b/boot-fx/src/test/resources/org/netbeans/html/boot/fx/empty.html
@@ -0,0 +1,55 @@
+<!--
+
+    DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+    Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
+
+    Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+    Other names may be trademarks of their respective owners.
+
+    The contents of this file are subject to the terms of either the GNU
+    General Public License Version 2 only ("GPL") or the Common
+    Development and Distribution License("CDDL") (collectively, the
+    "License"). You may not use this file except in compliance with the
+    License. You can obtain a copy of the License at
+    http://www.netbeans.org/cddl-gplv2.html
+    or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+    specific language governing permissions and limitations under the
+    License.  When distributing the software, include this License Header
+    Notice in each file and include the License file at
+    nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+    particular file as subject to the "Classpath" exception as provided
+    by Oracle in the GPL Version 2 section of the License file that
+    accompanied this code. If applicable, add the following below the
+    License Header, with the fields enclosed by brackets [] replaced by
+    your own identifying information:
+    "Portions Copyrighted [year] [name of copyright owner]"
+
+    Contributor(s):
+
+    The Original Software is NetBeans. The Initial Developer of the Original
+    Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved.
+
+    If you wish your version of this file to be governed by only the CDDL
+    or only the GPL Version 2, indicate your decision by adding
+    "[Contributor] elects to include this software in this distribution
+    under the [CDDL or GPL Version 2] license." If you do not indicate a
+    single choice of license, a recipient has the option to distribute
+    your version of this file under either the CDDL, the GPL Version 2 or
+    to extend the choice of license to its licensees as provided above.
+    However, if you add GPL Version 2 code and therefore, elected the GPL
+    Version 2 license, then the option applies only if the new code is
+    made subject to such option by the copyright holder.
+
+-->
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>FX Presenter Harness</title>
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+        <meta name="viewport" content="width=device-width">
+    </head>
+    <body>
+        <div>FX Presenter Harness</div>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-script/pom.xml
----------------------------------------------------------------------
diff --git a/boot-script/pom.xml b/boot-script/pom.xml
new file mode 100644
index 0000000..55073fd
--- /dev/null
+++ b/boot-script/pom.xml
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+    Copyright 2013-2016 Oracle and/or its affiliates. All rights reserved.
+
+    Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+    Other names may be trademarks of their respective owners.
+
+    The contents of this file are subject to the terms of either the GNU
+    General Public License Version 2 only ("GPL") or the Common
+    Development and Distribution License("CDDL") (collectively, the
+    "License"). You may not use this file except in compliance with the
+    License. You can obtain a copy of the License at
+    http://www.netbeans.org/cddl-gplv2.html
+    or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+    specific language governing permissions and limitations under the
+    License.  When distributing the software, include this License Header
+    Notice in each file and include the License file at
+    nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+    particular file as subject to the "Classpath" exception as provided
+    by Oracle in the GPL Version 2 section of the License file that
+    accompanied this code. If applicable, add the following below the
+    License Header, with the fields enclosed by brackets [] replaced by
+    your own identifying information:
+    "Portions Copyrighted [year] [name of copyright owner]"
+
+    Contributor(s):
+
+    The Original Software is NetBeans. The Initial Developer of the Original
+    Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved.
+
+    If you wish your version of this file to be governed by only the CDDL
+    or only the GPL Version 2, indicate your decision by adding
+    "[Contributor] elects to include this software in this distribution
+    under the [CDDL or GPL Version 2] license." If you do not indicate a
+    single choice of license, a recipient has the option to distribute
+    your version of this file under either the CDDL, the GPL Version 2 or
+    to extend the choice of license to its licensees as provided above.
+    However, if you add GPL Version 2 code and therefore, elected the GPL
+    Version 2 license, then the option applies only if the new code is
+    made subject to such option by the copyright holder.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.netbeans.html</groupId>
+        <artifactId>pom</artifactId>
+        <version>2.0-SNAPSHOT</version>
+    </parent>
+    <name>Presenter via javax.script</name>
+    <artifactId>net.java.html.boot.script</artifactId>
+    <version>2.0-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+    <properties>
+        <netbeans.compile.on.save>NONE</netbeans.compile.on.save>
+        <publicPackages>net.java.html.boot.script</publicPackages>
+    </properties>
+    <build>
+      <plugins>
+          <plugin>
+              <groupId>org.apache.felix</groupId>
+              <artifactId>maven-bundle-plugin</artifactId>
+              <extensions>true</extensions>
+              <configuration>
+                  <instructions>
+                      <Export-Package>${publicPackages}</Export-Package>
+                      <Bundle-SymbolicName>net.java.html.boot.script</Bundle-SymbolicName>
+                  </instructions>
+              </configuration>
+          </plugin>
+          <plugin>
+              <groupId>org.netbeans.html</groupId>
+              <artifactId>html4j-maven-plugin</artifactId>
+          </plugin>
+         <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-compiler-plugin</artifactId>
+            <version>2.3.2</version>
+            <configuration>
+               <source>1.7</source>
+               <target>1.7</target>
+            </configuration>
+         </plugin>
+      </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>org.netbeans.api</groupId>
+            <artifactId>org-openide-util-lookup</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.netbeans.html</groupId>
+            <artifactId>net.java.html.boot</artifactId>
+            <version>${project.version}</version>
+            <type>jar</type>
+        </dependency>
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>net.java.html.json.tck</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.grizzly</groupId>
+            <artifactId>grizzly-http-server</artifactId>
+            <version>${grizzly.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.grizzly</groupId>
+            <artifactId>grizzly-websockets-server</artifactId>
+            <version>${grizzly.version}</version>
+            <scope>test</scope>
+            <type>jar</type>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.grizzly</groupId>
+            <artifactId>grizzly-http-servlet</artifactId>
+            <version>${grizzly.version}</version>
+            <scope>test</scope>
+        </dependency>    
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <scope>test</scope>
+            <version>3.1.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.netbeans.html</groupId>
+            <artifactId>ko4j</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+            <type>jar</type>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>ko-ws-tyrus</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+            <type>jar</type>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-script/src/main/java/net/java/html/boot/script/ScriptPresenter.java
----------------------------------------------------------------------
diff --git a/boot-script/src/main/java/net/java/html/boot/script/ScriptPresenter.java b/boot-script/src/main/java/net/java/html/boot/script/ScriptPresenter.java
new file mode 100644
index 0000000..82dabff
--- /dev/null
+++ b/boot-script/src/main/java/net/java/html/boot/script/ScriptPresenter.java
@@ -0,0 +1,443 @@
+/**
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+package net.java.html.boot.script;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.ObjectOutput;
+import java.io.Reader;
+import java.lang.ref.WeakReference;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.script.Invocable;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import org.netbeans.html.boot.spi.Fn;
+import org.netbeans.html.boot.spi.Fn.Presenter;
+
+/** Implementation of {@link Presenter} that delegates
+ * to Java {@link ScriptEngine scripting} API. The presenter runs headless
+ * without appropriate simulation of browser APIs. Its primary usefulness
+ * is inside testing environments. 
+ * <p>
+ * One can load in browser simulation for example from 
+ * <a href="http://www.envjs.com/">env.js</a>. The best way to achieve so,
+ * is to wait until JDK-8046013 gets fixed....
+ * 
+ *
+ * @author Jaroslav Tulach
+ */
+final class ScriptPresenter implements Fn.KeepAlive,
+Presenter, Fn.FromJavaScript, Fn.ToJavaScript, Executor {
+    private static final Logger LOG = Logger.getLogger(ScriptPresenter.class.getName());
+    private static final boolean JDK7;
+    static {
+        boolean jdk7;
+        try {
+            Class.forName("java.lang.FunctionalInterface");
+            jdk7 = false;
+        } catch (ClassNotFoundException ex) {
+            jdk7 = true;
+        }
+        JDK7 = jdk7;
+    }
+    private final ScriptEngine eng;
+    private final Executor exc;
+    private final Object undefined;
+
+    public ScriptPresenter(Executor exc) {
+        this.exc = exc;
+        try {
+            eng = new ScriptEngineManager().getEngineByName("javascript");
+            eng.eval("function alert(msg) { Packages.java.lang.System.out.println(msg); };");
+            eng.eval("function confirm(msg) { Packages.java.lang.System.out.println(msg); return true; };");
+            eng.eval("function prompt(msg, txt) { Packages.java.lang.System.out.println(msg + ':' + txt); return txt; };");
+            Object undef;
+            if (JDK7) {
+                undef = new JDK7Callback().undefined(eng);
+            } else {
+                undef = ((Object[])eng.eval("Java.to([undefined])"))[0];
+            }
+            this.undefined = undef;
+        } catch (ScriptException ex) {
+            throw new IllegalStateException(ex);
+        }
+    }
+
+    @Override
+    public Fn defineFn(String code, String... names) {
+        return defineImpl(code, names, null);
+    }
+
+    @Override
+    public Fn defineFn(String code, String[] names, boolean[] keepAlive) {
+        return defineImpl(code, names, keepAlive);
+    }    
+    private FnImpl defineImpl(String code, String[] names, boolean[] keepAlive) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("(function() {\n");
+        sb.append("  return function(");
+        String sep = "";
+        if (names != null) for (String n : names) {
+            sb.append(sep).append(n);
+            sep = ",";
+        }
+        sb.append(") {\n");
+        sb.append(code);
+        sb.append("\n  };\n");
+        sb.append("})()\n");
+
+        final Object fn;
+        try {
+            fn = eng.eval(sb.toString());
+        } catch (ScriptException ex) {
+            throw new IllegalStateException(ex);
+        }
+        return new FnImpl(this, fn, keepAlive);
+    }
+
+    @Override
+    public void displayPage(URL page, Runnable onPageLoad) {
+        try {
+            eng.eval("if (typeof window !== 'undefined') window.location = '" + page + "'");
+        } catch (ScriptException ex) {
+            LOG.log(Level.SEVERE, "Cannot load " + page, ex);
+        }
+        if (onPageLoad != null) {
+            onPageLoad.run();
+        }
+    }
+
+    @Override
+    public void loadScript(Reader code) throws Exception {
+        eng.eval(code);
+    }
+    
+    //
+    // array conversions
+    //
+    
+    final Object convertArrays(Object[] arr) throws Exception {
+        for (int i = 0; i < arr.length; i++) {
+            if (arr[i] instanceof Object[]) {
+                arr[i] = convertArrays((Object[]) arr[i]);
+            }
+        }
+        final Object wrapArr = wrapArrFn().invokeImpl(null, false, arr); // NOI18N
+        return wrapArr;
+    }
+
+    private FnImpl wrapArrImpl;
+    private FnImpl wrapArrFn() {
+        if (wrapArrImpl == null) {
+            try {
+                wrapArrImpl = defineImpl("return Array.prototype.slice.call(arguments);", null, null);
+            } catch (Exception ex) {
+                throw new IllegalStateException(ex);
+            }
+        }
+        return wrapArrImpl;
+    }
+
+    final Object checkArray(Object val) throws Exception {
+        final FnImpl fn = arraySizeFn();
+        final Object fnRes = fn.invokeImpl(null, false, val, null);
+        int length = ((Number) fnRes).intValue();
+        if (length == -1) {
+            return val;
+        }
+        Object[] arr = new Object[length];
+        fn.invokeImpl(null, false, val, arr);
+        return arr;
+    }
+
+    private FnImpl arraySize;
+    private FnImpl arraySizeFn() {
+        if (arraySize == null) {
+            try {
+                arraySize = defineImpl("\n"
+                    + "if (to === null) {\n"
+                    + "  if (Object.prototype.toString.call(arr) === '[object Array]') return arr.length;\n"
+                    + "  else return -1;\n"
+                    + "} else {\n"
+                    + "  var l = arr.length;\n"
+                    + "  for (var i = 0; i < l; i++) {\n"
+                    + "    to[i] = arr[i] === undefined ? null : arr[i];\n"
+                    + "  }\n"
+                    + "  return l;\n"
+                    + "}", new String[] { "arr", "to" }, null
+                );
+            } catch (Exception ex) {
+                throw new IllegalStateException(ex);
+            }
+        }
+        return arraySize;
+    }
+
+    @Override
+    public Object toJava(Object toJS) {
+        if (toJS instanceof Weak) {
+            toJS = ((Weak)toJS).get();
+        }
+        if (toJS == undefined) {
+            return null;
+        }
+        try {
+            return checkArray(toJS);
+        } catch (Exception ex) {
+            throw new IllegalStateException(ex);
+        }
+    }
+    
+    @Override
+    public Object toJavaScript(Object toReturn) {
+        if (toReturn instanceof Object[]) {
+            try {
+                return convertArrays((Object[])toReturn);
+            } catch (Exception ex) {
+                throw new IllegalStateException(ex);
+            }
+        } else {
+            if (JDK7) {
+                if (toReturn instanceof Boolean) {
+                    return ((Boolean)toReturn) ? true : null;
+                }
+            }
+            return toReturn;
+        }
+    }
+
+    @Override
+    public void execute(final Runnable command) {
+        if (Fn.activePresenter() == this) {
+            command.run();
+            return;
+        }
+        
+        class Wrap implements Runnable {
+            public void run() {
+                try (Closeable c = Fn.activate(ScriptPresenter.this)) {
+                    command.run();
+                } catch (IOException ex) {
+                    throw new IllegalStateException(ex);
+                }
+            }
+        }
+        final Runnable wrap = new Wrap();
+        if (exc == null) {
+            wrap.run();
+        } else {
+            exc.execute(wrap);
+        }
+    }
+
+    private class FnImpl extends Fn {
+
+        private final Object fn;
+        private final boolean[] keepAlive;
+
+        public FnImpl(Presenter presenter, Object fn, boolean[] keepAlive) {
+            super(presenter);
+            this.fn = fn;
+            this.keepAlive = keepAlive;
+        }
+
+        @Override
+        public Object invoke(Object thiz, Object... args) throws Exception {
+            return invokeImpl(thiz, true, args);
+        }
+
+            final Object invokeImpl(Object thiz, boolean arrayChecks, Object... args) throws Exception {
+                List<Object> all = new ArrayList<>(args.length + 1);
+                all.add(thiz == null ? fn : thiz);
+                for (int i = 0; i < args.length; i++) {
+                    Object conv = args[i];
+                    if (arrayChecks) {
+                        if (args[i] instanceof Object[]) {
+                            Object[] arr = (Object[]) args[i];
+                            conv = ((ScriptPresenter) presenter()).convertArrays(arr);
+                        }
+                        if (conv != null && keepAlive != null
+                            && !keepAlive[i] && !isJSReady(conv)
+                            && !conv.getClass().getSimpleName().equals("$JsCallbacks$") // NOI18N
+                            ) {
+                            conv = new Weak(conv);
+                        }
+                        if (conv instanceof Character) {
+                            conv = (int)(Character)conv;
+                        }
+                    }
+                    all.add(conv);
+                }
+                Object ret = ((Invocable)eng).invokeMethod(fn, "call", all.toArray()); // NOI18N
+                if (ret instanceof Weak) {
+                    ret = ((Weak)ret).get();
+                }
+                if (ret == fn) {
+                    return null;
+                }
+                if (!arrayChecks) {
+                    return ret;
+                }
+                return ((ScriptPresenter)presenter()).checkArray(ret);
+            }
+    }
+    
+    private static boolean isJSReady(Object obj) {
+        if (obj == null) {
+            return true;
+        }
+        if (obj instanceof String) {
+            return true;
+        }
+        if (obj instanceof Number) {
+            return true;
+        }
+        final String cn = obj.getClass().getName();
+        if (cn.startsWith("jdk.nashorn") || ( // NOI18N
+            cn.contains(".mozilla.") && cn.contains(".Native") // NOI18N
+        )) {
+            return true;
+        }
+        if (obj instanceof Character) {
+            return true;
+        }
+        return false;
+    }    
+    
+    private static final class Weak extends WeakReference<Object> {
+        public Weak(Object referent) {
+            super(referent);
+        }
+    }
+
+    private static final class JDK7Callback implements ObjectOutput {
+        private Object undefined;
+
+        @Override
+        public void writeObject(Object obj) throws IOException {
+            undefined = obj;
+        }
+
+        @Override
+        public void write(int b) throws IOException {
+        }
+
+        @Override
+        public void write(byte[] b) throws IOException {
+        }
+
+        @Override
+        public void write(byte[] b, int off, int len) throws IOException {
+        }
+
+        @Override
+        public void flush() throws IOException {
+        }
+
+        @Override
+        public void close() throws IOException {
+        }
+
+        @Override
+        public void writeBoolean(boolean v) throws IOException {
+        }
+
+        @Override
+        public void writeByte(int v) throws IOException {
+        }
+
+        @Override
+        public void writeShort(int v) throws IOException {
+        }
+
+        @Override
+        public void writeChar(int v) throws IOException {
+        }
+
+        @Override
+        public void writeInt(int v) throws IOException {
+        }
+
+        @Override
+        public void writeLong(long v) throws IOException {
+        }
+
+        @Override
+        public void writeFloat(float v) throws IOException {
+        }
+
+        @Override
+        public void writeDouble(double v) throws IOException {
+        }
+
+        @Override
+        public void writeBytes(String s) throws IOException {
+        }
+
+        @Override
+        public void writeChars(String s) throws IOException {
+        }
+
+        @Override
+        public void writeUTF(String s) throws IOException {
+        }
+
+        public Object undefined(ScriptEngine eng) {
+            try {
+                eng.eval("function isJDK7Undefined(js) { js.writeObject(undefined); }");
+                Invocable inv = (Invocable) eng;
+                inv.invokeFunction("isJDK7Undefined", this);
+            } catch (NoSuchMethodException | ScriptException ex) {
+                throw new IllegalStateException(ex);
+            }
+            return undefined;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-script/src/main/java/net/java/html/boot/script/Scripts.java
----------------------------------------------------------------------
diff --git a/boot-script/src/main/java/net/java/html/boot/script/Scripts.java b/boot-script/src/main/java/net/java/html/boot/script/Scripts.java
new file mode 100644
index 0000000..d5ff411
--- /dev/null
+++ b/boot-script/src/main/java/net/java/html/boot/script/Scripts.java
@@ -0,0 +1,119 @@
+/**
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+package net.java.html.boot.script;
+
+import java.io.Closeable;
+import java.util.concurrent.Executor;
+import javax.script.ScriptEngine;
+import net.java.html.boot.BrowserBuilder;
+import net.java.html.js.JavaScriptBody;
+import org.netbeans.html.boot.spi.Fn;
+import org.netbeans.html.boot.spi.Fn.Presenter;
+
+/** Implementations of {@link Presenter}s that delegate
+ * to Java {@link ScriptEngine scripting} API. Initialize your presenter
+ * like this:
+ * 
+ * <pre>
+ * 
+ * {@link Runnable} <em>run</em> = ...; // your own init code
+ * {@link Presenter Fn.Presenter} <b>p</b> = Scripts.{@link Scripts#createPresenter()};
+ * BrowserBuilder.{@link BrowserBuilder#newBrowser(java.lang.Object...) newBrowser(<b>p</b>)}.
+ *      {@link BrowserBuilder#loadFinished(java.lang.Runnable) loadFinished(run)}.
+ *      {@link BrowserBuilder#showAndWait()};
+ * </pre>
+ * 
+ * and your runnable can make extensive use of {@link JavaScriptBody} directly or
+ * indirectly via APIs using {@link JavaScriptBody such annotation} themselves.
+ * <p>
+ * Alternatively one can manipulate the presenter manually, which is
+ * especially useful when writing tests:
+ * <pre>
+ * {@code @Test} public void runInASimulatedBrowser() throws Exception {
+ *   {@link Presenter Fn.Presenter} <b>p</b> = Scripts.{@link Scripts#createPresenter()};
+ *   try ({@link Closeable} c = {@link Fn#activate(org.netbeans.html.boot.spi.Fn.Presenter) Fn.activate}(<b>p</b>)) {
+ *     // your code operating in context of <b>p</b>
+ *   }
+ * }
+ * </pre>
+ * The previous code snippet requires Java 7 language syntax, as it relies
+ * on try-with-resources language syntactic sugar feature. The same block
+ * of code can be used on older versions of Java, but it is slightly more
+ * verbose.
+ * 
+ * @author Jaroslav Tulach
+ */
+public final class Scripts {
+    private Scripts() {
+    }
+    
+    /** Simple implementation of {@link Presenter} that delegates
+     * to Java {@link ScriptEngine scripting} API. The presenter runs headless
+     * without appropriate simulation of browser APIs. Its primary usefulness
+     * is inside testing environments. The presenter implements {@link Executor}
+     * interface, but invokes all runnables passed to {@link Executor#execute(java.lang.Runnable)}
+     * immediately.
+     * 
+     * @return new instance of a presenter that is using its own
+     *   {@link ScriptEngine} for <code>text/javascript</code> mimetype
+     */
+    public static Presenter createPresenter() {
+        return new ScriptPresenter(null);
+    }
+
+    /** Implementation of {@link Presenter} that delegates
+     * to Java {@link ScriptEngine scripting} API and can control execution
+     * thread. The presenter runs headless
+     * without appropriate simulation of browser APIs. Its primary usefulness
+     * is inside testing environments. The presenter implements {@link Executor}
+     * interface, and passes all runnables from {@link Executor#execute(java.lang.Runnable)}
+     * to here in provided <code>exc</code> instance.
+     * 
+     * @param exc the executor to re-schedule all asynchronous requests to
+     * @return new instance of a presenter that is using its own
+     *   {@link ScriptEngine} for <code>text/javascript</code> mimetype
+     */
+    public static Presenter createPresenter(Executor exc) {
+        return new ScriptPresenter(exc);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-script/src/main/java/net/java/html/boot/script/package.html
----------------------------------------------------------------------
diff --git a/boot-script/src/main/java/net/java/html/boot/script/package.html b/boot-script/src/main/java/net/java/html/boot/script/package.html
new file mode 100644
index 0000000..f700a76
--- /dev/null
+++ b/boot-script/src/main/java/net/java/html/boot/script/package.html
@@ -0,0 +1,51 @@
+<!--
+
+    DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+    Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
+
+    Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+    Other names may be trademarks of their respective owners.
+
+    The contents of this file are subject to the terms of either the GNU
+    General Public License Version 2 only ("GPL") or the Common
+    Development and Distribution License("CDDL") (collectively, the
+    "License"). You may not use this file except in compliance with the
+    License. You can obtain a copy of the License at
+    http://www.netbeans.org/cddl-gplv2.html
+    or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+    specific language governing permissions and limitations under the
+    License.  When distributing the software, include this License Header
+    Notice in each file and include the License file at
+    nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+    particular file as subject to the "Classpath" exception as provided
+    by Oracle in the GPL Version 2 section of the License file that
+    accompanied this code. If applicable, add the following below the
+    License Header, with the fields enclosed by brackets [] replaced by
+    your own identifying information:
+    "Portions Copyrighted [year] [name of copyright owner]"
+
+    Contributor(s):
+
+    The Original Software is NetBeans. The Initial Developer of the Original
+    Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved.
+
+    If you wish your version of this file to be governed by only the CDDL
+    or only the GPL Version 2, indicate your decision by adding
+    "[Contributor] elects to include this software in this distribution
+    under the [CDDL or GPL Version 2] license." If you do not indicate a
+    single choice of license, a recipient has the option to distribute
+    your version of this file under either the CDDL, the GPL Version 2 or
+    to extend the choice of license to its licensees as provided above.
+    However, if you add GPL Version 2 code and therefore, elected the GPL
+    Version 2 license, then the option applies only if the new code is
+    made subject to such option by the copyright holder.
+
+-->
+<body>
+    <p>
+        {@link net.java.html.boot.script.Scripts Factories} to create headless
+        {@link net.java.html.boot.BrowserBuilder browser environment} which is
+        useful for testing.
+    </p>
+</body>

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-script/src/test/java/net/java/html/boot/script/Jsr223JavaScriptTest.java
----------------------------------------------------------------------
diff --git a/boot-script/src/test/java/net/java/html/boot/script/Jsr223JavaScriptTest.java b/boot-script/src/test/java/net/java/html/boot/script/Jsr223JavaScriptTest.java
new file mode 100644
index 0000000..8868d62
--- /dev/null
+++ b/boot-script/src/test/java/net/java/html/boot/script/Jsr223JavaScriptTest.java
@@ -0,0 +1,117 @@
+/**
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+package net.java.html.boot.script;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executors;
+import net.java.html.boot.BrowserBuilder;
+import org.netbeans.html.boot.spi.Fn;
+import org.netbeans.html.json.tck.KOTest;
+import org.testng.Assert;
+import org.testng.annotations.Factory;
+
+/**
+ *
+ * @author Jaroslav Tulach
+ */
+public class Jsr223JavaScriptTest {
+    private static Class<?> browserClass;
+    private static Fn.Presenter browserPresenter;
+    
+    public Jsr223JavaScriptTest() {
+    }
+
+    @Factory public static Object[] compatibilityTests() throws Exception {
+        final BrowserBuilder bb = BrowserBuilder.newBrowser(new ScriptPresenter(SingleCase.JS)).
+            loadClass(Jsr223JavaScriptTest.class).
+            loadPage("empty.html").
+            invoke("initialized");
+
+        Executors.newSingleThreadExecutor().submit(new Runnable() {
+            @Override
+            public void run() {
+                bb.showAndWait();
+            }
+        });
+
+        List<Object> res = new ArrayList<Object>();
+        Class<? extends Annotation> test = 
+            loadClass().getClassLoader().loadClass(KOTest.class.getName()).
+            asSubclass(Annotation.class);
+
+        Class[] arr = (Class[]) loadClass().getDeclaredMethod("tests").invoke(null);
+        for (Class c : arr) {
+            for (Method m : c.getMethods()) {
+                if (m.getAnnotation(test) != null) {
+                    res.add(new SingleCase(browserPresenter, m));
+                }
+            }
+        }
+        return res.toArray();
+    }
+
+    static synchronized Class<?> loadClass() throws InterruptedException {
+        while (browserClass == null) {
+            Jsr223JavaScriptTest.class.wait();
+        }
+        return browserClass;
+    }
+    
+    public static synchronized void ready(Class<?> browserCls) throws Exception {
+        browserClass = browserCls;
+        browserPresenter = Fn.activePresenter();
+        Jsr223JavaScriptTest.class.notifyAll();
+    }
+    
+    public static void initialized() throws Exception {
+        Assert.assertSame(
+            Jsr223JavaScriptTest.class.getClassLoader(),
+            ClassLoader.getSystemClassLoader(),
+            "No special classloaders"
+        );
+        Jsr223JavaScriptTest.ready(Jsr223JavaScriptTst.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-script/src/test/java/net/java/html/boot/script/Jsr223JavaScriptTst.java
----------------------------------------------------------------------
diff --git a/boot-script/src/test/java/net/java/html/boot/script/Jsr223JavaScriptTst.java b/boot-script/src/test/java/net/java/html/boot/script/Jsr223JavaScriptTst.java
new file mode 100644
index 0000000..56fde22
--- /dev/null
+++ b/boot-script/src/test/java/net/java/html/boot/script/Jsr223JavaScriptTst.java
@@ -0,0 +1,55 @@
+/**
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+package net.java.html.boot.script;
+
+import org.netbeans.html.json.tck.JavaScriptTCK;
+
+/**
+ *
+ * @author Jaroslav Tulach
+ */
+public final class Jsr223JavaScriptTst extends JavaScriptTCK {
+    public static Class[] tests() {
+        return testClasses();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-script/src/test/java/net/java/html/boot/script/SingleCase.java
----------------------------------------------------------------------
diff --git a/boot-script/src/test/java/net/java/html/boot/script/SingleCase.java b/boot-script/src/test/java/net/java/html/boot/script/SingleCase.java
new file mode 100644
index 0000000..5ffa79c
--- /dev/null
+++ b/boot-script/src/test/java/net/java/html/boot/script/SingleCase.java
@@ -0,0 +1,127 @@
+/**
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+package net.java.html.boot.script;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import org.netbeans.html.boot.spi.Fn;
+import org.netbeans.html.boot.impl.FnContext;
+import org.testng.IHookCallBack;
+import org.testng.IHookable;
+import org.testng.ITest;
+import org.testng.ITestResult;
+import org.testng.annotations.Test;
+
+/**
+ *
+ * @author Jaroslav Tulach
+ */
+public final class SingleCase implements ITest, IHookable, Runnable {
+    static final Executor JS = Executors.newSingleThreadExecutor();
+    private final Fn.Presenter p;
+    private final Method m;
+    private Object result;
+    private Object inst;
+
+    SingleCase(Fn.Presenter p, Method m) {
+        this.p = p;
+        this.m = m;
+    }
+
+    @Override
+    public String getTestName() {
+        return m.getName();
+    }
+
+    @Test
+    public synchronized void executeTest() throws Exception {
+        if (result == null) {
+            JS.execute(this);
+            wait();
+        }
+        if (result instanceof Exception) {
+            throw (Exception)result;
+        }
+        if (result instanceof Error) {
+            throw (Error)result;
+        }
+    }
+
+    @Override
+    public synchronized void run() {
+        boolean notify = true;
+        try {
+            FnContext.currentPresenter(p);
+            if (inst == null) {
+                inst = m.getDeclaringClass().newInstance();
+            }
+            result = m.invoke(inst);
+            if (result == null) {
+                result = this;
+            }
+        } catch (InvocationTargetException ex) {
+            Throwable r = ex.getTargetException();
+            if (r instanceof InterruptedException) {
+                notify = false;
+                JS.execute(this);
+                return;
+            }
+            result = r;
+        } catch (Exception ex) {
+            result = ex;
+        } finally {
+            if (notify) {
+                notifyAll();
+            }
+            FnContext.currentPresenter(null);
+        }
+    }
+
+    @Override
+    public void run(IHookCallBack ihcb, ITestResult itr) {
+        ihcb.runTestMethod(itr);
+    }
+    
+}