1.1 --- a/json/src/main/java/org/netbeans/html/json/impl/Bindings.java Sun Dec 14 14:36:30 2014 +0100
1.2 +++ b/json/src/main/java/org/netbeans/html/json/impl/Bindings.java Tue Dec 16 21:03:16 2014 +0100
1.3 @@ -42,6 +42,8 @@
1.4 */
1.5 package org.netbeans.html.json.impl;
1.6
1.7 +import java.util.logging.Level;
1.8 +import java.util.logging.Logger;
1.9 import net.java.html.BrwsrCtx;
1.10 import org.netbeans.html.json.spi.FunctionBinding;
1.11 import org.netbeans.html.json.spi.PropertyBinding;
1.12 @@ -53,6 +55,8 @@
1.13 * @author Jaroslav Tulach
1.14 */
1.15 public final class Bindings<Data> {
1.16 + private static final Logger LOG = Logger.getLogger(Bindings.class.getName());
1.17 +
1.18 private Data data;
1.19 private final Technology<Data> bp;
1.20
1.21 @@ -105,7 +109,18 @@
1.22 }
1.23 }
1.24
1.25 - public void applyBindings() {
1.26 + public void applyBindings(String id) {
1.27 + if (bp instanceof Technology.ApplyId) {
1.28 + Technology.ApplyId<Data> ai = (Technology.ApplyId<Data>) bp;
1.29 + ai.applyBindings(id, data);
1.30 + return;
1.31 + }
1.32 + if (id != null) {
1.33 + LOG.log(Level.WARNING,
1.34 + "Technology {0} does not implement ApplyId extension. Can't apply to {1}. Applying globally.",
1.35 + new Object[]{bp, id}
1.36 + );
1.37 + }
1.38 bp.applyBindings(data);
1.39 }
1.40
2.1 --- a/json/src/main/java/org/netbeans/html/json/impl/JSONList.java Sun Dec 14 14:36:30 2014 +0100
2.2 +++ b/json/src/main/java/org/netbeans/html/json/impl/JSONList.java Tue Dec 16 21:03:16 2014 +0100
2.3 @@ -179,7 +179,7 @@
2.4 public void run() {
2.5 Bindings m = PropertyBindingAccessor.getBindings(proto, false);
2.6 if (m != null) {
2.7 - m.valueHasMutated(name, null, null);
2.8 + m.valueHasMutated(name, null, JSONList.this);
2.9 for (String dependant : deps) {
2.10 m.valueHasMutated(dependant, null, null);
2.11 }
3.1 --- a/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java Sun Dec 14 14:36:30 2014 +0100
3.2 +++ b/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java Tue Dec 16 21:03:16 2014 +0100
3.3 @@ -504,12 +504,26 @@
3.4 + "In case of using Knockout technology, this means to \n"
3.5 + "bind JSON like data in this model instance with Knockout tags in \n"
3.6 + "the surrounding HTML page.\n"
3.7 + + "@return returns <code>this</code>\n"
3.8 + "*/\n"
3.9 );
3.10 w.write(" public " + className + " applyBindings() {\n");
3.11 w.write(" proto.applyBindings();\n");
3.12 w.write(" return this;\n");
3.13 w.write(" }\n");
3.14 + w.write(" /** Activates this model instance in the current {@link \n"
3.15 + + "net.java.html.json.Models#bind(java.lang.Object, net.java.html.BrwsrCtx) browser context}. \n"
3.16 + + "In case of using Knockout technology, this means to \n"
3.17 + + "bind JSON like data in this model instance with Knockout tags in \n"
3.18 + + "the surrounding HTML page.\n"
3.19 + + "@param id identifies the element to apply the model to\n"
3.20 + + "@return returns <code>this</code>\n"
3.21 + + "*/\n"
3.22 + );
3.23 + w.write(" public " + className + " applyBindings(String id) {\n");
3.24 + w.write(" proto.applyBindings(id);\n");
3.25 + w.write(" return this;\n");
3.26 + w.write(" }\n");
3.27 w.write(" public boolean equals(Object o) {\n");
3.28 w.write(" if (o == this) return true;\n");
3.29 w.write(" if (!(o instanceof " + className + ")) return false;\n");
4.1 --- a/json/src/main/java/org/netbeans/html/json/spi/Proto.java Sun Dec 14 14:36:30 2014 +0100
4.2 +++ b/json/src/main/java/org/netbeans/html/json/spi/Proto.java Tue Dec 16 21:03:16 2014 +0100
4.3 @@ -193,7 +193,21 @@
4.4 * of the current model to the <em>body</em> element of the page.
4.5 */
4.6 public void applyBindings() {
4.7 - initBindings().applyBindings();
4.8 + initBindings().applyBindings(null);
4.9 + }
4.10 +
4.11 + /** Initializes the associated model to the specified element's subtree.
4.12 + * The technology is taken from the current {@link #getContext() context} and
4.13 + * in case of <em>knockout.js</em> applies given bindings
4.14 + * of the current model to the element of the page with 'id' attribute
4.15 + * set to the specified <code>id</code> value.
4.16 + *
4.17 + * @param id the id of element to apply the binding to
4.18 + * @since 1.1
4.19 + * @see Technology.ApplyId
4.20 + */
4.21 + public void applyBindings(String id) {
4.22 + initBindings().applyBindings(id);
4.23 }
4.24
4.25 /** Invokes the provided runnable in the {@link #getContext() context}
5.1 --- a/json/src/main/java/org/netbeans/html/json/spi/Technology.java Sun Dec 14 14:36:30 2014 +0100
5.2 +++ b/json/src/main/java/org/netbeans/html/json/spi/Technology.java Tue Dec 16 21:03:16 2014 +0100
5.3 @@ -173,4 +173,22 @@
5.4 */
5.5 public void valueHasMutated(D data, String propertyName, Object oldValue, Object newValue);
5.6 }
5.7 +
5.8 + /** Apply technology bindings at selected subtree of the HTML page.
5.9 + * Can be accessed via {@link Proto#applyBindings(java.lang.String)} or
5.10 + * via method <code>applyBindings(String)</code> generated when one
5.11 + * is using the {@link Model} annotation.
5.12 + *
5.13 + * @param <D> the internal data for the technology
5.14 + * @since 1.1
5.15 + */
5.16 + public static interface ApplyId<D> extends Technology<D> {
5.17 + /** Applies given data to current context (usually an element on an
5.18 + * HTML page).
5.19 + *
5.20 + * @param id the id of an element to apply the data to
5.21 + * @param data the data to apply
5.22 + */
5.23 + public void applyBindings(String id, D data);
5.24 + }
5.25 }
6.1 --- a/json/src/test/java/net/java/html/json/MapModelTest.java Sun Dec 14 14:36:30 2014 +0100
6.2 +++ b/json/src/test/java/net/java/html/json/MapModelTest.java Tue Dec 16 21:03:16 2014 +0100
6.3 @@ -76,6 +76,7 @@
6.4
6.5 @Test public void isThereABinding() throws Exception {
6.6 Person p = Models.bind(new Person(), c).applyBindings();
6.7 + assertNull(t.appliedId, "Applied globally");
6.8 p.setFirstName("Jarda");
6.9
6.10 Map m = (Map)Models.toRaw(p);
6.11 @@ -94,6 +95,10 @@
6.12 assertEquals(o.changes, 2, "Snd change");
6.13 }
6.14
6.15 + @Test public void applyLocally() throws Exception {
6.16 + Person p = Models.bind(new Person(), c).applyBindings("local");
6.17 + assertEquals(t.appliedId, "local", "Applied locally");
6.18 + }
6.19
6.20 @Test public void dontNotifySameProperty() throws Exception {
6.21 Person p = Models.bind(new Person(), c);
6.22 @@ -293,7 +298,9 @@
6.23 }
6.24
6.25 static final class MapTechnology
6.26 - implements Technology<Map<String,One>>, Transfer {
6.27 + implements Technology.ApplyId<Map<String,One>>, Transfer {
6.28 + private Map<String, One> appliedData;
6.29 + private String appliedId;
6.30
6.31 @Override
6.32 public Map<String, One> wrapModel(Object model) {
6.33 @@ -329,6 +336,7 @@
6.34
6.35 @Override
6.36 public void applyBindings(Map<String, One> data) {
6.37 + throw new UnsupportedOperationException("Never called!");
6.38 }
6.39
6.40 @Override
6.41 @@ -370,5 +378,11 @@
6.42 public void runSafe(Runnable r) {
6.43 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
6.44 }
6.45 +
6.46 + @Override
6.47 + public void applyBindings(String id, Map<String, One> data) {
6.48 + this.appliedId = id;
6.49 + this.appliedData = data;
6.50 + }
6.51 }
6.52 }
7.1 --- a/ko4j/src/main/java/org/netbeans/html/ko4j/KOTech.java Sun Dec 14 14:36:30 2014 +0100
7.2 +++ b/ko4j/src/main/java/org/netbeans/html/ko4j/KOTech.java Tue Dec 16 21:03:16 2014 +0100
7.3 @@ -57,7 +57,7 @@
7.4 */
7.5 @Contexts.Id("ko4j")
7.6 final class KOTech
7.7 -implements Technology.BatchInit<Object>, Technology.ValueMutated<Object> {
7.8 +implements Technology.BatchInit<Object>, Technology.ValueMutated<Object>, Technology.ApplyId<Object> {
7.9 private Object[] jsObjects;
7.10 private int jsIndex;
7.11
7.12 @@ -131,7 +131,11 @@
7.13
7.14 @Override
7.15 public void applyBindings(Object data) {
7.16 - Object ko = Knockout.applyBindings(data);
7.17 + applyBindings(null, data);
7.18 + }
7.19 + @Override
7.20 + public void applyBindings(String id, Object data) {
7.21 + Object ko = Knockout.applyBindings(id, data);
7.22 if (ko instanceof Knockout) {
7.23 ((Knockout)ko).hold();
7.24 }
8.1 --- a/ko4j/src/main/java/org/netbeans/html/ko4j/Knockout.java Sun Dec 14 14:36:30 2014 +0100
8.2 +++ b/ko4j/src/main/java/org/netbeans/html/ko4j/Knockout.java Tue Dec 16 21:03:16 2014 +0100
8.3 @@ -131,12 +131,14 @@
8.4 Object model, String prop, Object oldValue, Object newValue
8.5 );
8.6
8.7 - @JavaScriptBody(args = { "bindings" }, body =
8.8 - "ko['cleanNode'](window['document']['body']);\n" +
8.9 - "ko['applyBindings'](bindings);\n" +
8.10 + @JavaScriptBody(args = { "id", "bindings" }, body =
8.11 + "var d = window['document'];\n" +
8.12 + "var e = id ? d['getElementById'](id) : d['body'];\n" +
8.13 + "ko['cleanNode'](e);\n" +
8.14 + "ko['applyBindings'](bindings, e);\n" +
8.15 "return bindings['ko4j'];\n"
8.16 )
8.17 - native static Object applyBindings(Object bindings);
8.18 + native static Object applyBindings(String id, Object bindings);
8.19
8.20 @JavaScriptBody(args = { "cnt" }, body =
8.21 "var arr = new Array(cnt);\n" +
9.1 --- a/src/main/javadoc/overview.html Sun Dec 14 14:36:30 2014 +0100
9.2 +++ b/src/main/javadoc/overview.html Tue Dec 16 21:03:16 2014 +0100
9.3 @@ -93,7 +93,13 @@
9.4 module registers its
9.5 {@link org.netbeans.html.json.spi.Transfer Java based JSON} and
9.6 {@link org.netbeans.html.json.spi.WSTransfer WebSocket} implementations
9.7 - under the name <b>tyrus</b>.
9.8 + under the name <b>tyrus</b>. Also the particular DOM subtree
9.9 + that a <a href="knockoutjs.com">knockout.js</a> model gets
9.10 + applied can now be selected by using
9.11 + {@link org.netbeans.html.json.spi.Proto#applyBindings(java.lang.String)
9.12 + applyBindings(id)} with an id of an HTML element.
9.13 + </p>
9.14 + <p>
9.15 Memory model when using Knockout bindings has been improved
9.16 (required additions of two new methods:
9.17 {@link org.netbeans.html.json.spi.PropertyBinding#weak()} and