1.1 --- a/ko-fx/src/main/java/org/apidesign/html/kofx/FXContext.java Sat Aug 31 11:44:36 2013 +0000
1.2 +++ b/ko-fx/src/main/java/org/apidesign/html/kofx/FXContext.java Sat Aug 31 11:57:42 2013 +0000
1.3 @@ -95,15 +95,12 @@
1.4
1.5 @Override
1.6 public JSObject wrapModel(Object model) {
1.7 - JSObject obj = (JSObject) Knockout.createBinding(model).koData();
1.8 - return obj;
1.9 + throw new UnsupportedOperationException();
1.10 }
1.11
1.12 @Override
1.13 public void bind(PropertyBinding b, Object model, JSObject data) {
1.14 - final boolean isList = false;
1.15 - final boolean isPrimitive = false;
1.16 - Knockout.bind(data, model, b, isPrimitive, isList);
1.17 + throw new UnsupportedOperationException();
1.18 }
1.19
1.20 @Override
1.21 @@ -113,7 +110,7 @@
1.22
1.23 @Override
1.24 public void expose(FunctionBinding fb, Object model, JSObject d) {
1.25 - Knockout.expose(d, fb);
1.26 + throw new UnsupportedOperationException();
1.27 }
1.28
1.29 @Override
2.1 --- a/ko-fx/src/main/java/org/apidesign/html/kofx/Knockout.java Sat Aug 31 11:44:36 2013 +0000
2.2 +++ b/ko-fx/src/main/java/org/apidesign/html/kofx/Knockout.java Sat Aug 31 11:57:42 2013 +0000
2.3 @@ -20,8 +20,6 @@
2.4 */
2.5 package org.apidesign.html.kofx;
2.6
2.7 -import java.util.logging.Level;
2.8 -import java.util.logging.Logger;
2.9 import net.java.html.js.JavaScriptBody;
2.10 import net.java.html.js.JavaScriptResource;
2.11 import net.java.html.json.Model;
2.12 @@ -39,196 +37,81 @@
2.13 * @author Jaroslav Tulach <jtulach@netbeans.org>
2.14 */
2.15 @JavaScriptResource("knockout-2.2.1.js")
2.16 -public final class Knockout {
2.17 - private static final Logger LOG = Logger.getLogger(Knockout.class.getName());
2.18 - /** used by tests */
2.19 - static Knockout next;
2.20 - private final Object model;
2.21 -
2.22 - Knockout(Object model) {
2.23 - this.model = model == null ? this : model;
2.24 - }
2.25 -
2.26 - public Object koData() {
2.27 - return model;
2.28 +final class Knockout {
2.29 + static final JSObject KObject;
2.30 + static {
2.31 + Console.register();
2.32 + KObject = (JSObject) kObj();
2.33 }
2.34
2.35 static Object toArray(Object[] arr) {
2.36 - return InvokeJS.KObject.call("array", arr);
2.37 + return KObject.call("array", arr);
2.38 }
2.39
2.40 - private static int cnt;
2.41 - public static <M> Knockout createBinding(Object model) {
2.42 - Object bindings = InvokeJS.create(model, ++cnt);
2.43 - return new Knockout(bindings);
2.44 - }
2.45 + @JavaScriptBody(args = { "model", "prop" }, body =
2.46 + "if (model) {\n"
2.47 + + " var koProp = model[prop];\n"
2.48 + + " if (koProp && koProp['valueHasMutated']) {\n"
2.49 + + " koProp['valueHasMutated']();\n"
2.50 + + " }\n"
2.51 + + "}\n"
2.52 + )
2.53 + public native static void valueHasMutated(JSObject model, String prop);
2.54
2.55 - static JSObject wrapModel(
2.56 - Object model,
2.57 - String[] propNames, boolean[] propReadOnly, PropertyBinding[] propArr,
2.58 + @JavaScriptBody(args = { "bindings" }, body = "ko.applyBindings(bindings);")
2.59 + native static void applyBindings(Object bindings);
2.60 +
2.61 + @JavaScriptBody(args = {}, body =
2.62 + " var k = {};"
2.63 + + " k.array= function() {"
2.64 + + " return Array.prototype.slice.call(arguments);"
2.65 + + " };"
2.66 + + " return k;"
2.67 + )
2.68 + private static native Object kObj();
2.69 +
2.70 +
2.71 + @JavaScriptBody(
2.72 + javacall = true,
2.73 + args = {"model", "propNames", "propReadOnly", "propArr", "funcNames", "funcArr"},
2.74 + body
2.75 + = "var ret = {};\n"
2.76 + + "ret['ko-fx.model'] = model;\n"
2.77 + + "function koComputed(name, readOnly, prop) {\n"
2.78 + + " var bnd = {"
2.79 + + " read: function() {"
2.80 + + " try {"
2.81 + + " var v = prop.@org.apidesign.html.json.spi.PropertyBinding::getValue()();"
2.82 + + " return v;"
2.83 + + " } catch (e) {"
2.84 + + " alert(\"Cannot call getValue on \" + model + \" prop: \" + name + \" error: \" + e);"
2.85 + + " }"
2.86 + + " },"
2.87 + + " owner: ret\n"
2.88 + + " };\n"
2.89 + + " if (!readOnly) {\n"
2.90 + + " bnd.write = function(val) {\n"
2.91 + + " prop.@org.apidesign.html.json.spi.PropertyBinding::setValue(Ljava/lang/Object;)(val);\n"
2.92 + + " };"
2.93 + + " };"
2.94 + + " ret[name] = ko.computed(bnd);"
2.95 + + "}\n"
2.96 + + "for (var i = 0; i < propNames.length; i++) {\n"
2.97 + + " koComputed(propNames[i], propReadOnly[i], propArr[i]);\n"
2.98 + + "}\n"
2.99 + + "function koExpose(name, func) {\n"
2.100 + + " ret[name] = function(data, ev) {\n"
2.101 + + " func.@org.apidesign.html.json.spi.FunctionBinding::call(Ljava/lang/Object;Ljava/lang/Object;)(data, ev);\n"
2.102 + + " };\n"
2.103 + + "}\n"
2.104 + + "for (var i = 0; i < funcNames.length; i++) {\n"
2.105 + + " koExpose(funcNames[i], funcArr[i]);\n"
2.106 + + "}\n"
2.107 + + "return ret;\n"
2.108 + )
2.109 + static native JSObject wrapModel(
2.110 + Object model,
2.111 + String[] propNames, boolean[] propReadOnly, PropertyBinding[] propArr,
2.112 String[] funcNames, FunctionBinding[] funcArr
2.113 - ) {
2.114 - return InvokeJS.wrapModel(model, propNames, propReadOnly, propArr, funcNames, funcArr);
2.115 - }
2.116 -
2.117 -
2.118 - public void valueHasMutated(String prop) {
2.119 - valueHasMutated((JSObject) model, prop);
2.120 - }
2.121 - public static void valueHasMutated(JSObject model, String prop) {
2.122 - LOG.log(Level.FINE, "property mutated: {0}", prop);
2.123 - try {
2.124 - if (model != null) {
2.125 - Object koProp = model.getMember(prop);
2.126 - if (koProp instanceof JSObject) {
2.127 - ((JSObject)koProp).call("valueHasMutated");
2.128 - }
2.129 - }
2.130 - } catch (Throwable t) {
2.131 - LOG.log(Level.WARNING, "valueHasMutated failed for " + model + " prop: " + prop, t);
2.132 - }
2.133 - }
2.134 -
2.135 - static void bind(
2.136 - Object bindings, Object model, PropertyBinding pb, boolean primitive, boolean array
2.137 - ) {
2.138 - final String prop = pb.getPropertyName();
2.139 - try {
2.140 - InvokeJS.bind(bindings, pb, prop, "getValue", pb.isReadOnly() ? null : "setValue", primitive, array);
2.141 -
2.142 - LOG.log(Level.FINE, "binding defined for {0}: {1}", new Object[]{prop, ((JSObject)bindings).getMember(prop)});
2.143 - } catch (Throwable ex) {
2.144 - LOG.log(Level.WARNING, "binding failed for {0} on {1}", new Object[]{prop, bindings});
2.145 - }
2.146 - }
2.147 - static void expose(Object bindings, FunctionBinding f) {
2.148 - final String prop = f.getFunctionName();
2.149 - try {
2.150 - InvokeJS.expose(bindings, f, prop, "call");
2.151 - } catch (Throwable ex) {
2.152 - LOG.log(Level.SEVERE, "Cannot define binding for " + prop + " in model " + f, ex);
2.153 - }
2.154 - }
2.155 -
2.156 - static void applyBindings(Object bindings) {
2.157 - InvokeJS.applyBindings(bindings);
2.158 - }
2.159 -
2.160 - private static final class InvokeJS {
2.161 - static final JSObject KObject;
2.162 -
2.163 - static {
2.164 - Console.register();
2.165 - KObject = (JSObject) kObj();
2.166 - }
2.167 -
2.168 - @JavaScriptBody(args = { "s" }, body = "return eval(s);")
2.169 - private static native Object exec(String s);
2.170 -
2.171 - @JavaScriptBody(args = {}, body =
2.172 - " var k = {};"
2.173 - + " k.array= function() {"
2.174 - + " return Array.prototype.slice.call(arguments);"
2.175 - + " };"
2.176 - + " return k;"
2.177 - )
2.178 - private static native Object kObj();
2.179 -
2.180 - @JavaScriptBody(
2.181 - javacall = true,
2.182 - args = {"model", "propNames", "propReadOnly", "propArr", "funcNames", "funcArr"},
2.183 - body
2.184 - = "var ret = {};\n"
2.185 - + "ret['ko-fx.model'] = model;\n"
2.186 - + "function koComputed(name, readOnly, prop) {\n"
2.187 - + " var bnd = {"
2.188 - + " read: function() {"
2.189 - + " try {"
2.190 - + " var v = prop.@org.apidesign.html.json.spi.PropertyBinding::getValue()();"
2.191 - + " return v;"
2.192 - + " } catch (e) {"
2.193 - + " alert(\"Cannot call getValue on \" + model + \" prop: \" + name + \" error: \" + e);"
2.194 - + " }"
2.195 - + " },"
2.196 - + " owner: ret\n"
2.197 - + " };\n"
2.198 - + " if (!readOnly) {\n"
2.199 - + " bnd.write = function(val) {\n"
2.200 - + " prop.@org.apidesign.html.json.spi.PropertyBinding::setValue(Ljava/lang/Object;)(val);\n"
2.201 - + " };"
2.202 - + " };"
2.203 - + " ret[name] = ko.computed(bnd);"
2.204 - + "}\n"
2.205 - + "for (var i = 0; i < propNames.length; i++) {\n"
2.206 - + " koComputed(propNames[i], propReadOnly[i], propArr[i]);\n"
2.207 - + "}\n"
2.208 - + "function koExpose(name, func) {\n"
2.209 - + " ret[name] = function(data, ev) {\n"
2.210 - + " func.@org.apidesign.html.json.spi.FunctionBinding::call(Ljava/lang/Object;Ljava/lang/Object;)(data, ev);\n"
2.211 - + " };\n"
2.212 - + "}\n"
2.213 - + "for (var i = 0; i < funcNames.length; i++) {\n"
2.214 - + " koExpose(funcNames[i], funcArr[i]);\n"
2.215 - + "}\n"
2.216 - + "return ret;\n"
2.217 - )
2.218 - static native JSObject wrapModel(
2.219 - Object model,
2.220 - String[] propNames, boolean[] propReadOnly, PropertyBinding[] propArr,
2.221 - String[] funcNames, FunctionBinding[] funcArr
2.222 - );
2.223 -
2.224 -
2.225 - @JavaScriptBody(args = { "value", "cnt " }, body =
2.226 - " var ret = {};"
2.227 -/* + " ret.toString = function() { return 'KObject' + cnt + ' value: ' + value + ' props: ' + Object.keys(this); }; " */
2.228 - + " ret['ko-fx.model'] = value;"
2.229 - + " return ret;"
2.230 - )
2.231 - static native Object create(Object value, int cnt);
2.232 -
2.233 - @JavaScriptBody(args = { "bindings", "model", "prop", "sig" }, body =
2.234 - " bindings[prop] = function(data, ev) {"
2.235 - // + " console.log(\" callback on prop: \" + prop);"
2.236 - + " model[sig](data, ev);"
2.237 - + " };"
2.238 - )
2.239 - static native Object expose(Object bindings, Object model, String prop, String sig);
2.240 -
2.241 -
2.242 - @JavaScriptBody(args = { "bindings", "model", "prop", "getter", "setter", "primitive", "array" }, body =
2.243 - " var bnd = {"
2.244 - + " read: function() {"
2.245 - + " try {"
2.246 - + " var v = model[getter]();"
2.247 - // + " console.log(\" getter value \" + v + \" for property \" + prop);"
2.248 - // + " try { v = v.koData(); } catch (ignore) {"
2.249 - // + " console.log(\"Cannot convert to koData: \" + ignore);"
2.250 - // + " };"
2.251 - // + " console.log(\" getter ret value \" + v);"
2.252 - // + " for (var pn in v) {"
2.253 - // + " console.log(\" prop: \" + pn + \" + in + \" + v + \" = \" + v[pn]);"
2.254 - // + " if (typeof v[pn] == \"function\") console.log(\" its function value:\" + v[pn]());"
2.255 - // + " }"
2.256 - // + " console.log(\" all props printed for \" + (typeof v));"
2.257 - + " return v;"
2.258 - + " } catch (e) {"
2.259 - + " alert(\"Cannot call \" + getter + \" on \" + model + \" error: \" + e);"
2.260 - + " }"
2.261 - + " },"
2.262 - + " owner: bindings"
2.263 - // + " ,deferEvaluation: true"
2.264 - + " };"
2.265 - + " if (setter != null) {"
2.266 - + " bnd.write = function(val) {"
2.267 - + " model[setter](primitive ? new Number(val) : val);"
2.268 - + " };"
2.269 - + " };"
2.270 - + " bindings[prop] = ko.computed(bnd);"
2.271 - )
2.272 - static native void bind(Object binding, Object model, String prop, String getter, String setter, boolean primitive, boolean array);
2.273 -
2.274 - @JavaScriptBody(args = { "bindings" }, body = "ko.applyBindings(bindings);")
2.275 - private static native void applyBindings(Object bindings);
2.276 - }
2.277 + );
2.278 }