1.1 --- a/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/PageProcessor.java Tue Oct 30 09:26:54 2012 +0100
1.2 +++ b/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/PageProcessor.java Tue Oct 30 12:23:13 2012 +0100
1.3 @@ -39,6 +39,7 @@
1.4 import javax.lang.model.element.Modifier;
1.5 import javax.lang.model.element.PackageElement;
1.6 import javax.lang.model.element.TypeElement;
1.7 +import javax.lang.model.type.TypeMirror;
1.8 import javax.tools.Diagnostic;
1.9 import javax.tools.FileObject;
1.10 import javax.tools.StandardLocation;
1.11 @@ -138,6 +139,7 @@
1.12 }
1.13
1.14 private boolean initializeOnClick(PackageElement pe, Writer w, ProcessPage pp) throws IOException {
1.15 + TypeMirror stringType = processingEnv.getElementUtils().getTypeElement("java.lang.String").asType();
1.16 for (Element clazz : pe.getEnclosedElements()) {
1.17 if (clazz.getKind() != ElementKind.CLASS) {
1.18 continue;
1.19 @@ -146,28 +148,40 @@
1.20 for (Element method : clazz.getEnclosedElements()) {
1.21 OnClick oc = method.getAnnotation(OnClick.class);
1.22 if (oc != null) {
1.23 - if (pp.tagNameForId(oc.id()) == null) {
1.24 - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "id = " + oc.id() + " does not exist in the HTML page. Found only " + pp.ids(), method);
1.25 - return false;
1.26 - }
1.27 - ExecutableElement ee = (ExecutableElement)method;
1.28 - if (!ee.getParameters().isEmpty()) {
1.29 - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClose method can't take arguments", ee);
1.30 - return false;
1.31 - }
1.32 - if (!ee.getModifiers().contains(Modifier.STATIC)) {
1.33 - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClose method has to be static", ee);
1.34 - return false;
1.35 - }
1.36 - if (ee.getModifiers().contains(Modifier.PRIVATE)) {
1.37 - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClose method can't be private", ee);
1.38 - return false;
1.39 - }
1.40 - w.append(" ").append(cnstnt(oc.id())).
1.41 - append(".addOnClick(new Runnable() { public void run() {\n");
1.42 - w.append(" ").append(type.getSimpleName().toString()).
1.43 - append('.').append(ee.getSimpleName()).append("();\n");
1.44 - w.append(" }});\n");
1.45 + for (String id : oc.id()) {
1.46 + if (pp.tagNameForId(id) == null) {
1.47 + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "id = " + oc.id() + " does not exist in the HTML page. Found only " + pp.ids(), method);
1.48 + return false;
1.49 + }
1.50 + ExecutableElement ee = (ExecutableElement)method;
1.51 + boolean hasParam;
1.52 + if (ee.getParameters().isEmpty()) {
1.53 + hasParam = false;
1.54 + } else {
1.55 + if (ee.getParameters().size() != 1 || ee.getParameters().get(0).asType() != stringType) {
1.56 + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClick method should either have no arguments or one String argument", ee);
1.57 + return false;
1.58 + }
1.59 + hasParam = true;
1.60 + }
1.61 + if (!ee.getModifiers().contains(Modifier.STATIC)) {
1.62 + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClick method has to be static", ee);
1.63 + return false;
1.64 + }
1.65 + if (ee.getModifiers().contains(Modifier.PRIVATE)) {
1.66 + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClick method can't be private", ee);
1.67 + return false;
1.68 + }
1.69 + w.append(" ").append(cnstnt(id)).
1.70 + append(".addOnClick(new Runnable() { public void run() {\n");
1.71 + w.append(" ").append(type.getSimpleName().toString()).
1.72 + append('.').append(ee.getSimpleName()).append("(");
1.73 + if (hasParam) {
1.74 + w.append("\"").append(id).append("\"");
1.75 + }
1.76 + w.append(");\n");
1.77 + w.append(" }});\n");
1.78 + }
1.79 }
1.80 }
1.81 }
2.1 --- a/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnClick.java Tue Oct 30 09:26:54 2012 +0100
2.2 +++ b/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnClick.java Tue Oct 30 12:23:13 2012 +0100
2.3 @@ -30,5 +30,5 @@
2.4 @Retention(RetentionPolicy.SOURCE)
2.5 @Target(ElementType.METHOD)
2.6 public @interface OnClick {
2.7 - String id();
2.8 + String[] id();
2.9 }
3.1 --- a/htmlpage/src/test/java/org/apidesign/bck2brwsr/htmlpage/PageController.java Tue Oct 30 09:26:54 2012 +0100
3.2 +++ b/htmlpage/src/test/java/org/apidesign/bck2brwsr/htmlpage/PageController.java Tue Oct 30 12:23:13 2012 +0100
3.3 @@ -46,4 +46,12 @@
3.4 static void updateTitle() {
3.5 TestPage.PG_TITLE.setText("You want this window to be named " + TestPage.PG_TEXT.getValue());
3.6 }
3.7 +
3.8 + @OnClick(id={ "pg.title", "pg.text" })
3.9 + static void click(String id) {
3.10 + if (!id.equals("pg.title")) {
3.11 + throw new IllegalStateException();
3.12 + }
3.13 + TestPage.PG_TITLE.setText(id);
3.14 + }
3.15 }
4.1 --- a/htmlpage/src/test/java/org/apidesign/bck2brwsr/htmlpage/ProcessPageTest.java Tue Oct 30 09:26:54 2012 +0100
4.2 +++ b/htmlpage/src/test/java/org/apidesign/bck2brwsr/htmlpage/ProcessPageTest.java Tue Oct 30 12:23:13 2012 +0100
4.3 @@ -81,6 +81,45 @@
4.4 }
4.5 assertEquals(ret, "You want this window to be named something", "We expect that the JavaCode performs all the wiring");
4.6 }
4.7 +
4.8 + @Test public void clickWithArgumentCalled() throws Exception {
4.9 + StringBuilder sb = new StringBuilder();
4.10 + sb.append(
4.11 + "var window = new Object();\n"
4.12 + + "var doc = new Object();\n"
4.13 + + "doc.button = new Object();\n"
4.14 + + "doc.title = new Object();\n"
4.15 + + "doc.title.innerHTML = 'nothing';\n"
4.16 + + "doc.text = new Object();\n"
4.17 + + "doc.text.value = 'something';\n"
4.18 + + "doc.getElementById = function(id) {\n"
4.19 + + " switch(id) {\n"
4.20 + + " case 'pg.button': return doc.button;\n"
4.21 + + " case 'pg.title': return doc.title;\n"
4.22 + + " case 'pg.text': return doc.text;\n"
4.23 + + " }\n"
4.24 + + " throw id;\n"
4.25 + + " }\n"
4.26 + + "\n"
4.27 + + "function clickAndCheck() {\n"
4.28 + + " doc.title.onclick();\n"
4.29 + + " return doc.title.innerHTML.toString();\n"
4.30 + + "};\n"
4.31 + + "\n"
4.32 + + "window.document = doc;\n"
4.33 + );
4.34 + Invocable i = compileClass(sb, "org/apidesign/bck2brwsr/htmlpage/PageController");
4.35 +
4.36 + Object ret = null;
4.37 + try {
4.38 + ret = i.invokeFunction("clickAndCheck");
4.39 + } catch (ScriptException ex) {
4.40 + fail("Execution failed in " + sb, ex);
4.41 + } catch (NoSuchMethodException ex) {
4.42 + fail("Cannot find method in " + sb, ex);
4.43 + }
4.44 + assertEquals(ret, "pg.title", "Title has been passed to the method argument");
4.45 + }
4.46
4.47 static Invocable compileClass(StringBuilder sb, String... names) throws ScriptException, IOException {
4.48 if (sb == null) {