# HG changeset patch # User Jaroslav Tulach # Date 1351596193 -3600 # Node ID a5f8cb32549e00307224a398f251641bbbbed6f8 # Parent 2085fbe399b6297606f489d6226abe502a2b1ab0 Allow multi-value @OnClick ids diff -r 2085fbe399b6 -r a5f8cb32549e htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/PageProcessor.java --- a/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/PageProcessor.java Tue Oct 30 09:26:54 2012 +0100 +++ b/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/PageProcessor.java Tue Oct 30 12:23:13 2012 +0100 @@ -39,6 +39,7 @@ import javax.lang.model.element.Modifier; import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; +import javax.lang.model.type.TypeMirror; import javax.tools.Diagnostic; import javax.tools.FileObject; import javax.tools.StandardLocation; @@ -138,6 +139,7 @@ } private boolean initializeOnClick(PackageElement pe, Writer w, ProcessPage pp) throws IOException { + TypeMirror stringType = processingEnv.getElementUtils().getTypeElement("java.lang.String").asType(); for (Element clazz : pe.getEnclosedElements()) { if (clazz.getKind() != ElementKind.CLASS) { continue; @@ -146,28 +148,40 @@ for (Element method : clazz.getEnclosedElements()) { OnClick oc = method.getAnnotation(OnClick.class); if (oc != null) { - if (pp.tagNameForId(oc.id()) == null) { - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "id = " + oc.id() + " does not exist in the HTML page. Found only " + pp.ids(), method); - return false; - } - ExecutableElement ee = (ExecutableElement)method; - if (!ee.getParameters().isEmpty()) { - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClose method can't take arguments", ee); - return false; - } - if (!ee.getModifiers().contains(Modifier.STATIC)) { - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClose method has to be static", ee); - return false; - } - if (ee.getModifiers().contains(Modifier.PRIVATE)) { - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClose method can't be private", ee); - return false; - } - w.append(" ").append(cnstnt(oc.id())). - append(".addOnClick(new Runnable() { public void run() {\n"); - w.append(" ").append(type.getSimpleName().toString()). - append('.').append(ee.getSimpleName()).append("();\n"); - w.append(" }});\n"); + for (String id : oc.id()) { + if (pp.tagNameForId(id) == null) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "id = " + oc.id() + " does not exist in the HTML page. Found only " + pp.ids(), method); + return false; + } + ExecutableElement ee = (ExecutableElement)method; + boolean hasParam; + if (ee.getParameters().isEmpty()) { + hasParam = false; + } else { + if (ee.getParameters().size() != 1 || ee.getParameters().get(0).asType() != stringType) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClick method should either have no arguments or one String argument", ee); + return false; + } + hasParam = true; + } + if (!ee.getModifiers().contains(Modifier.STATIC)) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClick method has to be static", ee); + return false; + } + if (ee.getModifiers().contains(Modifier.PRIVATE)) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClick method can't be private", ee); + return false; + } + w.append(" ").append(cnstnt(id)). + append(".addOnClick(new Runnable() { public void run() {\n"); + w.append(" ").append(type.getSimpleName().toString()). + append('.').append(ee.getSimpleName()).append("("); + if (hasParam) { + w.append("\"").append(id).append("\""); + } + w.append(");\n"); + w.append(" }});\n"); + } } } } diff -r 2085fbe399b6 -r a5f8cb32549e htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnClick.java --- a/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnClick.java Tue Oct 30 09:26:54 2012 +0100 +++ b/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnClick.java Tue Oct 30 12:23:13 2012 +0100 @@ -30,5 +30,5 @@ @Retention(RetentionPolicy.SOURCE) @Target(ElementType.METHOD) public @interface OnClick { - String id(); + String[] id(); } diff -r 2085fbe399b6 -r a5f8cb32549e htmlpage/src/test/java/org/apidesign/bck2brwsr/htmlpage/PageController.java --- a/htmlpage/src/test/java/org/apidesign/bck2brwsr/htmlpage/PageController.java Tue Oct 30 09:26:54 2012 +0100 +++ b/htmlpage/src/test/java/org/apidesign/bck2brwsr/htmlpage/PageController.java Tue Oct 30 12:23:13 2012 +0100 @@ -46,4 +46,12 @@ static void updateTitle() { TestPage.PG_TITLE.setText("You want this window to be named " + TestPage.PG_TEXT.getValue()); } + + @OnClick(id={ "pg.title", "pg.text" }) + static void click(String id) { + if (!id.equals("pg.title")) { + throw new IllegalStateException(); + } + TestPage.PG_TITLE.setText(id); + } } diff -r 2085fbe399b6 -r a5f8cb32549e htmlpage/src/test/java/org/apidesign/bck2brwsr/htmlpage/ProcessPageTest.java --- a/htmlpage/src/test/java/org/apidesign/bck2brwsr/htmlpage/ProcessPageTest.java Tue Oct 30 09:26:54 2012 +0100 +++ b/htmlpage/src/test/java/org/apidesign/bck2brwsr/htmlpage/ProcessPageTest.java Tue Oct 30 12:23:13 2012 +0100 @@ -81,6 +81,45 @@ } assertEquals(ret, "You want this window to be named something", "We expect that the JavaCode performs all the wiring"); } + + @Test public void clickWithArgumentCalled() throws Exception { + StringBuilder sb = new StringBuilder(); + sb.append( + "var window = new Object();\n" + + "var doc = new Object();\n" + + "doc.button = new Object();\n" + + "doc.title = new Object();\n" + + "doc.title.innerHTML = 'nothing';\n" + + "doc.text = new Object();\n" + + "doc.text.value = 'something';\n" + + "doc.getElementById = function(id) {\n" + + " switch(id) {\n" + + " case 'pg.button': return doc.button;\n" + + " case 'pg.title': return doc.title;\n" + + " case 'pg.text': return doc.text;\n" + + " }\n" + + " throw id;\n" + + " }\n" + + "\n" + + "function clickAndCheck() {\n" + + " doc.title.onclick();\n" + + " return doc.title.innerHTML.toString();\n" + + "};\n" + + "\n" + + "window.document = doc;\n" + ); + Invocable i = compileClass(sb, "org/apidesign/bck2brwsr/htmlpage/PageController"); + + Object ret = null; + try { + ret = i.invokeFunction("clickAndCheck"); + } catch (ScriptException ex) { + fail("Execution failed in " + sb, ex); + } catch (NoSuchMethodException ex) { + fail("Cannot find method in " + sb, ex); + } + assertEquals(ret, "pg.title", "Title has been passed to the method argument"); + } static Invocable compileClass(StringBuilder sb, String... names) throws ScriptException, IOException { if (sb == null) {