# HG changeset patch # User Jaroslav Tulach # Date 1365073937 -7200 # Node ID 9a7df12648b9d95e689dd7b33c381298dfdcf89f # Parent e8916518b38d6ba512a97cc1ac641e48cb52440b Knockout.js Twitter client example rewritten to Bck2Brwsr (just missing JSON access to tweets) diff -r e8916518b38d -r 9a7df12648b9 javaquery/demo-twitter/bck2brwsr-assembly.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javaquery/demo-twitter/bck2brwsr-assembly.xml Thu Apr 04 13:12:17 2013 +0200 @@ -0,0 +1,71 @@ + + + + + bck2brwsr + + zip + + public_html + + + false + runtime + lib + + *:jar + *:rt + + + + false + provided + + *:js + + true + / + + + + + ${project.build.directory}/${project.build.finalName}.jar + / + + + ${project.build.directory}/classes/org/apidesign/bck2brwsr/demo/twitter/index.html + / + index.html + + + ${project.build.directory}/classes/org/apidesign/bck2brwsr/demo/twitter/twitterExample.css + / + twitterExample.css + + + ${project.build.directory}/classes/org/apidesign/bck2brwsr/demo/twitter/twitterApi.js + / + twitterApi.js + + + + \ No newline at end of file diff -r e8916518b38d -r 9a7df12648b9 javaquery/demo-twitter/nb-configuration.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javaquery/demo-twitter/nb-configuration.xml Thu Apr 04 13:12:17 2013 +0200 @@ -0,0 +1,37 @@ + + + + + + + none + + diff -r e8916518b38d -r 9a7df12648b9 javaquery/demo-twitter/nbactions.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javaquery/demo-twitter/nbactions.xml Thu Apr 04 13:12:17 2013 +0200 @@ -0,0 +1,29 @@ + + + + + run + + process-classes + org.apidesign.bck2brwsr:mojo:0.6-SNAPSHOT:brwsr + + + diff -r e8916518b38d -r 9a7df12648b9 javaquery/demo-twitter/pom.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javaquery/demo-twitter/pom.xml Thu Apr 04 13:12:17 2013 +0200 @@ -0,0 +1,141 @@ + + + 4.0.0 + + javaquery + org.apidesign.bck2brwsr + 0.6-SNAPSHOT + + + org.apidesign.bck2brwsr + demo-twitter + 0.6-SNAPSHOT + jar + + Bck2Brwsr's Twttr + + Rewrite of knockoutjs example to use model written in Java and + execute using Bck2Brwsr virtual machine. + + + + + java.net + Java.net + https://maven.java.net/content/repositories/releases/ + + + + + netbeans + NetBeans + http://bits.netbeans.org/maven2/ + + + + + java.net + Java.net + https://maven.java.net/content/repositories/releases/ + + + + + + + UTF-8 + + + + + org.apidesign.bck2brwsr + mojo + 0.6-SNAPSHOT + + + + brwsr + + + + + org/apidesign/bck2brwsr/demo/twitter/index.html + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.7 + 1.7 + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + + true + lib/ + + + + + + maven-assembly-plugin + 2.4 + + + distro-assembly + package + + single + + + + bck2brwsr-assembly.xml + + + + + + + + + + + org.apidesign.bck2brwsr + emul + 0.6-SNAPSHOT + rt + + + org.apidesign.bck2brwsr + javaquery.api + 0.6-SNAPSHOT + + + org.testng + testng + 6.5.2 + test + + + org.apidesign.bck2brwsr + vm4brwsr + js + zip + 0.6-SNAPSHOT + provided + + + org.apidesign.bck2brwsr + vmtest + 0.6-SNAPSHOT + test + + + diff -r e8916518b38d -r 9a7df12648b9 javaquery/demo-twitter/src/main/java/org/apidesign/bck2brwsr/demo/twitter/TwitterClient.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javaquery/demo-twitter/src/main/java/org/apidesign/bck2brwsr/demo/twitter/TwitterClient.java Thu Apr 04 13:12:17 2013 +0200 @@ -0,0 +1,137 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.demo.twitter; + +import java.util.Arrays; +import java.util.List; +import org.apidesign.bck2brwsr.htmlpage.api.*; +import org.apidesign.bck2brwsr.htmlpage.api.Page; +import org.apidesign.bck2brwsr.htmlpage.api.Property; +import org.apidesign.bck2brwsr.htmlpage.api.ComputedProperty; + +/** Controller class for access to Twitter. + * + * @author Jaroslav Tulach + */ +@Page(xhtml="index.html", className="TwitterModel", properties={ + @Property(name="savedLists", type=TwitterClient.Twttrs.class, array = true), + @Property(name="activeTweetersName", type=String.class), + @Property(name="modifiedList", type=TwitterClient.Twttrs.class), + @Property(name="userNameToAdd", type=String.class), + @Property(name="currentTweets", type=String.class, array = true) +}) +public class TwitterClient { + @Model(className = "Tweeters", properties = { + @Property(name="name", type = String.class), + @Property(name="userNames", type = String.class, array = true) + }) + static class Twttrs { + } + + private static Tweeters tweeters(String listName, String... userNames) { + Tweeters t = new Tweeters(); + t.setName(listName); + t.getUserNames().addAll(Arrays.asList(userNames)); + return t; + } + + static { + final TwitterModel model = new TwitterModel(); + final List svdLst = model.getSavedLists(); + svdLst.add(tweeters("API Design", "JaroslavTulach")); + svdLst.add(tweeters("Celebrities", "JohnCleese", "MCHammer", "StephenFry", "algore", "StevenSanderson")); + svdLst.add(tweeters("Microsoft people", "BillGates", "shanselman", "ScottGu")); + svdLst.add(tweeters("NetBeans", "GeertjanW","monacotoni", "NetBeans")); + svdLst.add(tweeters("Tech pundits", "Scobleizer", "LeoLaporte", "techcrunch", "BoingBoing", "timoreilly", "codinghorror")); + + model.setActiveTweetersName("NetBeans"); + + model.applyBindings(); + } + + @ComputedProperty + static Tweeters activeTweeters(String activeTweetersName, List savedLists, Tweeters modifiedList) { + if (modifiedList != null && modifiedList.getName() != null) { + if (modifiedList.getName().equals(activeTweetersName)) { + return modifiedList; + } else { + modifiedList.setName(null); + } + } + return findByName(savedLists, activeTweetersName); + } + + @ComputedProperty + static boolean hasUnsavedChanges(Tweeters modifiedList) { + return modifiedList != null; + } + + @ComputedProperty + static boolean userNameToAddIsValid(String userNameToAdd, String activeTweetersName, List savedLists, Tweeters modifiedList) { + Tweeters editingList = activeTweeters(activeTweetersName, savedLists, modifiedList); + return editingList != null && userNameToAdd != null && + userNameToAdd.matches("[a-zA-Z0-9_]{1,15}") && + !editingList.getUserNames().contains(userNameToAdd); + } + + @OnFunction + static void deleteList(TwitterModel model) { + final List sl = model.getSavedLists(); + sl.remove(model.getActiveTweeters()); + if (sl.isEmpty()) { + final Tweeters t = new Tweeters(); + t.setName("New"); + sl.add(t); + } + model.setActiveTweetersName(sl.get(0).getName()); + } + + @OnFunction + static void saveChanges(TwitterModel model) { + Tweeters t = findByName(model.getSavedLists(), model.getActiveTweetersName()); + int indx = model.getSavedLists().indexOf(t); + assert indx != -1; + model.getSavedLists().set(indx, model.getModifiedList()); + model.setModifiedList(null); + } + + @OnFunction + static void addUser(TwitterModel model) { + String n = model.getUserNameToAdd(); + findModifiedList(model).getUserNames().add(n); + } + @OnFunction + static void removeUser(String data, TwitterModel model) { + findModifiedList(model).getUserNames().remove(data); + } + + private static Tweeters findModifiedList(TwitterModel model) { + if (model.getModifiedList() == null || model.getModifiedList().getName() == null) { + model.setModifiedList(model.getActiveTweeters().clone()); + } + return model.getModifiedList(); + } + private static Tweeters findByName(List list, String name) { + for (Tweeters l : list) { + if (l.getName() != null && l.getName().equals(name)) { + return l; + } + } + return list.isEmpty() ? null : list.get(0); + } +} diff -r e8916518b38d -r 9a7df12648b9 javaquery/demo-twitter/src/main/resources/org/apidesign/bck2brwsr/demo/twitter/index.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javaquery/demo-twitter/src/main/resources/org/apidesign/bck2brwsr/demo/twitter/index.html Thu Apr 04 13:12:17 2013 +0200 @@ -0,0 +1,99 @@ + + + + + + + + + Bck2Brwsr's Twitter + + + + + + + + + +

