Need a wrapper around JSObject to keep list of properties. Alas, when the Technology's Data parameter does not represent in browser recognizable object, we need to do some unwrapping. Right now doing it via Callable check.
1.1 --- a/json/src/main/java/org/apidesign/html/json/impl/WrapperObject.java Thu Sep 12 17:59:10 2013 +0200
1.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/WrapperObject.java Fri Sep 13 10:06:56 2013 +0200
1.3 @@ -22,6 +22,9 @@
1.4 package org.apidesign.html.json.impl;
1.5
1.6 import java.util.Collection;
1.7 +import java.util.concurrent.Callable;
1.8 +import java.util.logging.Level;
1.9 +import java.util.logging.Logger;
1.10 import org.apidesign.html.json.impl.PropertyBindingAccessor.PBData;
1.11
1.12 /** A way to extract real object from a model classes.
1.13 @@ -35,7 +38,15 @@
1.14 }
1.15
1.16 public void setRealObject(Object ko) {
1.17 - this.ko = ko;
1.18 + if (ko instanceof Callable) {
1.19 + try {
1.20 + this.ko = ((Callable)ko).call();
1.21 + } catch (Exception ex) {
1.22 + throw new IllegalStateException(ex);
1.23 + }
1.24 + } else {
1.25 + this.ko = ko;
1.26 + }
1.27 }
1.28
1.29 public static Object find(Object object) {
2.1 --- a/ko-fx/src/main/java/org/apidesign/html/kofx/FXContext.java Thu Sep 12 17:59:10 2013 +0200
2.2 +++ b/ko-fx/src/main/java/org/apidesign/html/kofx/FXContext.java Fri Sep 13 10:06:56 2013 +0200
2.3 @@ -29,6 +29,7 @@
2.4 import java.util.Map;
2.5 import java.util.ServiceLoader;
2.6 import java.util.Set;
2.7 +import java.util.concurrent.Callable;
2.8 import java.util.logging.Logger;
2.9 import javafx.application.Platform;
2.10 import net.java.html.js.JavaScriptBody;
2.11 @@ -53,7 +54,7 @@
2.12 * @author Jaroslav Tulach <jtulach@netbeans.org>
2.13 */
2.14 public final class FXContext
2.15 -implements Technology.BatchInit<JSObject>, Transfer, WSTransfer<LoadWS>, Runnable {
2.16 +implements Technology.BatchInit<FXContext.Combo>, Transfer, WSTransfer<LoadWS>, Runnable {
2.17 static final Logger LOG = Logger.getLogger(FXContext.class.getName());
2.18 private static Boolean javaScriptEnabled;
2.19 private final Fn.Presenter browserContext;
2.20 @@ -82,7 +83,7 @@
2.21
2.22
2.23 @Override
2.24 - public JSObject wrapModel(Object model, PropertyBinding[] propArr, FunctionBinding[] funcArr) {
2.25 + public Combo wrapModel(Object model, PropertyBinding[] propArr, FunctionBinding[] funcArr) {
2.26 String[] propNames = new String[propArr.length];
2.27 boolean[] propReadOnly = new boolean[propArr.length];
2.28 Object[] propValues = new Object[propArr.length];
2.29 @@ -95,25 +96,27 @@
2.30 for (int i = 0; i < funcNames.length; i++) {
2.31 funcNames[i] = funcArr[i].getFunctionName();
2.32 }
2.33 -
2.34 - return Knockout.wrapModel(model,
2.35 - propNames, propReadOnly, Knockout.toArray(propValues), propArr,
2.36 +
2.37 + JSObject js = Knockout.wrapModel(model,
2.38 + propNames, propReadOnly, Knockout.toArray(propValues), propArr,
2.39 funcNames, funcArr
2.40 );
2.41 + return new Combo(js, propArr);
2.42 }
2.43
2.44 @Override
2.45 - public JSObject wrapModel(Object model) {
2.46 + public Combo wrapModel(Object model) {
2.47 throw new UnsupportedOperationException();
2.48 }
2.49
2.50 @Override
2.51 - public void bind(PropertyBinding b, Object model, JSObject data) {
2.52 + public void bind(PropertyBinding b, Object model, Combo data) {
2.53 throw new UnsupportedOperationException();
2.54 }
2.55
2.56 @Override
2.57 - public synchronized void valueHasMutated(JSObject data, String propertyName) {
2.58 + public synchronized void valueHasMutated(Combo c, String propertyName) {
2.59 + JSObject data = c.js;
2.60 if (notifyMutated.isEmpty()) {
2.61 FnUtils.runLater(this);
2.62 }
2.63 @@ -126,13 +129,13 @@
2.64 }
2.65
2.66 @Override
2.67 - public void expose(FunctionBinding fb, Object model, JSObject d) {
2.68 + public void expose(FunctionBinding fb, Object model, Combo d) {
2.69 throw new UnsupportedOperationException();
2.70 }
2.71
2.72 @Override
2.73 - public void applyBindings(JSObject data) {
2.74 - Knockout.applyBindings(data);
2.75 + public void applyBindings(Combo data) {
2.76 + Knockout.applyBindings(data.js);
2.77 }
2.78
2.79 @Override
2.80 @@ -152,6 +155,9 @@
2.81
2.82 @Override
2.83 public <M> M toModel(Class<M> modelClass, Object data) {
2.84 + if (data instanceof Combo) {
2.85 + data = ((Combo)data).js;
2.86 + }
2.87 if (data instanceof JSObject) {
2.88 data = ((JSObject)data).getMember("ko-fx.model"); // NOI18N
2.89 }
2.90 @@ -241,4 +247,18 @@
2.91 }
2.92 }
2.93
2.94 + static final class Combo implements Callable<JSObject> {
2.95 + final JSObject js;
2.96 + final PropertyBinding[] props;
2.97 +
2.98 + public Combo(JSObject js, PropertyBinding[] props) {
2.99 + this.js = js;
2.100 + this.props = props;
2.101 + }
2.102 +
2.103 + @Override
2.104 + public JSObject call() {
2.105 + return js;
2.106 + }
2.107 + }
2.108 }