123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- /* appjet:version 0.1 */
- /* appjet:library */
- // Copyright (c) 2009, Herbert Vojčík
- // Licensed by MIT license (http://www.opensource.org/licenses/mit-license.php)
- // ====== Rendering context ======
- var _stack = [];
- // ====== API ======
- /**
- * A seq is like DIV() or SPAN() without having attributes and without
- * any tags rendered.
- */
- function seq(element1, element2, etc) {
- return new _seq(arguments);
- }
- /**
- * A box is seq, which can have model set via given(model).
- * By default, model is false.
- * If a box's model evaluates to false, it renders to ""; otherwise,
- * it renders normally (eg. renders its contents).
- */
- function box(element1, element2, etc) {
- return new _box(arguments);
- }
- /**
- * A lazy is an object which calls appropriate function when rendered
- * to obtain actual object to be rendered.
- * This function gets actually rendered boxes' models as its arguments,
- * the innermost model being the first argument, parent being the second, etc.
- @param f the rendering function. Returns the structure (eg. DIV(), TABLE()
- or whatever else which you would put inside print()). It should not print() directly.
- */
- function lazy(f) {
- return new _lazy(f);
- }
- // ====== Convenience functions ======
- /** Convenience lazy that returns data from model, arguments (if any) denote property chain. */
- function data(prop1, prop2, etc) {
- var args = arguments;
- return lazy(function(model) {
- Array.forEach(args, function(p) { model = model[p]; });
- return model;
- });
- }
- /** Convenience lazy that returns data from parent's model, arguments (if any) denote property chain. */
- function outerdata(prop1, prop2, etc) {
- var args = arguments;
- return lazy(function(model, parent) {
- Array.forEach(args, function(p) { parent = parent[p]; });
- return parent;
- });
- }
- /**
- * Convenience proxy lazily representing the box's model.
- * Use dot notation to lazily represent particular contents of the model, to any depth.
- */
- //var data = _subdata([]);
- /**
- * Convenience proxy lazily representing the box's parent's model.
- * Use dot notation to lazily represent particular contents of the parent's model, to any depth.
- */
- //var outerdata = _subdata([], 1);
- /**
- * Convenience lazy that wraps a box and sets its model from supplied value model
- * (either lazy or plain value).
- */
- function sub(valueModel, box) {
- return lazy(function() { return box.given(valueModel.valueOf()); });
- }
- /**
- * Convenience lazy that iteratively repeats a sub-box with elements
- * of supplied valueModel (either lazy or plain value) set as a sub-boxes' models.
- */
- function iter(valueModel, box) {
- return lazy(function() {
- var result = seq();
- valueModel.valueOf().forEach(function(element) {
- result.push(lazy(function() { return box.given(element); }));
- });
- return result;
- });
- }
- // ====== Workers ======
- function _seq(content) {
- this.push.apply(this, content);
- }
- _seq.prototype = object(Array.prototype);
- _seq.prototype.toHTML = function() { return this.map(toHTML).join(""); };
- _seq.prototype.toString = function() { return this.toHTML(); };
- function _box(content) {
- _seq.apply(this, arguments);
- }
- _box.prototype = object(_seq.prototype);
- _box.prototype.model = false;
- _box.prototype.toHTML = function() {
- if (!this.model) { return ""; }
- try { _stack.unshift(this.model); return this.map(toHTML).join(""); }
- finally { _stack.shift(); }
- };
- /** Sets model for the box. Returns the box. */
- _box.prototype.given = function(model) {
- /** Model of the box */
- this.model = model;
- return this;
- };
- function _lazy(f) {
- this.f = f;
- }
- _lazy.prototype.valueOf = function() {
- return this.f.apply(null, _stack);
- };
- _lazy.prototype.toHTML = function() { return toHTML(this.valueOf()); };
- _lazy.prototype.toString = function() { return this.valueOf().toString(); };
- /*function _subdata(props, i) {
- if (!i) { i = 0; }
- var valueFun = props.length ?
- function() {
- var inner = _stack[i];
- props.forEach(function(p) { inner = inner[p]; });
- return inner;
- } : function() { return _stack[i]; };
- return appjet._native.createProxyObject(
- function(p) {
- switch(p) {
- case "valueOf": return valueFun;
- default: return _lazy.prototype[p] || _subdata(props.concat([p]), i);
- }
- },
- function() {}, function() {}, function() {return [];}, _lazy.prototype
- );
- }*/
- /* appjet:server */
- import("lib-app/liveui");
- print(
- box(
- "<div>", data("hello"), "</div> <-- div tags should be written",
- HR(),
- sub(data("innerwld"), box(
- "<div>", outerdata("hello"), ", ", data("foo"), "</div> <-- here as well"
- )),
- UL(iter(data("squares"), box(
- LI(data("n")," squared is ", data("n2"))
- )))
- ).given({
- hello: "hello",
- innerwld: {foo: "world"},
- squares: [1,2,3,4,5].map(function(x) { return { n:x, n2:x*x }; })
- })
- );
|