Bck2Brwsr's Twitter

+ +

+ This code based on original knockout.js Twitter example and + uses almost unmodified HTML code. It just changes the model. It + is written in Java language and it is executed using Bck2Brwsr + virtual machine. +

+ +
+
+
+ + + +
+ +

Currently viewing user(s):

+
+
    +
  • + +
    +
  • +
+
+ +
+ + + +
+
+
+
Loading...
+ + + + + +
+ + +
+
+
+
+ + + + + + + diff -r e8916518b38d -r 9a7df12648b9 javaquery/demo-twitter/src/main/resources/org/apidesign/bck2brwsr/demo/twitter/twitterExample.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javaquery/demo-twitter/src/main/resources/org/apidesign/bck2brwsr/demo/twitter/twitterExample.css Thu Apr 04 13:12:17 2013 +0200 @@ -0,0 +1,50 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ + +/* + Copied from knockout.js Twitter example: + http://knockoutjs.com/examples/twitter.html +*/ + +.configuration, .tweets, .tweets td { font-family: Verdana; font-size: 13px; } +.configuration { background-color: #DEDEDE; border: 2px solid gray; float:left; height: 40em; width: 40%; padding: 0.5em; border-right-width:0; } +.tweets { width: 55%; border: 2px solid gray; height: 40em; overflow: scroll; overflow-x: hidden; background-color: Black; color: White; padding: 0.5em; position: relative; } +.tweets table { border-width: 0;} +.tweets tr { vertical-align: top; } +.tweets td { padding: 0.4em 0.3em 1em 0.4em; border-width: 0; } +.tweets img { width: 4em; } +.tweetInfo { color: Gray; font-size: 0.9em; } +.twitterUser { color: #77AAFF; text-decoration: none; font-size: 1.1em; font-weight: bold; } +input.invalid { border: 1px solid red !important; background-color: #FFAAAA !important; } + +.listChooser select, .listChooser button { vertical-align:top; } +.listChooser select { width: 60%; font-size:1.2em; height:1.4em; } +.listChooser button { width: 19%; height:1.68em; float:right; } + +.currentUsers { height: 28em; overflow-y: auto; overflow-x: hidden; } +.currentUsers button { float: right; height: 2.5em; margin: 0.1em; padding-left: 1em; padding-right: 1em; } +.currentUsers ul, .configuration li { list-style: none; margin: 0; padding: 0 } +.currentUsers li { height: 2.4em; font-size: 1.2em; background-color: #A7D0E3; border: 1px solid gray; margin-bottom: 0.3em; -webkit-border-radius: 5px; -moz-border-radius: 5px; -webkit-box-shadow: 0 0.2em 0.5em gray; -moz-box-shadow: 0 0.2em 0.5em gray; } +.currentUsers li div { padding: 0.6em; } +.currentUsers li:hover { background-color: #EEC; } + +.configuration form label { width: 25%; display: inline-block; text-align:right; overflow: hidden; } +.configuration form input { width:40%; font-size: 1.3em; border:1px solid silver; background-color: White; padding: 0.1em; } +.configuration form button { width: 20%; margin-left: 0.3em; height: 2em; } + +.loadingIndicator { position: absolute; top: 0.1em; left: 0.1em; font: 0.8em Arial; background-color: #229; color: White; padding: 0.2em 0.5em 0.2em 0.5em; display: none; } diff -r e8916518b38d -r 9a7df12648b9 javaquery/demo-twitter/src/test/java/org/apidesign/bck2brwsr/demo/twitter/TwitterClientTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javaquery/demo-twitter/src/test/java/org/apidesign/bck2brwsr/demo/twitter/TwitterClientTest.java Thu Apr 04 13:12:17 2013 +0200 @@ -0,0 +1,66 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.demo.twitter; + +import static org.testng.Assert.*; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +/** We can unit test the TwitterModel smoothly. + * + * @author Jaroslav Tulach + */ +public class TwitterClientTest { + private TwitterModel model; + + + @BeforeMethod + public void initModel() { + model = new TwitterModel().applyBindings(); + } + + @Test public void testIsValidToAdd() { + model.setUserNameToAdd("Joe"); + Tweeters t = new Tweeters(); + t.setName("test"); + model.getSavedLists().add(t); + model.setActiveTweetersName("test"); + + assertTrue(model.isUserNameToAddIsValid(), "Joe is OK"); + TwitterClient.addUser(model); + assertFalse(model.isUserNameToAddIsValid(), "Can't add Joe for the 2nd time"); + assertEquals(t.getUserNames().size(), 0, "Original tweeters list remains empty"); + + Tweeters mod = model.getModifiedList(); + assertNotNull(mod, "Modified list is not filled in"); + assertTrue(model.isHasUnsavedChanges(), "We have modifications"); + assertEquals(mod.getUserNames().size(), 1, "One element in the list"); + assertEquals(mod.getUserNames().get(0), "Joe", "Its name is Joe"); + + assertSame(model.getActiveTweeters(), mod, "Editing list is the modified one"); + + TwitterClient.saveChanges(model); + assertFalse(model.isHasUnsavedChanges(), "Does not have anything to save"); + assertNull(model.getModifiedList(), "No list modified"); + + assertSame(model.getActiveTweeters(), mod, "Still editing the old modified one"); + + assertFalse(model.getSavedLists().contains(t), "No longer contains old list"); + } + +} diff -r e8916518b38d -r 9a7df12648b9 javaquery/pom.xml --- a/javaquery/pom.xml Thu Apr 04 13:08:26 2013 +0200 +++ b/javaquery/pom.xml Thu Apr 04 13:12:17 2013 +0200 @@ -15,5 +15,6 @@ api demo-calculator demo-calculator-dynamic - - + demo-twitter + + \ No newline at end of file