--- api.knockout/build.xml +++ api.knockout/build.xml @@ -0,0 +1,5 @@ + + + Builds, tests, and runs the project org.netbeans.api.knockout + + --- api.knockout/manifest.mf +++ api.knockout/manifest.mf @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +OpenIDE-Module: org.netbeans.api.knockout +OpenIDE-Module-Localizing-Bundle: org/netbeans/api/knockout/Bundle.properties +OpenIDE-Module-Specification-Version: 1.0 + --- api.knockout/nbproject/project.properties +++ api.knockout/nbproject/project.properties @@ -0,0 +1,2 @@ +javac.source=1.7 +javac.compilerargs=-Xlint -Xlint:-serial --- api.knockout/nbproject/project.xml +++ api.knockout/nbproject/project.xml @@ -0,0 +1,85 @@ + + + org.netbeans.modules.apisupport.project + + + org.netbeans.api.knockout + + + org.netbeans.modules.editor.mimelookup + + + + 1 + 1.32 + + + + org.netbeans.modules.html.editor + + + + 2 + 2.52 + + + + org.netbeans.modules.html.lexer + + + + 1 + 1.29 + + + + org.netbeans.modules.lexer + + + + 2 + 1.52 + + + + org.netbeans.modules.parsing.api + + + + 1 + 9.0 + + + + org.openide.filesystems + + + + 9.0 + + + + org.openide.util.lookup + + + + 8.21 + + + + + + unit + + org.netbeans.libs.testng + + + + + + org.netbeans.modules.knockout.impl + org.netbeans.spi.knockout + + + + --- api.knockout/src/org/netbeans/api/knockout/Bundle.properties +++ api.knockout/src/org/netbeans/api/knockout/Bundle.properties @@ -0,0 +1, @@ +OpenIDE-Module-Name=Knockout Model Provider API --- api.knockout/src/org/netbeans/spi/knockout/Bindings.java +++ api.knockout/src/org/netbeans/spi/knockout/Bindings.java @@ -0,0 +1,210 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 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]" + * + * 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. + * + * Contributor(s): + * + * Portions Copyrighted 2013 Sun Microsystems, Inc. + */ +package org.netbeans.spi.knockout; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import org.netbeans.spi.knockout.BindingsProvider.Response; +import org.openide.filesystems.FileObject; +import org.openide.util.Lookup; + +/** + * Allows structural description of a ko.applyBindings parameter. + * Register as {@link BindingsProvider}. When called build description of JSON + * types using methods like {@link #stringProperty(java.lang.String, boolean)} + * and then pass the result into + * {@link Response#applyBindings(org.netbeans.spi.knockout.Bindings)} method. + * + * @author Jaroslav Tulach + */ +public final class Bindings { + + private final String name; + private final List subBindings = new ArrayList<>(); + private final List props = new ArrayList<>(); + + private Bindings(String name) { + this.name = name; + } + + /** + * Defines new variable with provided name and assigns a JSON object into + * it. The created instance is a builder - continue calling its various + * builder methods like {@link #intProperty(java.lang.String, boolean)}. + * + * @param name name of variable (must be valid JavaScript identifier) + * @return empty JSON object ready to be filled using + * {@link #doubleProperty(java.lang.String, boolean)}, and other methods + */ + public static Bindings create(String name) { + return new Bindings(name); + } + + /** + * Generates a boolean property (with value true) into the JSON + * class. + * + * @param name name of variable (must be valid JavaScript identifier) + * @param array should this property be an array of just a single value + * @return this object + */ + public final Bindings booleanProperty(String name, boolean array) { + addProp(name, array, "true"); + return this; + } + + /** + * Generates a string property (with value '') into the JSON + * class. + * + * @param name name of variable (must be valid JavaScript identifier) + * @param array should this property be an array of just a single value + * @return this object + */ + public final Bindings stringProperty(String name, boolean array) { + addProp(name, array, "''"); + return this; + } + + /** + * Generates a integer property (with value 0) into the JSON + * class. + * + * @param name name of variable (must be valid JavaScript identifier) + * @param array should this property be an array of just a single value + * @return this object + */ + public final Bindings intProperty(String name, boolean array) { + addProp(name, array, "0"); + return this; + } + + /** + * Generates a floating point property (with value 0.1) into + * the JSON class. + * + * @param name name of variable (must be valid JavaScript identifier) + * @param array should this property be an array of just a single value + * @return this object + */ + public final Bindings doubleProperty(String name, boolean array) { + addProp(name, array, "0.1"); + return this; + } + + /** + * Generates complex subtype based on another {@link Bindings} class. + * + * @param name name of variable (must be valid JavaScript identifier) + * @param binding another description of a JSON like object + * @param array should this property be an array of just a single value + * @return this object + */ + public final Bindings modelProperty(String name, Bindings binding, boolean array) { + subBindings.add(binding); + addProp(name, array, binding.name); + return this; + } + + final String generate() { + StringBuilder sb = new StringBuilder(); + //sb.append("(function() {\n"); + HashSet visited = new HashSet<>(); + LinkedHashSet lhs = new LinkedHashSet<>(); + walkBindings(visited, lhs); + for (Bindings b : lhs) { + b.generate(sb); + } + sb.append(" ko.applyBindings(").append(name).append(");\n"); + //sb.append("}());"); + return sb.toString(); + } + + private void generate(StringBuilder sb) { + sb.append("var ").append(name).append(" = {"); + String sep = "\n"; + for (String s : props) { + sb.append(sep).append(" ").append(s); + sep = ",\n"; + } + sb.append("\n};\n"); + } + + private void addProp(String name, boolean array, String value) { + if (array) { + value = "[ " + value + " ]"; + } + if (name.contains("\"")) { + throw new IllegalStateException("Wrong name " + name); + } + props.add('\"' + name + "\" : " + value); + } + + private void walkBindings(Set visited, Set collect) { + if (!visited.add(this)) { + return; + } + for (Bindings b : subBindings) { + b.walkBindings(visited, collect); + } + collect.add(this); + } + + static { + new SPIAccessor() { + @Override + protected String findBindings(FileObject fo) { + Response r = new Response(); + for (BindingsProvider p : Lookup.getDefault().lookupAll(BindingsProvider.class)) { + p.findBindings(fo, r); + if (r.bindings != null) { + return r.bindings.generate(); + } + } + return null; + } + }; + } +} --- api.knockout/src/org/netbeans/spi/knockout/BindingsProvider.java +++ api.knockout/src/org/netbeans/spi/knockout/BindingsProvider.java @@ -0,0 +1,65 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 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]" + * + * 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. + * + * Contributor(s): + * + * Portions Copyrighted 2013 Sun Microsystems, Inc. + */ +package org.netbeans.spi.knockout; + +import org.openide.filesystems.FileObject; + +/** + * + * @author Jaroslav Tulach + */ +public interface BindingsProvider { + + public void findBindings(FileObject htmlFile, Response r); + + public static final class Response { + + Bindings bindings; + + Response() { + } + + public void applyBindings(Bindings bindings) { + this.bindings = bindings; + } + } +} --- api.knockout/src/org/netbeans/spi/knockout/SPIAccessor.java +++ api.knockout/src/org/netbeans/spi/knockout/SPIAccessor.java @@ -0,0 +1,67 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 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]" + * + * 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. + * + * Contributor(s): + * + * Portions Copyrighted 2013 Sun Microsystems, Inc. + */ +package org.netbeans.spi.knockout; + +import org.openide.filesystems.FileObject; + +/** + * + * @author Jaroslav Tulach + */ +public abstract class SPIAccessor { + + private static SPIAccessor DEFAULT; + + static { + Bindings.create(""); + } + + public static String findModelFor(FileObject fo) { + return DEFAULT.findBindings(fo); + } + + protected SPIAccessor() { + DEFAULT = this; + } + + protected abstract String findBindings(FileObject fo); +} --- api.knockout/test/unit/src/org/netbeans/spi/knockout/BindingsNGTest.java +++ api.knockout/test/unit/src/org/netbeans/spi/knockout/BindingsNGTest.java @@ -0,0 +1,104 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 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]" + * + * 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. + * + * Contributor(s): + * + * Portions Copyrighted 2013 Sun Microsystems, Inc. + */ +package org.netbeans.spi.knockout; + +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import static org.testng.Assert.*; + +/** + * + * @author Jaroslav Tulach + */ +public class BindingsNGTest { + private ScriptEngine eng; + + public BindingsNGTest() { + } + + @BeforeMethod public void initEngine() { + ScriptEngineManager sem = new ScriptEngineManager(); + eng = sem.getEngineByMimeType("text/javascript"); + } + + @Test public void generateTwitterModel() throws Exception { + Bindings tweet = Bindings.create("Tweet"). + stringProperty("from_user", false). + intProperty("from_user_id", false); + + Bindings tweeters = Bindings.create("Tweeters"). + stringProperty("name", false). + stringProperty("userNames", true); + + Bindings twitterClient = Bindings.create("TwitterClient"); + twitterClient. + stringProperty("activeTweetersName", false). + stringProperty("activeTweeters", true). + stringProperty("userNameToAdd", false). + booleanProperty("loading", false). + modelProperty("currentTweets", tweet, true). + modelProperty("savedLists", tweeters, true); + + String txt = twitterClient.generate(); + + assertValidJS(txt); + + assertNotNull(eng.eval("ko")); + assertNotNull(eng.eval("ko.value")); + assertEquals(eng.eval("ko.value.loading"), true, "Boolean values are set to true"); + assertEquals(eng.eval("ko.value.currentTweets[0].from_user_id"), 0d, "Boolean values are set to true"); + } + + private void assertValidJS(String txt) { + assertNotNull(txt, "We have some script"); + try { + eng.eval("ko = {}; ko.applyBindings = function(val) { ko.value = val; }"); + eng.eval(txt); + } catch (ScriptException ex) { + throw new AssertionError(txt, ex); + } + } + +} --- html.editor/manifest.mf +++ html.editor/manifest.mf @@ -2,5 +2,5 @@ OpenIDE-Module: org.netbeans.modules.html.editor/2 OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/html/editor/resources/Bundle.properties OpenIDE-Module-Layer: org/netbeans/modules/html/editor/resources/layer.xml -OpenIDE-Module-Specification-Version: 2.51 +OpenIDE-Module-Specification-Version: 2.52 AutoUpdate-Show-In-Client: false --- html.editor/nbproject/project.xml +++ html.editor/nbproject/project.xml @@ -541,6 +541,7 @@ com.ext4yii.editor nl.truesoftware.blendsdk + org.netbeans.api.knockout org.netbeans.modules.css.visual org.netbeans.modules.groovy.gsp org.netbeans.modules.html.angular @@ -549,8 +550,8 @@ org.netbeans.modules.html.ojet org.netbeans.modules.javascript.editing org.netbeans.modules.javascript2.editor - org.netbeans.modules.javascript2.requirejs org.netbeans.modules.javascript2.nodejs + org.netbeans.modules.javascript2.requirejs org.netbeans.modules.php.latte org.netbeans.modules.ruby.rhtml org.netbeans.modules.web.clientproject --- html.knockout/nbproject/project.xml +++ html.knockout/nbproject/project.xml @@ -15,6 +15,14 @@ + org.netbeans.api.knockout + + + + 1.0 + + + org.netbeans.api.progress --- html.knockout/src/org/netbeans/modules/html/knockout/KOJsEmbeddingProviderPlugin.java +++ html.knockout/src/org/netbeans/modules/html/knockout/KOJsEmbeddingProviderPlugin.java @@ -65,8 +65,10 @@ import org.netbeans.modules.html.knockout.KODataBindContext.ParentContext; import org.netbeans.modules.html.knockout.model.KOModel; import org.netbeans.modules.javascript2.editor.api.lexer.JsTokenId; +import org.netbeans.spi.knockout.SPIAccessor; import org.netbeans.modules.parsing.api.Embedding; import org.netbeans.modules.parsing.api.Snapshot; +import org.openide.filesystems.FileObject; import org.openide.util.Pair; /** @@ -100,6 +102,8 @@ private KODataBindContext currentTemplateContext; + private String generatedSource; + public KOJsEmbeddingProviderPlugin() { JS_LANGUAGE = Language.find(KOUtils.JAVASCRIPT_MIMETYPE); //NOI18N this.stack = new LinkedList(); @@ -114,6 +118,11 @@ if(!KOModel.getModel(parserResult).containsKnockout()) { return false; } + + FileObject fo = snapshot.getSource().getFileObject(); + if (fo != null) { + generatedSource = SPIAccessor.findModelFor(fo); + } return true; } @@ -341,6 +350,10 @@ StringBuilder sb = new StringBuilder(); sb.append("(function(){\n"); // NOI18N + if (generatedSource != null) { + sb.append(generatedSource).append("\n"); + } + // for now this is actually just a placeholder sb.append("var $element;\n"); --- nbbuild/cluster.properties +++ nbbuild/cluster.properties @@ -296,6 +296,7 @@ api.debugger,\ api.java.classpath,\ api.java.classpath.nb,\ + api.knockout,\ api.xml,\ api.xml.ui,\ bugtracking,\ --- sample.bindingsprovider/build.xml +++ sample.bindingsprovider/build.xml @@ -0,0 +1,5 @@ + + + Builds, tests, and runs the project org.netbeans.modules.sample.bindingsprovider + + --- sample.bindingsprovider/manifest.mf +++ sample.bindingsprovider/manifest.mf @@ -0,0 +1,6 @@ +Manifest-Version: 1.0 +AutoUpdate-Show-In-Client: true +OpenIDE-Module: org.netbeans.modules.sample.bindingsprovider +OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/sample/bindingsprovider/Bundle.properties +OpenIDE-Module-Specification-Version: 1.0 + --- sample.bindingsprovider/nbproject/project.properties +++ sample.bindingsprovider/nbproject/project.properties @@ -0,0 +1,2 @@ +javac.source=1.7 +javac.compilerargs=-Xlint -Xlint:-serial --- sample.bindingsprovider/nbproject/project.xml +++ sample.bindingsprovider/nbproject/project.xml @@ -0,0 +1,36 @@ + + + org.netbeans.modules.apisupport.project + + + org.netbeans.modules.sample.bindingsprovider + + + org.netbeans.api.knockout + + + + 1.0 + + + + org.openide.filesystems + + + + 9.3 + + + + org.openide.util.lookup + + + + 8.30 + + + + + + + --- sample.bindingsprovider/src/org/netbeans/modules/sample/bindingsprovider/Bundle.properties +++ sample.bindingsprovider/src/org/netbeans/modules/sample/bindingsprovider/Bundle.properties @@ -0,0 +1, @@ +OpenIDE-Module-Name=Knockout Sample Bindings Provider --- sample.bindingsprovider/src/org/netbeans/modules/sample/bindingsprovider/SampleBindingsProvider.java +++ sample.bindingsprovider/src/org/netbeans/modules/sample/bindingsprovider/SampleBindingsProvider.java @@ -0,0 +1,78 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 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]" + * + * 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. + * + * Contributor(s): + * + * Portions Copyrighted 2014 Sun Microsystems, Inc. + */ +package org.netbeans.modules.sample.bindingsprovider; + +import org.netbeans.spi.knockout.Bindings; +import org.netbeans.spi.knockout.BindingsProvider; +import org.openide.filesystems.FileObject; +import org.openide.util.lookup.ServiceProvider; + +/** + * + * @author rsvitanic + */ +@ServiceProvider(service = BindingsProvider.class) +public class SampleBindingsProvider implements BindingsProvider { + + @Override + public void findBindings(FileObject htmlFile, Response r) { + Bindings tweet = Bindings.create("Tweet"). + stringProperty("from_user", false). + intProperty("from_user_id", false); + + Bindings tweeters = Bindings.create("Tweeters"). + stringProperty("name", false). + stringProperty("userNames", true); + + Bindings twitterClient = Bindings.create("TwitterClient"); + twitterClient. + stringProperty("activeTweetersName", false). + stringProperty("activeTweeters", true). + stringProperty("userNameToAdd", false). + booleanProperty("loading", false). + modelProperty("currentTweets", tweet, true). + modelProperty("savedLists", tweeters, true); + + r.applyBindings(twitterClient); + } + +}