Support only batch operations
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Sat, 31 Aug 2013 11:57:42 +0000
changeset 276a8663166a8d1
parent 275 5a75c617a922
child 277 285765af17f0
Support only batch operations
ko-fx/src/main/java/org/apidesign/html/kofx/FXContext.java
ko-fx/src/main/java/org/apidesign/html/kofx/Knockout.java
     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  }