Now we are able to change a title of a page inside of a browser emul
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Thu, 11 Oct 2012 06:15:22 -0700
branchemul
changeset 100029e6eed60e9
parent 99 67e892757752
child 101 ff3f0de0b8a2
child 553 388e48c0a37a
Now we are able to change a title of a page inside of a browser
htmlpage/pom.xml
htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/PageProcessor.java
htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Element.java
htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Element.js
htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Input.java
htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Page.java
htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Title.java
htmlpage/src/test/java/org/apidesign/bck2brwsr/htmlpage/PageController.java
htmlpage/src/test/java/org/apidesign/bck2brwsr/htmlpage/ProcessPageTest.java
htmlpage/src/test/java/org/apidesign/bck2brwsr/htmlpage/package-info.java
htmlpage/src/test/resources/org/apidesign/bck2brwsr/htmlpage/TestPage.html
htmlpage/src/test/resources/org/apidesign/bck2brwsr/htmlpage/TestPage.xhtml
vm/pom.xml
     1.1 --- a/htmlpage/pom.xml	Thu Oct 11 04:11:42 2012 -0700
     1.2 +++ b/htmlpage/pom.xml	Thu Oct 11 06:15:22 2012 -0700
     1.3 @@ -31,6 +31,25 @@
     1.4        <groupId>org.netbeans.api</groupId>
     1.5        <artifactId>org-openide-util-lookup</artifactId>
     1.6      </dependency>
     1.7 +    <dependency>
     1.8 +      <groupId>org.apidesign.bck2brwsr</groupId>
     1.9 +      <artifactId>core</artifactId>
    1.10 +      <version>1.0-SNAPSHOT</version>
    1.11 +      <type>jar</type>
    1.12 +    </dependency>
    1.13 +    <dependency>
    1.14 +      <groupId>org.apidesign.bck2brwsr</groupId>
    1.15 +      <artifactId>emul</artifactId>
    1.16 +      <version>1.0-SNAPSHOT</version>
    1.17 +      <type>jar</type>
    1.18 +    </dependency>
    1.19 +    <dependency>
    1.20 +      <groupId>org.apidesign.bck2brwsr</groupId>
    1.21 +      <artifactId>vm4brwsr</artifactId>
    1.22 +      <version>0.1-SNAPSHOT</version>
    1.23 +      <type>jar</type>
    1.24 +      <scope>test</scope>
    1.25 +    </dependency>
    1.26    </dependencies>
    1.27      <build>
    1.28          <plugins>
     2.1 --- a/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/PageProcessor.java	Thu Oct 11 04:11:42 2012 -0700
     2.2 +++ b/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/PageProcessor.java	Thu Oct 11 06:15:22 2012 -0700
     2.3 @@ -55,7 +55,7 @@
     2.4      public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
     2.5          for (Element e : roundEnv.getElementsAnnotatedWith(Page.class)) {
     2.6              Page p = e.getAnnotation(Page.class);
     2.7 -            PackageElement pe = (PackageElement)e;
     2.8 +            PackageElement pe = (PackageElement)e.getEnclosingElement();
     2.9              String pkg = pe.getQualifiedName().toString();
    2.10              
    2.11              ProcessPage pp;
     3.1 --- a/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Element.java	Thu Oct 11 04:11:42 2012 -0700
     3.2 +++ b/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Element.java	Thu Oct 11 06:15:22 2012 -0700
     3.3 @@ -17,6 +17,8 @@
     3.4   */
     3.5  package org.apidesign.bck2brwsr.htmlpage.api;
     3.6  
     3.7 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
     3.8 +
     3.9  /** Represents a generic HTML element.
    3.10   *
    3.11   * @author Jaroslav Tulach <jtulach@netbeans.org>
    3.12 @@ -30,14 +32,33 @@
    3.13      
    3.14      abstract void dontSubclass();
    3.15      
    3.16 +    @JavaScriptBody(
    3.17 +        args={"el", "property", "value"},
    3.18 +        body="var e = window.document.getElementById(el.id);\n"
    3.19 +           + "e[property] = value;\n"
    3.20 +    )
    3.21      static void setAttribute(Element el, String property, Object value) {
    3.22          throw new UnsupportedOperationException("Needs JavaScript!");
    3.23      }
    3.24 +
    3.25 +    @JavaScriptBody(
    3.26 +        args={"el", "property"},
    3.27 +        body="var e = window.document.getElementById(el.id);\n"
    3.28 +           + "return e[property];\n"
    3.29 +    )
    3.30 +    static Object getAttribute(Element el, String property) {
    3.31 +        throw new UnsupportedOperationException("Needs JavaScript!");
    3.32 +    }
    3.33      
    3.34      /** Executes given runnable when user performs a "click" on the given
    3.35       * element.
    3.36       * @param r the runnable to execute, never null
    3.37       */
    3.38 +    @JavaScriptBody(
    3.39 +        args={"el", "r"},
    3.40 +        body="var e = window.document.getElementById(el.id);\n"
    3.41 +           + "e.onclick = function() { r.runV(); };\n"
    3.42 +    )
    3.43      public final void addOnClick(Runnable r) {
    3.44          throw new UnsupportedOperationException("Needs JavaScript!");
    3.45      }
     4.1 --- a/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Element.js	Thu Oct 11 04:11:42 2012 -0700
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,10 +0,0 @@
     4.4 -
     4.5 -
     4.6 -function org_apidesign_bck2brwsr_htmlpage_api_Element_setAttribute_Lorg_apidesign_bck2brwsr_htmlpage_api_ElementLjava_lang_StringLjava_lang_Object(self, property, value) {
     4.7 -    document.getElementById(self.id)[property] = value;
     4.8 -}
     4.9 -
    4.10 -function org_apidesign_bck2brwsr_htmlpage_api_Element_addOnClick_Ljava_lang_Runnable(self, run) {
    4.11 -    document.getElementById(self.id).onClick = function() { run.runV(); };
    4.12 -}
    4.13 -
     5.1 --- a/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Input.java	Thu Oct 11 04:11:42 2012 -0700
     5.2 +++ b/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Input.java	Thu Oct 11 06:15:22 2012 -0700
     5.3 @@ -31,6 +31,10 @@
     5.4      }
     5.5      
     5.6      public void setAutocomplete(boolean state) {
     5.7 -        setAttribute(this, "autocomplete", state);
     5.8 +        Element.setAttribute(this, "autocomplete", state);
     5.9 +    }
    5.10 +    
    5.11 +    public final String getValue() {
    5.12 +        return (String)Element.getAttribute(this, "value");
    5.13      }
    5.14  }
     6.1 --- a/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Page.java	Thu Oct 11 04:11:42 2012 -0700
     6.2 +++ b/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Page.java	Thu Oct 11 06:15:22 2012 -0700
     6.3 @@ -32,7 +32,7 @@
     6.4   * @author Jaroslav Tulach <jtulach@netbeans.org>
     6.5   */
     6.6  @Retention(RetentionPolicy.SOURCE)
     6.7 -@Target(ElementType.PACKAGE)
     6.8 +@Target(ElementType.TYPE)
     6.9  public @interface Page {
    6.10      /** Path to the XHTML page to read in */
    6.11      String xhtml();
     7.1 --- a/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Title.java	Thu Oct 11 04:11:42 2012 -0700
     7.2 +++ b/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Title.java	Thu Oct 11 06:15:22 2012 -0700
     7.3 @@ -29,4 +29,8 @@
     7.4      @Override
     7.5      void dontSubclass() {
     7.6      }
     7.7 +    
     7.8 +    public final void setText(String text) {
     7.9 +        Element.setAttribute(this, "innerHTML", text);
    7.10 +    }
    7.11  }
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/htmlpage/src/test/java/org/apidesign/bck2brwsr/htmlpage/PageController.java	Thu Oct 11 06:15:22 2012 -0700
     8.3 @@ -0,0 +1,32 @@
     8.4 +package org.apidesign.bck2brwsr.htmlpage;
     8.5 +
     8.6 +import org.apidesign.bck2brwsr.htmlpage.api.OnClick;
     8.7 +import org.apidesign.bck2brwsr.htmlpage.api.Page;
     8.8 +
     8.9 +/** Trivial demo for the bck2brwsr project. First of all start
    8.10 + * with <a href="TestPage.html">your XHTML page</a>. Include there
    8.11 + * a script that will <em>boot Java</em> in your browser.
    8.12 + * <p>
    8.13 + * Then use <code>@Page</code> annotation to 
    8.14 + * generate a Java representation of elements with IDs in that page.
    8.15 + * Depending on the type of the elements, they will have different 
    8.16 + * methods (e.g. <code>PG_TITLE</code> has <code>setText</code>, etc.).
    8.17 + * Use <code>@OnClick</code> annotation to associate behavior
    8.18 + * with existing elements. Use the generated elements
    8.19 + * (<code>PG_TITLE</code>, <code>PG_TEXT</code>) to modify the page.
    8.20 + * <p>
    8.21 + * Everything is type-safe. As soon as somebody modifies the page and
    8.22 + * removes the IDs or re-assigns them to wrong elements. Java compiler
    8.23 + * will emit an error.
    8.24 + * <p>
    8.25 + * Welcome to the type-safe HTML5 world!
    8.26 + *
    8.27 + * @author Jaroslav Tulach <jtulach@netbeans.org>
    8.28 + */
    8.29 +@Page(xhtml="TestPage.html", name="TestPage")
    8.30 +public class PageController {
    8.31 +    @OnClick(id="pg.button")
    8.32 +    static void updateTitle() {
    8.33 +        TestPage.PG_TITLE.setText(TestPage.PG_TEXT.getValue());
    8.34 +    }
    8.35 +}
     9.1 --- a/htmlpage/src/test/java/org/apidesign/bck2brwsr/htmlpage/ProcessPageTest.java	Thu Oct 11 04:11:42 2012 -0700
     9.2 +++ b/htmlpage/src/test/java/org/apidesign/bck2brwsr/htmlpage/ProcessPageTest.java	Thu Oct 11 06:15:22 2012 -0700
     9.3 @@ -19,17 +19,20 @@
     9.4  
     9.5  import java.io.IOException;
     9.6  import java.io.InputStream;
     9.7 +import java.lang.reflect.Method;
     9.8  import java.util.Set;
     9.9 +import javax.script.Invocable;
    9.10 +import javax.script.ScriptEngine;
    9.11 +import javax.script.ScriptEngineManager;
    9.12 +import javax.script.ScriptException;
    9.13  import org.testng.annotations.Test;
    9.14  import static org.testng.Assert.*;
    9.15  
    9.16 -import org.apidesign.bck2brwsr.htmlpage.api.*;
    9.17 -
    9.18  public class ProcessPageTest {
    9.19      
    9.20      
    9.21      @Test public void findsThreeIds() throws IOException {
    9.22 -        InputStream is = ProcessPageTest.class.getResourceAsStream("TestPage.xhtml");
    9.23 +        InputStream is = ProcessPageTest.class.getResourceAsStream("TestPage.html");
    9.24          assertNotNull(is, "Sample HTML page found");
    9.25          ProcessPage res = ProcessPage.readPage(is);
    9.26          final Set<String> ids = res.ids();
    9.27 @@ -40,16 +43,67 @@
    9.28          assertEquals(res.tagNameForId("pg.text"), "input");
    9.29      }
    9.30      
    9.31 -    void testWhetherWeCanCallTheGeneratedIdFields() {
    9.32 -        Title t = TestPage.PG_TITLE;
    9.33 +    @Test public void testCompileAndRunPageController() throws Exception {
    9.34 +        StringBuilder sb = new StringBuilder();
    9.35 +        sb.append(
    9.36 +              "var window = new Object();\n"
    9.37 +            + "var doc = new Object();\n"
    9.38 +            + "doc.button = new Object();\n"
    9.39 +            + "doc.title = new Object();\n"
    9.40 +            + "doc.title.innerHTML = 'nothing';\n"
    9.41 +            + "doc.text = new Object();\n"
    9.42 +            + "doc.text.value = 'something';\n"
    9.43 +            + "doc.getElementById = function(id) {\n"
    9.44 +            + "    switch(id) {\n"
    9.45 +            + "      case 'pg.button': return doc.button;\n"
    9.46 +            + "      case 'pg.title': return doc.title;\n"
    9.47 +            + "      case 'pg.text': return doc.text;\n"
    9.48 +            + "    }\n"
    9.49 +            + "    throw id;\n"
    9.50 +            + "  }\n"
    9.51 +            + "\n"
    9.52 +            + "function clickAndCheck() {\n"
    9.53 +            + "  doc.button.onclick();\n"
    9.54 +            + "  return doc.title.innerHTML.toString();\n"
    9.55 +            + "};\n"
    9.56 +            + "\n"
    9.57 +            + "window.document = doc;\n"
    9.58 +        );
    9.59 +        Invocable i = compileClass(sb, "org/apidesign/bck2brwsr/htmlpage/PageController");
    9.60 +
    9.61 +        Object ret = null;
    9.62 +        try {
    9.63 +            ret = i.invokeFunction("clickAndCheck");
    9.64 +        } catch (ScriptException ex) {
    9.65 +            fail("Execution failed in " + sb, ex);
    9.66 +        } catch (NoSuchMethodException ex) {
    9.67 +            fail("Cannot find method in " + sb, ex);
    9.68 +        }
    9.69 +        assertEquals(ret, "something", "We expect that the JavaCode performs all the wiring");
    9.70      }
    9.71 -    
    9.72 -    @OnClick(id="pg.button")
    9.73 -    static void handleButtonClick() {
    9.74 -        
    9.75 -    }
    9.76 -    
    9.77 -    @Test public void testOnclickHandlerGenerated() {
    9.78 -        
    9.79 +
    9.80 +    static Invocable compileClass(StringBuilder sb, String... names) throws ScriptException, IOException {
    9.81 +        if (sb == null) {
    9.82 +            sb = new StringBuilder();
    9.83 +        }
    9.84 +        try {
    9.85 +            Method m;
    9.86 +            Class<?> genJS = Class.forName("org.apidesign.vm4brwsr.GenJS");
    9.87 +            m = genJS.getDeclaredMethod("compile", Appendable.class, String[].class);
    9.88 +            m.setAccessible(true);
    9.89 +            m.invoke(null, sb, names);
    9.90 +        } catch (Exception exception) {
    9.91 +            throw new IOException(exception);
    9.92 +        }
    9.93 +        ScriptEngineManager sem = new ScriptEngineManager();
    9.94 +        ScriptEngine js = sem.getEngineByExtension("js");
    9.95 +        try {
    9.96 +            Object res = js.eval(sb.toString());
    9.97 +            assertTrue(js instanceof Invocable, "It is invocable object: " + res);
    9.98 +            return (Invocable) js;
    9.99 +        } catch (ScriptException ex) {
   9.100 +            fail("Could not compile:\n" + sb, ex);
   9.101 +            return null;
   9.102 +        }
   9.103      }
   9.104  }
    10.1 --- a/htmlpage/src/test/java/org/apidesign/bck2brwsr/htmlpage/package-info.java	Thu Oct 11 04:11:42 2012 -0700
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,22 +0,0 @@
    10.4 -/**
    10.5 - * Java 4 Browser Bytecode Translator
    10.6 - * Copyright (C) 2012-2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    10.7 - *
    10.8 - * This program is free software: you can redistribute it and/or modify
    10.9 - * it under the terms of the GNU General Public License as published by
   10.10 - * the Free Software Foundation, version 2 of the License.
   10.11 - *
   10.12 - * This program is distributed in the hope that it will be useful,
   10.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   10.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   10.15 - * GNU General Public License for more details.
   10.16 - *
   10.17 - * You should have received a copy of the GNU General Public License
   10.18 - * along with this program. Look for COPYING file in the top folder.
   10.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   10.20 - */
   10.21 -@Page(xhtml="TestPage.xhtml", name="TestPage")
   10.22 -package org.apidesign.bck2brwsr.htmlpage;
   10.23 -
   10.24 -import org.apidesign.bck2brwsr.htmlpage.api.Page;
   10.25 -
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/htmlpage/src/test/resources/org/apidesign/bck2brwsr/htmlpage/TestPage.html	Thu Oct 11 06:15:22 2012 -0700
    11.3 @@ -0,0 +1,30 @@
    11.4 +<?xml version="1.0" encoding="UTF-8"?>
    11.5 +<!--
    11.6 +
    11.7 +    Java 4 Browser Bytecode Translator
    11.8 +    Copyright (C) 2012-2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    11.9 +
   11.10 +    This program is free software: you can redistribute it and/or modify
   11.11 +    it under the terms of the GNU General Public License as published by
   11.12 +    the Free Software Foundation, version 2 of the License.
   11.13 +
   11.14 +    This program is distributed in the hope that it will be useful,
   11.15 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   11.16 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   11.17 +    GNU General Public License for more details.
   11.18 +
   11.19 +    You should have received a copy of the GNU General Public License
   11.20 +    along with this program. Look for COPYING file in the top folder.
   11.21 +    If not, see http://opensource.org/licenses/GPL-2.0.
   11.22 +
   11.23 +-->
   11.24 +<!DOCTYPE html>
   11.25 +<html xmlns="http://www.w3.org/1999/xhtml">
   11.26 +    <head>
   11.27 +        <title id="pg.title">Default Title</title>
   11.28 +    </head>
   11.29 +    <body>
   11.30 +        New title: <input id="pg.text"/>
   11.31 +        <button id="pg.button">Change title!</button>
   11.32 +    </body>
   11.33 +</html>
    12.1 --- a/htmlpage/src/test/resources/org/apidesign/bck2brwsr/htmlpage/TestPage.xhtml	Thu Oct 11 04:11:42 2012 -0700
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,30 +0,0 @@
    12.4 -<?xml version="1.0" encoding="UTF-8"?>
    12.5 -<!--
    12.6 -
    12.7 -    Java 4 Browser Bytecode Translator
    12.8 -    Copyright (C) 2012-2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    12.9 -
   12.10 -    This program is free software: you can redistribute it and/or modify
   12.11 -    it under the terms of the GNU General Public License as published by
   12.12 -    the Free Software Foundation, version 2 of the License.
   12.13 -
   12.14 -    This program is distributed in the hope that it will be useful,
   12.15 -    but WITHOUT ANY WARRANTY; without even the implied warranty of
   12.16 -    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12.17 -    GNU General Public License for more details.
   12.18 -
   12.19 -    You should have received a copy of the GNU General Public License
   12.20 -    along with this program. Look for COPYING file in the top folder.
   12.21 -    If not, see http://opensource.org/licenses/GPL-2.0.
   12.22 -
   12.23 --->
   12.24 -<!DOCTYPE html>
   12.25 -<html xmlns="http://www.w3.org/1999/xhtml">
   12.26 -    <head>
   12.27 -        <title id="pg.title">Default Title</title>
   12.28 -    </head>
   12.29 -    <body>
   12.30 -        New title: <input id="pg.text"/>
   12.31 -        <button id="pg.button">Change title!</button>
   12.32 -    </body>
   12.33 -</html>
    13.1 --- a/vm/pom.xml	Thu Oct 11 04:11:42 2012 -0700
    13.2 +++ b/vm/pom.xml	Thu Oct 11 06:15:22 2012 -0700
    13.3 @@ -7,7 +7,7 @@
    13.4      <version>1.0-SNAPSHOT</version>
    13.5    </parent>
    13.6  
    13.7 -  <groupId>org.apidesign</groupId>
    13.8 +  <groupId>org.apidesign.bck2brwsr</groupId>
    13.9    <artifactId>vm4brwsr</artifactId>
   13.10    <version>0.1-SNAPSHOT</version>
   13.11    <packaging>jar</packaging>