diff options
Diffstat (limited to 'js/dojo/dojox/dtl/contrib')
| -rw-r--r-- | js/dojo/dojox/dtl/contrib/data.js | 165 | ||||
| -rw-r--r-- | js/dojo/dojox/dtl/contrib/dijit.js | 234 | ||||
| -rw-r--r-- | js/dojo/dojox/dtl/contrib/dom.js | 177 | ||||
| -rw-r--r-- | js/dojo/dojox/dtl/contrib/objects.js | 21 |
4 files changed, 597 insertions, 0 deletions
diff --git a/js/dojo/dojox/dtl/contrib/data.js b/js/dojo/dojox/dtl/contrib/data.js new file mode 100644 index 0000000..490119c --- /dev/null +++ b/js/dojo/dojox/dtl/contrib/data.js @@ -0,0 +1,165 @@ +//>>built +define("dojox/dtl/contrib/data", [ + "dojo/_base/kernel", + "dojo/_base/lang", + "../_base", + "dojo/_base/array" +], function(kernel,lang,dd,array){ + /*===== + dd = dojox.dtl; + =====*/ + lang.getObject("dojox.dtl.contrib.data", true); + + var ddcd = dd.contrib.data; + var first = true; + + ddcd._BoundItem = lang.extend(function(item, store){ + this.item = item; + this.store = store; + }, + { + get: function(key){ + var store = this.store; + var item = this.item; + + if(key == "getLabel"){ + return store.getLabel(item); + }else if(key == "getAttributes"){ + return store.getAttributes(item); + }else if(key == "getIdentity"){ + if(store.getIdentity){ + return store.getIdentity(item); + } + return "Store has no identity API"; + }else{ + if(!store.hasAttribute(item, key)){ + if(key.slice(-1) == "s"){ + if(first){ + first = false; + kernel.deprecated("You no longer need an extra s to call getValues, it can be figured out automatically"); + } + key = key.slice(0, -1); + } + if(!store.hasAttribute(item, key)){ + return; + } + } + + var values = store.getValues(item, key); + if(!values){ + return; + } + if(!lang.isArray(values)){ + return new ddcd._BoundItem(values, store); + } + + values = array.map(values, function(value){ + if(lang.isObject(value) && store.isItem(value)){ + return new ddcd._BoundItem(value, store); + } + return value; + }); + values.get = ddcd._get; + return values; + } + } + }); + ddcd._BoundItem.prototype.get.safe = true; + + ddcd.BindDataNode = lang.extend(function(items, query, store, alias){ + this.items = items && new dd._Filter(items); + this.query = query && new dd._Filter(query); + this.store = new dd._Filter(store); + this.alias = alias; + }, + { + render: function(context, buffer){ + var items = this.items && this.items.resolve(context); + var query = this.query && this.query.resolve(context); + var store = this.store.resolve(context); + if(!store || !store.getFeatures){ + throw new Error("data_bind didn't receive a store"); + } + + if(query){ + var sync = false; + + store.fetch({ + query: query, + sync: true, + scope: this, + onComplete: function(it){ + sync = true; + items = it; + } + }); + + if(!sync){ + throw new Error("The bind_data tag only works with a query if the store executed synchronously"); + } + } + + var list = []; + + if(items){ + for(var i = 0, item; item = items[i]; i++){ + list.push(new ddcd._BoundItem(item, store)); + } + } + + context[this.alias] = list; + return buffer; + }, + unrender: function(context, buffer){ + return buffer; + }, + clone: function(){ + return this; + } + }); + + lang.mixin(ddcd, { + _get: function(key){ + if(this.length){ + return (this[0] instanceof ddcd._BoundItem) ? this[0].get(key) : this[0][key]; + } + }, + bind_data: function(parser, token){ + // summary: Turns a list of data store items into DTL compatible items + // example: + // `contextItems` and `contextStore` should be an item list + // and a data store that get assigned to `newVariable` + // + // | {% bind_data contextItems to contextStore as newVariable %} + var parts = token.contents.split(); + + if(parts[2] != 'to' || parts[4] != 'as' || !parts[5]){ + throw new Error("data_bind expects the format: 'data_bind items to store as varName'"); + } + + return new ddcd.BindDataNode(parts[1], null, parts[3], parts[5]); + }, + bind_query: function(parser, token){ + // summary: Queries a data store and makes the returned items DTL compatible + // example: + // You can only use this with data stores that work in a synchronous + // way (meaning that `onComplete` is fired during the `fetch` call). + // A `sync` flag is sent to the fetch call so that stores that usually + // work asynchronously make themselves syncrhonous if possible. + // | {% bind_query contextQuery to contextStore as newVariable %} + var parts = token.contents.split(); + + if(parts[2] != 'to' || parts[4] != 'as' || !parts[5]){ + throw new Error("data_bind expects the format: 'bind_query query to store as varName'"); + } + + return new ddcd.BindDataNode(null, parts[1], parts[3], parts[5]); + } + }); + ddcd._get.safe = true; + + dd.register.tags("dojox.dtl.contrib", { + "data": ["bind_data", "bind_query"] + }); + return dojox.dtl.contrib.data; +});
\ No newline at end of file diff --git a/js/dojo/dojox/dtl/contrib/dijit.js b/js/dojo/dojox/dtl/contrib/dijit.js new file mode 100644 index 0000000..6b54320 --- /dev/null +++ b/js/dojo/dojox/dtl/contrib/dijit.js @@ -0,0 +1,234 @@ +//>>built +define("dojox/dtl/contrib/dijit", [ + "dojo/_base/lang", + "dojo/_base/connect", + "dojo/_base/array", + "dojo/query", + "../_base", + "../dom", + "dojo/parser", + "dojo/_base/sniff" +], function(lang,connect,array,Query,dd,dxdom,Parser,has){ + /*===== + Query = dojo.query; + Parser = dojo.parser; + dd = dojox.dtl; + =====*/ + lang.getObject("dojox.dtl.contrib.dijit", true); + var ddcd = dd.contrib.dijit; + ddcd.AttachNode = lang.extend(function(keys, object){ + this._keys = keys; + this._object = object; + }, + { + render: function(context, buffer){ + if(!this._rendered){ + this._rendered = true; + for(var i = 0, key; key = this._keys[i]; i++){ + context.getThis()[key] = this._object || buffer.getParent(); + } + } + return buffer; + }, + unrender: function(context, buffer){ + if(this._rendered){ + this._rendered = false; + for(var i = 0, key; key = this._keys[i]; i++){ + if(context.getThis()[key] === (this._object || buffer.getParent())){ + delete context.getThis()[key]; + } + } + } + return buffer; + }, + clone: function(buffer){ + return new this.constructor(this._keys, this._object); + } + }); + + ddcd.EventNode = lang.extend(function(command, obj){ + this._command = command; + + var type, events = command.split(/\s*,\s*/); + var trim = lang.trim; + var types = []; + var fns = []; + while(type = events.pop()){ + if(type){ + var fn = null; + if(type.indexOf(":") != -1){ + // oh, if only JS had tuple assignment + var funcNameArr = type.split(":"); + type = trim(funcNameArr[0]); + fn = trim(funcNameArr.slice(1).join(":")); + }else{ + type = trim(type); + } + if(!fn){ + fn = type; + } + types.push(type); + fns.push(fn); + } + } + + this._types = types; + this._fns = fns; + this._object = obj; + this._rendered = []; + }, + { + // _clear: Boolean + // Make sure we kill the actual tags (onclick problems, etc) + _clear: false, + render: function(context, buffer){ + for(var i = 0, type; type = this._types[i]; i++){ + if(!this._clear && !this._object){ + buffer.getParent()[type] = null; + } + var fn = this._fns[i]; + var args; + if(fn.indexOf(" ") != -1){ + if(this._rendered[i]){ + connect.disconnect(this._rendered[i]); + this._rendered[i] = false; + } + args = array.map(fn.split(" ").slice(1), function(item){ + return new dd._Filter(item).resolve(context); + }); + fn = fn.split(" ", 2)[0]; + } + if(!this._rendered[i]){ + if(!this._object){ + this._rendered[i] = buffer.addEvent(context, type, fn, args); + }else{ + this._rendered[i] = connect.connect(this._object, type, context.getThis(), fn); + } + } + } + this._clear = true; + + return buffer; + }, + unrender: function(context, buffer){ + while(this._rendered.length){ + connect.disconnect(this._rendered.pop()); + } + return buffer; + }, + clone: function(){ + return new this.constructor(this._command, this._object); + } + }); + + function cloneNode(n1){ + var n2 = n1.cloneNode(true); + if(has("ie")){ + Query("script", n2).forEach("item.text = this[index].text;", Query("script", n1)); + } + return n2; + } + + ddcd.DojoTypeNode = lang.extend(function(node, parsed){ + this._node = node; + this._parsed = parsed; + + var events = node.getAttribute("dojoAttachEvent") || node.getAttribute("data-dojo-attach-event"); + if(events){ + this._events = new ddcd.EventNode(lang.trim(events)); + } + var attach = node.getAttribute("dojoAttachPoint") || node.getAttribute("data-dojo-attach-point"); + if(attach){ + this._attach = new ddcd.AttachNode(lang.trim(attach).split(/\s*,\s*/)); + } + + if(!parsed){ + this._dijit = Parser.instantiate([cloneNode(node)])[0]; + }else{ + node = cloneNode(node); + var old = ddcd.widgetsInTemplate; + ddcd.widgetsInTemplate = false; + this._template = new dd.DomTemplate(node); + ddcd.widgetsInTemplate = old; + } + }, + { + render: function(context, buffer){ + if(this._parsed){ + var _buffer = new dd.DomBuffer(); + this._template.render(context, _buffer); + var root = cloneNode(_buffer.getRootNode()); + var div = document.createElement("div"); + div.appendChild(root); + var rendered = div.innerHTML; + div.removeChild(root); + if(rendered != this._rendered){ + this._rendered = rendered; + if(this._dijit){ + this._dijit.destroyRecursive(); + } + this._dijit = Parser.instantiate([root])[0]; + } + } + + var node = this._dijit.domNode; + + if(this._events){ + this._events._object = this._dijit; + this._events.render(context, buffer); + } + if(this._attach){ + this._attach._object = this._dijit; + this._attach.render(context, buffer); + } + + return buffer.concat(node); + }, + unrender: function(context, buffer){ + return buffer.remove(this._dijit.domNode); + }, + clone: function(){ + return new this.constructor(this._node, this._parsed); + } + }); + + lang.mixin(ddcd, { + widgetsInTemplate: true, + dojoAttachPoint: function(parser, token){ + return new ddcd.AttachNode(token.contents.slice(token.contents.indexOf("data-") !== -1 ? 23 : 16).split(/\s*,\s*/)); + }, + dojoAttachEvent: function(parser, token){ + return new ddcd.EventNode(token.contents.slice(token.contents.indexOf("data-") !== -1 ? 23 : 16)); + }, + dojoType: function(parser, token){ + var parsed = false; + if(token.contents.slice(-7) == " parsed"){ + parsed = true; + } + var contents = token.contents.indexOf("data-") !== -1 ? token.contents.slice(15) : token.contents.slice(9); + var dojoType = parsed ? contents.slice(0, -7) : contents.toString(); + + if(ddcd.widgetsInTemplate){ + var node = parser.swallowNode(); + node.setAttribute("data-dojo-type", dojoType); + return new ddcd.DojoTypeNode(node, parsed); + } + + return new dd.AttributeNode("data-dojo-type", dojoType); + }, + on: function(parser, token){ + // summary: Associates an event type to a function (on the current widget) by name + var parts = token.contents.split(); + return new ddcd.EventNode(parts[0] + ":" + parts.slice(1).join(" ")); + } + }); + ddcd["data-dojo-type"] = ddcd.dojoType; + ddcd["data-dojo-attach-point"] = ddcd.dojoAttachPoint; + ddcd["data-dojo-attach-event"] = ddcd.dojoAttachEvent; + + + dd.register.tags("dojox.dtl.contrib", { + "dijit": ["attr:dojoType", "attr:data-dojo-type", "attr:dojoAttachPoint", "attr:data-dojo-attach-point", ["attr:attach", "dojoAttachPoint"], ["attr:attach", "data-dojo-attach-point"], "attr:dojoAttachEvent", "attr:data-dojo-attach-event", [/(attr:)?on(click|key(up))/i, "on"]] + }); + return dojox.dtl.contrib.dijit; +}); diff --git a/js/dojo/dojox/dtl/contrib/dom.js b/js/dojo/dojox/dtl/contrib/dom.js new file mode 100644 index 0000000..d2e181f --- /dev/null +++ b/js/dojo/dojox/dtl/contrib/dom.js @@ -0,0 +1,177 @@ +//>>built +define("dojox/dtl/contrib/dom", [ + "dojo/_base/kernel", + "dojo/_base/lang", + "dojo/_base/connect", + "dojo/dom-style", + "dojo/dom-construct", + "../_base", + "../dom" +], function(kernel,lang,connect,domStyle,domConstruct,dd,dddom){ + /*===== + dd = dojox.dtl; + =====*/ + var ddch = lang.getObject("dojox.dtl.contrib.dom", true); + + var simple = {render: function(){ return this.contents; }}; + + ddch.StyleNode = lang.extend(function(styles){ + this.contents = {}; + this._current = {}; + this._styles = styles; + for(var key in styles){ + if(styles[key].indexOf("{{") != -1){ + var node = new dd.Template(styles[key]); + }else{ + var node = lang.delegate(simple); + node.contents = styles[key]; + } + this.contents[key] = node; + } + }, + { + render: function(context, buffer){ + for(var key in this.contents){ + var value = this.contents[key].render(context); + if(this._current[key] != value){ + domStyle.set(buffer.getParent(), key, this._current[key] = value); + } + } + return buffer; + }, + unrender: function(context, buffer){ + this._current = {}; + return buffer; + }, + clone: function(buffer){ + return new this.constructor(this._styles); + } + }); + + ddch.BufferNode = lang.extend(function(nodelist, options){ + this.nodelist = nodelist; + this.options = options; + }, + { + _swap: function(type, node){ + if(!this.swapped && this.parent.parentNode){ + if(type == "node"){ + if((node.nodeType == 3 && !this.options.text) || (node.nodeType == 1 && !this.options.node)){ + return; + } + }else if(type == "class"){ + if(type != "class"){ + return; + } + } + + this.onAddNode && connect.disconnect(this.onAddNode); + this.onRemoveNode && connect.disconnect(this.onRemoveNode); + this.onChangeAttribute && connect.disconnect(this.onChangeAttribute); + this.onChangeData && connect.disconnect(this.onChangeData); + + this.swapped = this.parent.cloneNode(true); + this.parent.parentNode.replaceChild(this.swapped, this.parent); + } + }, + render: function(context, buffer){ + this.parent = buffer.getParent(); + if(this.options.node){ + this.onAddNode = connect.connect(buffer, "onAddNode", lang.hitch(this, "_swap", "node")); + this.onRemoveNode = connect.connect(buffer, "onRemoveNode", lang.hitch(this, "_swap", "node")); + } + if(this.options.text){ + this.onChangeData = connect.connect(buffer, "onChangeData", lang.hitch(this, "_swap", "node")); + } + if(this.options["class"]){ + this.onChangeAttribute = connect.connect(buffer, "onChangeAttribute", lang.hitch(this, "_swap", "class")); + } + + buffer = this.nodelist.render(context, buffer); + + if(this.swapped){ + this.swapped.parentNode.replaceChild(this.parent, this.swapped); + domConstruct.destroy(this.swapped); + }else{ + this.onAddNode && connect.disconnect(this.onAddNode); + this.onRemoveNode && connect.disconnect(this.onRemoveNode); + this.onChangeAttribute && connect.disconnect(this.onChangeAttribute); + this.onChangeData && connect.disconnect(this.onChangeData); + } + + delete this.parent; + delete this.swapped; + return buffer; + }, + unrender: function(context, buffer){ + return this.nodelist.unrender(context, buffer); + }, + clone: function(buffer){ + return new this.constructor(this.nodelist.clone(buffer), this.options); + } + }); + + lang.mixin(ddch, { + buffer: function(parser, token){ + // summary: + // Buffer large DOM manipulations during re-render. + // description: + // When using DomTemplate, wrap any content + // that you expect to change often during + // re-rendering. It will then remove its parent + // from the main document while it re-renders that + // section of code. It will only remove it from + // the main document if a mainpulation of somes sort + // happens. ie It won't swap out if it diesn't have to. + // example: + // By default, it considers only node addition/removal + // to be "changing" + // + // | {% buffer %}{% for item in items %}<li>{{ item }}</li>{% endfor %}{% endbuffer %} + // example: + // You can explicitly declare options: + // + // * node: Watch node removal/addition + // * class: Watch for a classname to be changed + // * text: Watch for any text to be changed + // + // | {% buffer node class %}{% for item in items %}<li>{{ item }}</li>{% endfor %}{% endbuffer %} + var parts = token.contents.split().slice(1); + var options = {}; + var found = false; + for(var i = parts.length; i--;){ + found = true; + options[parts[i]] = true; + } + if(!found){ + options.node = true; + } + var nodelist = parser.parse(["endbuffer"]); + parser.next_token(); + return new ddch.BufferNode(nodelist, options); + }, + html: function(parser, token){ + kernel.deprecated("{% html someVariable %}", "Use {{ someVariable|safe }} instead"); + return parser.create_variable_node(token.contents.slice(5) + "|safe"); + }, + style_: function(parser, token){ + var styles = {}; + token = token.contents.replace(/^style\s+/, ""); + var rules = token.split(/\s*;\s*/g); + for(var i = 0, rule; rule = rules[i]; i++){ + var parts = rule.split(/\s*:\s*/g); + var key = parts[0]; + var value = lang.trim(parts[1]); + if(value){ + styles[key] = value; + } + } + return new ddch.StyleNode(styles); + } + }); + + dd.register.tags("dojox.dtl.contrib", { + "dom": ["html", "attr:style", "buffer"] + }); + return dojox.dtl.contrib.dom; +});
\ No newline at end of file diff --git a/js/dojo/dojox/dtl/contrib/objects.js b/js/dojo/dojox/dtl/contrib/objects.js new file mode 100644 index 0000000..ea1d07b --- /dev/null +++ b/js/dojo/dojox/dtl/contrib/objects.js @@ -0,0 +1,21 @@ +//>>built +define("dojox/dtl/contrib/objects", [ + "dojo/_base/lang", + "../_base" +], function(lang,dd){ + /*===== + dd = dojox.dtl; + =====*/ + lang.getObject("dojox.dtl.contrib.objects", true); + + lang.mixin(dd.contrib.objects, { + key: function(value, arg){ + return value[arg]; + } + }); + + dd.register.filters("dojox.dtl.contrib", { + "objects": ["key"] + }); + return dojox.dtl.contrib.objects; +});
\ No newline at end of file |
