diff options
Diffstat (limited to 'js/dojo-1.7.2/dojox/dtl.js.uncompressed.js')
| -rw-r--r-- | js/dojo-1.7.2/dojox/dtl.js.uncompressed.js | 2974 |
1 files changed, 2974 insertions, 0 deletions
diff --git a/js/dojo-1.7.2/dojox/dtl.js.uncompressed.js b/js/dojo-1.7.2/dojox/dtl.js.uncompressed.js new file mode 100644 index 0000000..0987165 --- /dev/null +++ b/js/dojo-1.7.2/dojox/dtl.js.uncompressed.js @@ -0,0 +1,2974 @@ +/* + Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved. + Available via Academic Free License >= 2.1 OR the modified BSD license. + see: http://dojotoolkit.org/license for details +*/ + +/* + This is an optimized version of Dojo, built for deployment and not for + development. To get sources and documentation, please visit: + + http://dojotoolkit.org +*/ + +//>>built +require({cache:{ +'dojox/dtl/_base':function(){ +define([ + "dojo/_base/kernel", + "dojo/_base/lang", + "dojox/string/tokenize", + "dojo/_base/json", + "dojo/dom", + "dojo/_base/xhr", + "dojox/string/Builder", + "dojo/_base/Deferred"], + function(kernel, lang, Tokenize, json, dom, xhr, StringBuilder, deferred){ + /*===== + Tokenize = dojox.string.tokenize; + StringBuilder = dojox.string.Builder; + =====*/ + kernel.experimental("dojox.dtl"); + var dd = lang.getObject("dojox.dtl", true); + dd._base = {}; + /*===== + dd = dojox.dtl; + =====*/ + + dd.TOKEN_BLOCK = -1; + dd.TOKEN_VAR = -2; + dd.TOKEN_COMMENT = -3; + dd.TOKEN_TEXT = 3; + + /*===== + dd._Context = function(dict){ + // summary: Pass one of these when rendering a template to tell the template what values to use. + } + =====*/ + dd._Context = lang.extend(function(dict){ + // summary: Pass one of these when rendering a template to tell the template what values to use. + if(dict){ + lang._mixin(this, dict); + if(dict.get){ + // Preserve passed getter and restore prototype get + this._getter = dict.get; + delete this.get; + } + } + }, + { + push: function(){ + var last = this; + var context = lang.delegate(this); + context.pop = function(){ return last; } + return context; + }, + pop: function(){ + throw new Error("pop() called on empty Context"); + }, + get: function(key, otherwise){ + var n = this._normalize; + + if(this._getter){ + var got = this._getter(key); + if(got !== undefined){ + return n(got); + } + } + + if(this[key] !== undefined){ + return n(this[key]); + } + + return otherwise; + }, + _normalize: function(value){ + if(value instanceof Date){ + value.year = value.getFullYear(); + value.month = value.getMonth() + 1; + value.day = value.getDate(); + value.date = value.year + "-" + ("0" + value.month).slice(-2) + "-" + ("0" + value.day).slice(-2); + value.hour = value.getHours(); + value.minute = value.getMinutes(); + value.second = value.getSeconds(); + value.microsecond = value.getMilliseconds(); + } + return value; + }, + update: function(dict){ + var context = this.push(); + if(dict){ + lang._mixin(this, dict); + } + return context; + } + }); + + var smart_split_re = /("(?:[^"\\]*(?:\\.[^"\\]*)*)"|'(?:[^'\\]*(?:\\.[^'\\]*)*)'|[^\s]+)/g; + var split_re = /\s+/g; + var split = function(/*String|RegExp?*/ splitter, /*Integer?*/ limit){ + splitter = splitter || split_re; + if(!(splitter instanceof RegExp)){ + splitter = new RegExp(splitter, "g"); + } + if(!splitter.global){ + throw new Error("You must use a globally flagged RegExp with split " + splitter); + } + splitter.exec(""); // Reset the global + + var part, parts = [], lastIndex = 0, i = 0; + while((part = splitter.exec(this))){ + parts.push(this.slice(lastIndex, splitter.lastIndex - part[0].length)); + lastIndex = splitter.lastIndex; + if(limit && (++i > limit - 1)){ + break; + } + } + parts.push(this.slice(lastIndex)); + return parts; + } + + dd.Token = function(token_type, contents){ + this.token_type = token_type; + this.contents = new String(lang.trim(contents)); + this.contents.split = split; + this.split = function(){ + return String.prototype.split.apply(this.contents, arguments); + } + } + dd.Token.prototype.split_contents = function(/*Integer?*/ limit){ + var bit, bits = [], i = 0; + limit = limit || 999; + while(i++ < limit && (bit = smart_split_re.exec(this.contents))){ + bit = bit[0]; + if(bit.charAt(0) == '"' && bit.slice(-1) == '"'){ + bits.push('"' + bit.slice(1, -1).replace('\\"', '"').replace('\\\\', '\\') + '"'); + }else if(bit.charAt(0) == "'" && bit.slice(-1) == "'"){ + bits.push("'" + bit.slice(1, -1).replace("\\'", "'").replace('\\\\', '\\') + "'"); + }else{ + bits.push(bit); + } + } + return bits; + } + + var ddt = dd.text = { + _get: function(module, name, errorless){ + // summary: Used to find both tags and filters + var params = dd.register.get(module, name.toLowerCase(), errorless); + if(!params){ + if(!errorless){ + throw new Error("No tag found for " + name); + } + return null; + } + + var fn = params[1]; + var deps = params[2]; + + var parts; + if(fn.indexOf(":") != -1){ + parts = fn.split(":"); + fn = parts.pop(); + } + +// FIXME: THIS DESIGN DOES NOT WORK WITH ASYNC LOADERS! + var mod = deps; + if (/\./.test(deps)) { + deps = deps.replace(/\./g, "/"); + } + require([deps], function(){}); + + var parent = lang.getObject(mod); + + return parent[fn || name] || parent[name + "_"] || parent[fn + "_"]; + }, + getTag: function(name, errorless){ + return ddt._get("tag", name, errorless); + }, + getFilter: function(name, errorless){ + return ddt._get("filter", name, errorless); + }, + getTemplate: function(file){ + return new dd.Template(ddt.getTemplateString(file)); + }, + getTemplateString: function(file){ + return xhr._getText(file.toString()) || ""; + }, + _resolveLazy: function(location, sync, json){ + if(sync){ + if(json){ + return json.fromJson(xhr._getText(location)) || {}; + }else{ + return dd.text.getTemplateString(location); + } + }else{ + return xhr.get({ + handleAs: json ? "json" : "text", + url: location + }); + } + }, + _resolveTemplateArg: function(arg, sync){ + if(ddt._isTemplate(arg)){ + if(!sync){ + var d = new deferred(); + d.callback(arg); + return d; + } + return arg; + } + return ddt._resolveLazy(arg, sync); + }, + _isTemplate: function(arg){ + return (arg === undefined) || (typeof arg == "string" && (arg.match(/^\s*[<{]/) || arg.indexOf(" ") != -1)); + }, + _resolveContextArg: function(arg, sync){ + if(arg.constructor == Object){ + if(!sync){ + var d = new deferred; + d.callback(arg); + return d; + } + return arg; + } + return ddt._resolveLazy(arg, sync, true); + }, + _re: /(?:\{\{\s*(.+?)\s*\}\}|\{%\s*(load\s*)?(.+?)\s*%\})/g, + tokenize: function(str){ + return Tokenize(str, ddt._re, ddt._parseDelims); + }, + _parseDelims: function(varr, load, tag){ + if(varr){ + return [dd.TOKEN_VAR, varr]; + }else if(load){ + var parts = lang.trim(tag).split(/\s+/g); + for(var i = 0, part; part = parts[i]; i++){ + if (/\./.test(part)){ + part = part.replace(/\./g,"/"); + } + require([part]); + } + }else{ + return [dd.TOKEN_BLOCK, tag]; + } + } + } + + /*===== + dd.Template = function(template, isString){ + // summary: + // The base class for text-based templates. + // template: String|dojo._Url + // The string or location of the string to + // use as a template + // isString: Boolean + // Indicates whether the template is a string or a url. + }; + dd.Template.prototype.update= function(node, context){ + // summary: + // Updates this template according to the given context. + // node: DOMNode|String|dojo.NodeList + // A node reference or set of nodes + // context: dojo._Url|String|Object + // The context object or location + } + dd.Template.prototype.render= function(context, buffer){ + // summary: + // Renders this template. + // context: Object + // The runtime context. + // buffer: StringBuilder? + // A string buffer. + } + + =====*/ + dd.Template = lang.extend(function(/*String|dojo._Url*/ template, /*Boolean*/ isString){ + // template: + // The string or location of the string to + // use as a template + var str = isString ? template : ddt._resolveTemplateArg(template, true) || ""; + var tokens = ddt.tokenize(str); + var parser = new dd._Parser(tokens); + this.nodelist = parser.parse(); + }, + { + update: function(node, context){ + // summary: + // Updates this template according to the given context. + // node: DOMNode|String|dojo.NodeList + // A node reference or set of nodes + // context: dojo._Url|String|Object + // The context object or location + return ddt._resolveContextArg(context).addCallback(this, function(contextObject){ + var content = this.render(new dd._Context(contextObject)); + if(node.forEach){ + node.forEach(function(item){ + item.innerHTML = content; + }); + }else{ + dom.byId(node).innerHTML = content; + } + return this; + }); + }, + render: function(context, /*concatenatable?*/ buffer){ + buffer = buffer || this.getBuffer(); + context = context || new dd._Context({}); + return this.nodelist.render(context, buffer) + ""; + }, + getBuffer: function(){ + return new StringBuilder(); + } + }); + + var qfRe = /\{\{\s*(.+?)\s*\}\}/g; + dd.quickFilter = function(str){ + if(!str){ + return new dd._NodeList(); + } + + if(str.indexOf("{%") == -1){ + return new dd._QuickNodeList(Tokenize(str, qfRe, function(token){ + return new dd._Filter(token); + })); + } + } + + dd._QuickNodeList = lang.extend(function(contents){ + this.contents = contents; + }, + { + render: function(context, buffer){ + for(var i = 0, l = this.contents.length; i < l; i++){ + if(this.contents[i].resolve){ + buffer = buffer.concat(this.contents[i].resolve(context)); + }else{ + buffer = buffer.concat(this.contents[i]); + } + } + return buffer; + }, + dummyRender: function(context){ return this.render(context, dd.Template.prototype.getBuffer()).toString(); }, + clone: function(buffer){ return this; } + }); + + dd._Filter = lang.extend(function(token){ + // summary: Uses a string to find (and manipulate) a variable + if(!token) throw new Error("Filter must be called with variable name"); + this.contents = token; + + var cache = this._cache[token]; + if(cache){ + this.key = cache[0]; + this.filters = cache[1]; + }else{ + this.filters = []; + Tokenize(token, this._re, this._tokenize, this); + this._cache[token] = [this.key, this.filters]; + } + }, + { + _cache: {}, + _re: /(?:^_\("([^\\"]*(?:\\.[^\\"])*)"\)|^"([^\\"]*(?:\\.[^\\"]*)*)"|^([a-zA-Z0-9_.]+)|\|(\w+)(?::(?:_\("([^\\"]*(?:\\.[^\\"])*)"\)|"([^\\"]*(?:\\.[^\\"]*)*)"|([a-zA-Z0-9_.]+)|'([^\\']*(?:\\.[^\\']*)*)'))?|^'([^\\']*(?:\\.[^\\']*)*)')/g, + _values: { + 0: '"', // _("text") + 1: '"', // "text" + 2: "", // variable + 8: '"' // 'text' + }, + _args: { + 4: '"', // :_("text") + 5: '"', // :"text" + 6: "", // :variable + 7: "'"// :'text' + }, + _tokenize: function(){ + var pos, arg; + + for(var i = 0, has = []; i < arguments.length; i++){ + has[i] = (arguments[i] !== undefined && typeof arguments[i] == "string" && arguments[i]); + } + + if(!this.key){ + for(pos in this._values){ + if(has[pos]){ + this.key = this._values[pos] + arguments[pos] + this._values[pos]; + break; + } + } + }else{ + for(pos in this._args){ + if(has[pos]){ + var value = arguments[pos]; + if(this._args[pos] == "'"){ + value = value.replace(/\\'/g, "'"); + }else if(this._args[pos] == '"'){ + value = value.replace(/\\"/g, '"'); + } + arg = [!this._args[pos], value]; + break; + } + } + // Get a named filter + var fn = ddt.getFilter(arguments[3]); + if(!lang.isFunction(fn)) throw new Error(arguments[3] + " is not registered as a filter"); + this.filters.push([fn, arg]); + } + }, + getExpression: function(){ + return this.contents; + }, + resolve: function(context){ + if(this.key === undefined){ + return ""; + } + + var str = this.resolvePath(this.key, context); + + for(var i = 0, filter; filter = this.filters[i]; i++){ + // Each filter has the function in [0], a boolean in [1][0] of whether it's a variable or a string + // and [1][1] is either the variable name of the string content. + if(filter[1]){ + if(filter[1][0]){ + str = filter[0](str, this.resolvePath(filter[1][1], context)); + }else{ + str = filter[0](str, filter[1][1]); + } + }else{ + str = filter[0](str); + } + } + + return str; + }, + resolvePath: function(path, context){ + var current, parts; + var first = path.charAt(0); + var last = path.slice(-1); + if(!isNaN(parseInt(first))){ + current = (path.indexOf(".") == -1) ? parseInt(path) : parseFloat(path); + }else if(first == '"' && first == last){ + current = path.slice(1, -1); + }else{ + if(path == "true"){ return true; } + if(path == "false"){ return false; } + if(path == "null" || path == "None"){ return null; } + parts = path.split("."); + current = context.get(parts[0]); + + if(lang.isFunction(current)){ + var self = context.getThis && context.getThis(); + if(current.alters_data){ + current = ""; + }else if(self){ + current = current.call(self); + }else{ + current = ""; + } + } + + for(var i = 1; i < parts.length; i++){ + var part = parts[i]; + if(current){ + var base = current; + if(lang.isObject(current) && part == "items" && current[part] === undefined){ + var items = []; + for(var key in current){ + items.push([key, current[key]]); + } + current = items; + continue; + } + + if(current.get && lang.isFunction(current.get) && current.get.safe){ + current = current.get(part); + }else if(current[part] === undefined){ + current = current[part]; + break; + }else{ + current = current[part]; + } + + if(lang.isFunction(current)){ + if(current.alters_data){ + current = ""; + }else{ + current = current.call(base); + } + }else if(current instanceof Date){ + current = dd._Context.prototype._normalize(current); + } + }else{ + return ""; + } + } + } + return current; + } + }); + + dd._TextNode = dd._Node = lang.extend(function(/*Object*/ obj){ + // summary: Basic catch-all node + this.contents = obj; + }, + { + set: function(data){ + this.contents = data; + return this; + }, + render: function(context, buffer){ + // summary: Adds content onto the buffer + return buffer.concat(this.contents); + }, + isEmpty: function(){ + return !lang.trim(this.contents); + }, + clone: function(){ return this; } + }); + + dd._NodeList = lang.extend(function(/*Node[]*/ nodes){ + // summary: Allows us to render a group of nodes + this.contents = nodes || []; + this.last = ""; + }, + { + push: function(node){ + // summary: Add a new node to the list + this.contents.push(node); + return this; + }, + concat: function(nodes){ + this.contents = this.contents.concat(nodes); + return this; + }, + render: function(context, buffer){ + // summary: Adds all content onto the buffer + for(var i = 0; i < this.contents.length; i++){ + buffer = this.contents[i].render(context, buffer); + if(!buffer) throw new Error("Template must return buffer"); + } + return buffer; + }, + dummyRender: function(context){ + return this.render(context, dd.Template.prototype.getBuffer()).toString(); + }, + unrender: function(){ return arguments[1]; }, + clone: function(){ return this; }, + rtrim: function(){ + while(1){ + i = this.contents.length - 1; + if(this.contents[i] instanceof dd._TextNode && this.contents[i].isEmpty()){ + this.contents.pop(); + }else{ + break; + } + } + + return this; + } + }); + + dd._VarNode = lang.extend(function(str){ + // summary: A node to be processed as a variable + this.contents = new dd._Filter(str); + }, + { + render: function(context, buffer){ + var str = this.contents.resolve(context); + if(!str.safe){ + str = dd._base.escape("" + str); + } + return buffer.concat(str); + } + }); + + dd._noOpNode = new function(){ + // summary: Adds a no-op node. Useful in custom tags + this.render = this.unrender = function(){ return arguments[1]; } + this.clone = function(){ return this; } + } + + dd._Parser = lang.extend(function(tokens){ + // summary: Parser used during initialization and for tag groups. + this.contents = tokens; + }, + { + i: 0, + parse: function(/*Array?*/ stop_at){ + // summary: Turns tokens into nodes + // description: Steps into tags are they're found. Blocks use the parse object + // to find their closing tag (the stop_at array). stop_at is inclusive, it + // returns the node that matched. + var terminators = {}, token; + stop_at = stop_at || []; + for(var i = 0; i < stop_at.length; i++){ + terminators[stop_at[i]] = true; + } + + var nodelist = new dd._NodeList(); + while(this.i < this.contents.length){ + token = this.contents[this.i++]; + if(typeof token == "string"){ + nodelist.push(new dd._TextNode(token)); + }else{ + var type = token[0]; + var text = token[1]; + if(type == dd.TOKEN_VAR){ + nodelist.push(new dd._VarNode(text)); + }else if(type == dd.TOKEN_BLOCK){ + if(terminators[text]){ + --this.i; + return nodelist; + } + var cmd = text.split(/\s+/g); + if(cmd.length){ + cmd = cmd[0]; + var fn = ddt.getTag(cmd); + if(fn){ + nodelist.push(fn(this, new dd.Token(type, text))); + } + } + } + } + } + + if(stop_at.length){ + throw new Error("Could not find closing tag(s): " + stop_at.toString()); + } + + this.contents.length = 0; + return nodelist; + }, + next_token: function(){ + // summary: Returns the next token in the list. + var token = this.contents[this.i++]; + return new dd.Token(token[0], token[1]); + }, + delete_first_token: function(){ + this.i++; + }, + skip_past: function(endtag){ + while(this.i < this.contents.length){ + var token = this.contents[this.i++]; + if(token[0] == dd.TOKEN_BLOCK && token[1] == endtag){ + return; + } + } + throw new Error("Unclosed tag found when looking for " + endtag); + }, + create_variable_node: function(expr){ + return new dd._VarNode(expr); + }, + create_text_node: function(expr){ + return new dd._TextNode(expr || ""); + }, + getTemplate: function(file){ + return new dd.Template(file); + } + }); + + dd.register = { + _registry: { + attributes: [], + tags: [], + filters: [] + }, + get: function(/*String*/ module, /*String*/ name){ + var registry = dd.register._registry[module + "s"]; + for(var i = 0, entry; entry = registry[i]; i++){ + if(typeof entry[0] == "string"){ + if(entry[0] == name){ + return entry; + } + }else if(name.match(entry[0])){ + return entry; + } + } + }, + getAttributeTags: function(){ + var tags = []; + var registry = dd.register._registry.attributes; + for(var i = 0, entry; entry = registry[i]; i++){ + if(entry.length == 3){ + tags.push(entry); + }else{ + var fn = lang.getObject(entry[1]); + if(fn && lang.isFunction(fn)){ + entry.push(fn); + tags.push(entry); + } + } + } + return tags; + }, + _any: function(type, base, locations){ + for(var path in locations){ + for(var i = 0, fn; fn = locations[path][i]; i++){ + var key = fn; + if(lang.isArray(fn)){ + key = fn[0]; + fn = fn[1]; + } + if(typeof key == "string"){ + if(key.substr(0, 5) == "attr:"){ + var attr = fn; + if(attr.substr(0, 5) == "attr:"){ + attr = attr.slice(5); + } + dd.register._registry.attributes.push([attr.toLowerCase(), base + "." + path + "." + attr]); + } + key = key.toLowerCase() + } + dd.register._registry[type].push([ + key, + fn, + base + "." + path + ]); + } + } + }, + tags: function(/*String*/ base, /*Object*/ locations){ + dd.register._any("tags", base, locations); + }, + filters: function(/*String*/ base, /*Object*/ locations){ + dd.register._any("filters", base, locations); + } + } + + var escapeamp = /&/g; + var escapelt = /</g; + var escapegt = />/g; + var escapeqt = /'/g; + var escapedblqt = /"/g; + dd._base.escape = function(value){ + // summary: Escapes a string's HTML + return dd.mark_safe(value.replace(escapeamp, '&').replace(escapelt, '<').replace(escapegt, '>').replace(escapedblqt, '"').replace(escapeqt, ''')); + } + + dd._base.safe = function(value){ + if(typeof value == "string"){ + value = new String(value); + } + if(typeof value == "object"){ + value.safe = true; + } + return value; + } + dd.mark_safe = dd._base.safe; + + dd.register.tags("dojox.dtl.tag", { + "date": ["now"], + "logic": ["if", "for", "ifequal", "ifnotequal"], + "loader": ["extends", "block", "include", "load", "ssi"], + "misc": ["comment", "debug", "filter", "firstof", "spaceless", "templatetag", "widthratio", "with"], + "loop": ["cycle", "ifchanged", "regroup"] + }); + dd.register.filters("dojox.dtl.filter", { + "dates": ["date", "time", "timesince", "timeuntil"], + "htmlstrings": ["linebreaks", "linebreaksbr", "removetags", "striptags"], + "integers": ["add", "get_digit"], + "lists": ["dictsort", "dictsortreversed", "first", "join", "length", "length_is", "random", "slice", "unordered_list"], + "logic": ["default", "default_if_none", "divisibleby", "yesno"], + "misc": ["filesizeformat", "pluralize", "phone2numeric", "pprint"], + "strings": ["addslashes", "capfirst", "center", "cut", "fix_ampersands", "floatformat", "iriencode", "linenumbers", "ljust", "lower", "make_list", "rjust", "slugify", "stringformat", "title", "truncatewords", "truncatewords_html", "upper", "urlencode", "urlize", "urlizetrunc", "wordcount", "wordwrap"] + }); + dd.register.filters("dojox.dtl", { + "_base": ["escape", "safe"] + }); + return dd; +}); + + +}, +'dojox/dtl/tag/loader':function(){ +define("dojox/dtl/tag/loader", [ + "dojo/_base/lang", + "../_base", + "dojo/_base/array", + "dojo/_base/connect" +], function(lang,dd,array,connect){ + /*===== + dd = dojox.dtl; + =====*/ + lang.getObject("dojox.dtl.tag.loader", true); + + var ddtl = dd.tag.loader; + + ddtl.BlockNode = lang.extend(function(name, nodelist){ + this.name = name; + this.nodelist = nodelist; // Can be overridden + }, + { + "super": function(){ + if(this.parent){ + var html = this.parent.nodelist.dummyRender(this.context, null, true); + if(typeof html == "string"){ + html = new String(html); + } + html.safe = true; + return html; + } + return ''; + }, + render: function(context, buffer){ + var name = this.name; + var nodelist = this.nodelist; + var parent; + if(buffer.blocks){ + var block = buffer.blocks[name]; + if(block){ + parent = block.parent; + nodelist = block.nodelist; + block.used = true; + } + } + + this.rendered = nodelist; + + context = context.push(); + this.context = context; + this.parent = null; + if(nodelist != this.nodelist){ + this.parent = this; + } + context.block = this; + + if(buffer.getParent){ + var bufferParent = buffer.getParent(); + var setParent = connect.connect(buffer, "onSetParent", function(node, up, root){ + if(up && root){ + buffer.setParent(bufferParent); + } + }); + } + buffer = nodelist.render(context, buffer, this); + setParent && connect.disconnect(setParent); + context = context.pop(); + return buffer; + }, + unrender: function(context, buffer){ + return this.rendered.unrender(context, buffer); + }, + clone: function(buffer){ + return new this.constructor(this.name, this.nodelist.clone(buffer)); + }, + toString: function(){ return "dojox.dtl.tag.loader.BlockNode"; } + }); + + ddtl.ExtendsNode = lang.extend(function(getTemplate, nodelist, shared, parent, key){ + this.getTemplate = getTemplate; + this.nodelist = nodelist; + this.shared = shared; + this.parent = parent; + this.key = key; + }, + { + parents: {}, + getParent: function(context){ + var parent = this.parent; + if(!parent){ + var string; + parent = this.parent = context.get(this.key, false); + if(!parent){ + throw new Error("extends tag used a variable that did not resolve"); + } + if(typeof parent == "object"){ + var url = parent.url || parent.templatePath; + if(parent.shared){ + this.shared = true; + } + if(url){ + parent = this.parent = url.toString(); + }else if(parent.templateString){ + // Allow the builder's string interning to work + string = parent.templateString; + parent = this.parent = " "; + }else{ + parent = this.parent = this.parent.toString(); + } + } + if(parent && parent.indexOf("shared:") === 0){ + this.shared = true; + parent = this.parent = parent.substring(7, parent.length); + } + } + if(!parent){ + throw new Error("Invalid template name in 'extends' tag."); + } + if(parent.render){ + return parent; + } + if(this.parents[parent]){ + return this.parents[parent]; + } + this.parent = this.getTemplate(string || dojox.dtl.text.getTemplateString(parent)); + if(this.shared){ + this.parents[parent] = this.parent; + } + return this.parent; + }, + render: function(context, buffer){ + var parent = this.getParent(context); + + parent.blocks = parent.blocks || {}; + buffer.blocks = buffer.blocks || {}; + + for(var i = 0, node; node = this.nodelist.contents[i]; i++){ + if(node instanceof dojox.dtl.tag.loader.BlockNode){ + var old = parent.blocks[node.name]; + if(old && old.nodelist != node.nodelist){ + // In a shared template, the individual blocks might change + buffer = old.nodelist.unrender(context, buffer); + } + parent.blocks[node.name] = buffer.blocks[node.name] = { + shared: this.shared, + nodelist: node.nodelist, + used: false + } + } + } + + this.rendered = parent; + return parent.nodelist.render(context, buffer, this); + }, + unrender: function(context, buffer){ + return this.rendered.unrender(context, buffer, this); + }, + toString: function(){ return "dojox.dtl.block.ExtendsNode"; } + }); + + ddtl.IncludeNode = lang.extend(function(path, constant, getTemplate, text, parsed){ + this._path = path; + this.constant = constant; + this.path = (constant) ? path : new dd._Filter(path); + this.getTemplate = getTemplate; + this.text = text; + this.parsed = (arguments.length == 5) ? parsed : true; + }, + { + _cache: [{}, {}], + render: function(context, buffer){ + var location = ((this.constant) ? this.path : this.path.resolve(context)).toString(); + var parsed = Number(this.parsed); + var dirty = false; + if(location != this.last){ + dirty = true; + if(this.last){ + buffer = this.unrender(context, buffer); + } + this.last = location; + } + + var cache = this._cache[parsed]; + + if(parsed){ + if(!cache[location]){ + cache[location] = dd.text._resolveTemplateArg(location, true); + } + if(dirty){ + var template = this.getTemplate(cache[location]); + this.rendered = template.nodelist; + } + return this.rendered.render(context, buffer, this); + }else{ + if(this.text instanceof dd._TextNode){ + if(dirty){ + this.rendered = this.text; + this.rendered.set(dd.text._resolveTemplateArg(location, true)); + } + return this.rendered.render(context, buffer); + }else{ + if(!cache[location]){ + var nodelist = []; + var div = document.createElement("div"); + div.innerHTML = dd.text._resolveTemplateArg(location, true); + var children = div.childNodes; + while(children.length){ + var removed = div.removeChild(children[0]); + nodelist.push(removed); + } + cache[location] = nodelist; + } + if(dirty){ + this.nodelist = []; + var exists = true; + for(var i = 0, child; child = cache[location][i]; i++){ + this.nodelist.push(child.cloneNode(true)); + } + } + for(var i = 0, node; node = this.nodelist[i]; i++){ + buffer = buffer.concat(node); + } + } + } + return buffer; + }, + unrender: function(context, buffer){ + if(this.rendered){ + buffer = this.rendered.unrender(context, buffer); + } + if(this.nodelist){ + for(var i = 0, node; node = this.nodelist[i]; i++){ + buffer = buffer.remove(node); + } + } + return buffer; + }, + clone: function(buffer){ + return new this.constructor(this._path, this.constant, this.getTemplate, this.text.clone(buffer), this.parsed); + } + }); + + lang.mixin(ddtl, { + block: function(parser, token){ + var parts = token.contents.split(); + var name = parts[1]; + + parser._blocks = parser._blocks || {}; + parser._blocks[name] = parser._blocks[name] || []; + parser._blocks[name].push(name); + + var nodelist = parser.parse(["endblock", "endblock " + name]).rtrim(); + parser.next_token(); + return new dojox.dtl.tag.loader.BlockNode(name, nodelist); + }, + extends_: function(parser, token){ + var parts = token.contents.split(); + var shared = false; + var parent = null; + var key = null; + if(parts[1].charAt(0) == '"' || parts[1].charAt(0) == "'"){ + parent = parts[1].substring(1, parts[1].length - 1); + }else{ + key = parts[1]; + } + if(parent && parent.indexOf("shared:") == 0){ + shared = true; + parent = parent.substring(7, parent.length); + } + var nodelist = parser.parse(); + return new dojox.dtl.tag.loader.ExtendsNode(parser.getTemplate, nodelist, shared, parent, key); + }, + include: function(parser, token){ + var parts = token.contents.split(); + if(parts.length != 2){ + throw new Error(parts[0] + " tag takes one argument: the name of the template to be included"); + } + var path = parts[1]; + var constant = false; + if((path.charAt(0) == '"' || path.slice(-1) == "'") && path.charAt(0) == path.slice(-1)){ + path = path.slice(1, -1); + constant = true; + } + return new ddtl.IncludeNode(path, constant, parser.getTemplate, parser.create_text_node()); + }, + ssi: function(parser, token){ + // We're going to treat things a little differently here. + // First of all, this tag is *not* portable, so I'm not + // concerned about it being a "drop in" replacement. + + // Instead, we'll just replicate the include tag, but with that + // optional "parsed" parameter. + var parts = token.contents.split(); + var parsed = false; + if(parts.length == 3){ + parsed = (parts.pop() == "parsed"); + if(!parsed){ + throw new Error("Second (optional) argument to ssi tag must be 'parsed'"); + } + } + var node = ddtl.include(parser, new dd.Token(token.token_type, parts.join(" "))); + node.parsed = parsed; + return node; + } + }); + return dojox.dtl.tag.loader; +}); +}, +'dojo/date':function(){ +define(["./_base/kernel", "./_base/lang"], function(dojo, lang) { + // module: + // dojo/date + // summary: + // TODOC + +lang.getObject("date", true, dojo); + +/*===== +dojo.date = { + // summary: Date manipulation utilities +} +=====*/ + +dojo.date.getDaysInMonth = function(/*Date*/dateObject){ + // summary: + // Returns the number of days in the month used by dateObject + var month = dateObject.getMonth(); + var days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + if(month == 1 && dojo.date.isLeapYear(dateObject)){ return 29; } // Number + return days[month]; // Number +}; + +dojo.date.isLeapYear = function(/*Date*/dateObject){ + // summary: + // Determines if the year of the dateObject is a leap year + // description: + // Leap years are years with an additional day YYYY-02-29, where the + // year number is a multiple of four with the following exception: If + // a year is a multiple of 100, then it is only a leap year if it is + // also a multiple of 400. For example, 1900 was not a leap year, but + // 2000 is one. + + var year = dateObject.getFullYear(); + return !(year%400) || (!(year%4) && !!(year%100)); // Boolean +}; + +// FIXME: This is not localized +dojo.date.getTimezoneName = function(/*Date*/dateObject){ + // summary: + // Get the user's time zone as provided by the browser + // dateObject: + // Needed because the timezone may vary with time (daylight savings) + // description: + // Try to get time zone info from toString or toLocaleString method of + // the Date object -- UTC offset is not a time zone. See + // http://www.twinsun.com/tz/tz-link.htm Note: results may be + // inconsistent across browsers. + + var str = dateObject.toString(); // Start looking in toString + var tz = ''; // The result -- return empty string if nothing found + var match; + + // First look for something in parentheses -- fast lookup, no regex + var pos = str.indexOf('('); + if(pos > -1){ + tz = str.substring(++pos, str.indexOf(')')); + }else{ + // If at first you don't succeed ... + // If IE knows about the TZ, it appears before the year + // Capital letters or slash before a 4-digit year + // at the end of string + var pat = /([A-Z\/]+) \d{4}$/; + if((match = str.match(pat))){ + tz = match[1]; + }else{ + // Some browsers (e.g. Safari) glue the TZ on the end + // of toLocaleString instead of putting it in toString + str = dateObject.toLocaleString(); + // Capital letters or slash -- end of string, + // after space + pat = / ([A-Z\/]+)$/; + if((match = str.match(pat))){ + tz = match[1]; + } + } + } + + // Make sure it doesn't somehow end up return AM or PM + return (tz == 'AM' || tz == 'PM') ? '' : tz; // String +}; + +// Utility methods to do arithmetic calculations with Dates + +dojo.date.compare = function(/*Date*/date1, /*Date?*/date2, /*String?*/portion){ + // summary: + // Compare two date objects by date, time, or both. + // description: + // Returns 0 if equal, positive if a > b, else negative. + // date1: + // Date object + // date2: + // Date object. If not specified, the current Date is used. + // portion: + // A string indicating the "date" or "time" portion of a Date object. + // Compares both "date" and "time" by default. One of the following: + // "date", "time", "datetime" + + // Extra step required in copy for IE - see #3112 + date1 = new Date(+date1); + date2 = new Date(+(date2 || new Date())); + + if(portion == "date"){ + // Ignore times and compare dates. + date1.setHours(0, 0, 0, 0); + date2.setHours(0, 0, 0, 0); + }else if(portion == "time"){ + // Ignore dates and compare times. + date1.setFullYear(0, 0, 0); + date2.setFullYear(0, 0, 0); + } + + if(date1 > date2){ return 1; } // int + if(date1 < date2){ return -1; } // int + return 0; // int +}; + +dojo.date.add = function(/*Date*/date, /*String*/interval, /*int*/amount){ + // summary: + // Add to a Date in intervals of different size, from milliseconds to years + // date: Date + // Date object to start with + // interval: + // A string representing the interval. One of the following: + // "year", "month", "day", "hour", "minute", "second", + // "millisecond", "quarter", "week", "weekday" + // amount: + // How much to add to the date. + + var sum = new Date(+date); // convert to Number before copying to accomodate IE (#3112) + var fixOvershoot = false; + var property = "Date"; + + switch(interval){ + case "day": + break; + case "weekday": + //i18n FIXME: assumes Saturday/Sunday weekend, but this is not always true. see dojo.cldr.supplemental + + // Divide the increment time span into weekspans plus leftover days + // e.g., 8 days is one 5-day weekspan / and two leftover days + // Can't have zero leftover days, so numbers divisible by 5 get + // a days value of 5, and the remaining days make up the number of weeks + var days, weeks; + var mod = amount % 5; + if(!mod){ + days = (amount > 0) ? 5 : -5; + weeks = (amount > 0) ? ((amount-5)/5) : ((amount+5)/5); + }else{ + days = mod; + weeks = parseInt(amount/5); + } + // Get weekday value for orig date param + var strt = date.getDay(); + // Orig date is Sat / positive incrementer + // Jump over Sun + var adj = 0; + if(strt == 6 && amount > 0){ + adj = 1; + }else if(strt == 0 && amount < 0){ + // Orig date is Sun / negative incrementer + // Jump back over Sat + adj = -1; + } + // Get weekday val for the new date + var trgt = strt + days; + // New date is on Sat or Sun + if(trgt == 0 || trgt == 6){ + adj = (amount > 0) ? 2 : -2; + } + // Increment by number of weeks plus leftover days plus + // weekend adjustments + amount = (7 * weeks) + days + adj; + break; + case "year": + property = "FullYear"; + // Keep increment/decrement from 2/29 out of March + fixOvershoot = true; + break; + case "week": + amount *= 7; + break; + case "quarter": + // Naive quarter is just three months + amount *= 3; + // fallthrough... + case "month": + // Reset to last day of month if you overshoot + fixOvershoot = true; + property = "Month"; + break; +// case "hour": +// case "minute": +// case "second": +// case "millisecond": + default: + property = "UTC"+interval.charAt(0).toUpperCase() + interval.substring(1) + "s"; + } + + if(property){ + sum["set"+property](sum["get"+property]()+amount); + } + + if(fixOvershoot && (sum.getDate() < date.getDate())){ + sum.setDate(0); + } + + return sum; // Date +}; + +dojo.date.difference = function(/*Date*/date1, /*Date?*/date2, /*String?*/interval){ + // summary: + // Get the difference in a specific unit of time (e.g., number of + // months, weeks, days, etc.) between two dates, rounded to the + // nearest integer. + // date1: + // Date object + // date2: + // Date object. If not specified, the current Date is used. + // interval: + // A string representing the interval. One of the following: + // "year", "month", "day", "hour", "minute", "second", + // "millisecond", "quarter", "week", "weekday" + // Defaults to "day". + + date2 = date2 || new Date(); + interval = interval || "day"; + var yearDiff = date2.getFullYear() - date1.getFullYear(); + var delta = 1; // Integer return value + + switch(interval){ + case "quarter": + var m1 = date1.getMonth(); + var m2 = date2.getMonth(); + // Figure out which quarter the months are in + var q1 = Math.floor(m1/3) + 1; + var q2 = Math.floor(m2/3) + 1; + // Add quarters for any year difference between the dates + q2 += (yearDiff * 4); + delta = q2 - q1; + break; + case "weekday": + var days = Math.round(dojo.date.difference(date1, date2, "day")); + var weeks = parseInt(dojo.date.difference(date1, date2, "week")); + var mod = days % 7; + + // Even number of weeks + if(mod == 0){ + days = weeks*5; + }else{ + // Weeks plus spare change (< 7 days) + var adj = 0; + var aDay = date1.getDay(); + var bDay = date2.getDay(); + + weeks = parseInt(days/7); + mod = days % 7; + // Mark the date advanced by the number of + // round weeks (may be zero) + var dtMark = new Date(date1); + dtMark.setDate(dtMark.getDate()+(weeks*7)); + var dayMark = dtMark.getDay(); + + // Spare change days -- 6 or less + if(days > 0){ + switch(true){ + // Range starts on Sat + case aDay == 6: + adj = -1; + break; + // Range starts on Sun + case aDay == 0: + adj = 0; + break; + // Range ends on Sat + case bDay == 6: + adj = -1; + break; + // Range ends on Sun + case bDay == 0: + adj = -2; + break; + // Range contains weekend + case (dayMark + mod) > 5: + adj = -2; + } + }else if(days < 0){ + switch(true){ + // Range starts on Sat + case aDay == 6: + adj = 0; + break; + // Range starts on Sun + case aDay == 0: + adj = 1; + break; + // Range ends on Sat + case bDay == 6: + adj = 2; + break; + // Range ends on Sun + case bDay == 0: + adj = 1; + break; + // Range contains weekend + case (dayMark + mod) < 0: + adj = 2; + } + } + days += adj; + days -= (weeks*2); + } + delta = days; + break; + case "year": + delta = yearDiff; + break; + case "month": + delta = (date2.getMonth() - date1.getMonth()) + (yearDiff * 12); + break; + case "week": + // Truncate instead of rounding + // Don't use Math.floor -- value may be negative + delta = parseInt(dojo.date.difference(date1, date2, "day")/7); + break; + case "day": + delta /= 24; + // fallthrough + case "hour": + delta /= 60; + // fallthrough + case "minute": + delta /= 60; + // fallthrough + case "second": + delta /= 1000; + // fallthrough + case "millisecond": + delta *= date2.getTime() - date1.getTime(); + } + + // Round for fractional values and DST leaps + return Math.round(delta); // Number (integer) +}; + +return dojo.date; +}); + +}, +'dojox/date/php':function(){ +define("dojox/date/php", ["dojo/_base/kernel", "dojo/_base/lang","dojo/date","dojox/string/tokenize"], function(dojo,dlang,ddate,dxst){ +dojo.getObject("date.php", true, dojox); + +dojox.date.php.format = function(/*Date*/ date, /*String*/ format){ + // summary: Get a formatted string for a given date object + var df = new dojox.date.php.DateFormat(format); + return df.format(date); +} + +dojox.date.php.DateFormat = function(/*String*/ format){ + // summary: Format the internal date object + if(!this.regex){ + var keys = []; + for(var key in this.constructor.prototype){ + if(dojo.isString(key) && key.length == 1 && dojo.isFunction(this[key])){ + keys.push(key); + } + } + this.constructor.prototype.regex = new RegExp("(?:(\\\\.)|([" + keys.join("") + "]))", "g"); + } + + var replacements = []; + + this.tokens = dxst(format, this.regex, function(escape, token, i){ + if(token){ + replacements.push([i, token]); + return token; + } + if(escape){ + return escape.charAt(1); + } + }); + + this.replacements = replacements; +} +dojo.extend(dojox.date.php.DateFormat, { + weekdays: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], + weekdays_3: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], + months_3: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], + monthdays: [31,28,31,30,31,30,31,31,30,31,30,31], + + format: function(/*Date*/ date){ + this.date = date; + for(var i = 0, replacement; replacement = this.replacements[i]; i++){ + this.tokens[replacement[0]] = this[replacement[1]](); + } + return this.tokens.join(""); + }, + + // Day + + d: function(){ + // summary: Day of the month, 2 digits with leading zeros + var j = this.j(); + return (j.length == 1) ? "0" + j : j; + }, + + D: function(){ + // summary: A textual representation of a day, three letters + return this.weekdays_3[this.date.getDay()]; + }, + + j: function(){ + // summary: Day of the month without leading zeros + return this.date.getDate() + ""; + }, + + l: function(){ + // summary: A full textual representation of the day of the week + return this.weekdays[this.date.getDay()]; + }, + + N: function(){ + // summary: ISO-8601 numeric representation of the day of the week (added in PHP 5.1.0) + var w = this.w(); + return (!w) ? 7 : w; + }, + + S: function(){ + // summary: English ordinal suffix for the day of the month, 2 characters + switch(this.date.getDate()){ + case 11: case 12: case 13: return "th"; + case 1: case 21: case 31: return "st"; + case 2: case 22: return "nd"; + case 3: case 23: return "rd"; + default: return "th"; + } + }, + + w: function(){ + // summary: Numeric representation of the day of the week + return this.date.getDay() + ""; + }, + + z: function(){ + // summary: The day of the year (starting from 0) + var millis = this.date.getTime() - new Date(this.date.getFullYear(), 0, 1).getTime(); + return Math.floor(millis/86400000) + ""; + }, + + // Week + + W: function(){ + // summary: ISO-8601 week number of year, weeks starting on Monday (added in PHP 4.1.0) + var week; + var jan1_w = new Date(this.date.getFullYear(), 0, 1).getDay() + 1; + var w = this.date.getDay() + 1; + var z = parseInt(this.z()); + + if(z <= (8 - jan1_w) && jan1_w > 4){ + var last_year = new Date(this.date.getFullYear() - 1, this.date.getMonth(), this.date.getDate()); + if(jan1_w == 5 || (jan1_w == 6 && ddate.isLeapYear(last_year))){ + week = 53; + }else{ + week = 52; + } + }else{ + var i; + if(Boolean(this.L())){ + i = 366; + }else{ + i = 365; + } + if((i - z) < (4 - w)){ + week = 1; + }else{ + var j = z + (7 - w) + (jan1_w - 1); + week = Math.ceil(j / 7); + if(jan1_w > 4){ + --week; + } + } + } + + return week; + }, + + // Month + + F: function(){ + // summary: A full textual representation of a month, such as January or March + return this.months[this.date.getMonth()]; + }, + + m: function(){ + // summary: Numeric representation of a month, with leading zeros + var n = this.n(); + return (n.length == 1) ? "0" + n : n; + }, + + M: function(){ + // summary: A short textual representation of a month, three letters + return this.months_3[this.date.getMonth()]; + }, + + n: function(){ + // summary: Numeric representation of a month, without leading zeros + return this.date.getMonth() + 1 + ""; + }, + + t: function(){ + // summary: Number of days in the given month + return (Boolean(this.L()) && this.date.getMonth() == 1) ? 29 : this.monthdays[this.getMonth()]; + }, + + // Year + + L: function(){ + // summary: Whether it's a leap year + return (ddate.isLeapYear(this.date)) ? "1" : "0"; + }, + + o: function(){ + // summary: + // ISO-8601 year number. This has the same value as Y, except that if + // the ISO week number (W) belongs to the previous or next year, that year is used instead. (added in PHP 5.1.0) + // TODO: Figure out what this means + }, + + Y: function(){ + // summary: A full numeric representation of a year, 4 digits + return this.date.getFullYear() + ""; + }, + + y: function(){ + // summary: A two digit representation of a year + return this.Y().slice(-2); + }, + + // Time + + a: function(){ + // summary: Lowercase Ante meridiem and Post meridiem + return this.date.getHours() >= 12 ? "pm" : "am"; + }, + + b: function(){ + // summary: Uppercase Ante meridiem and Post meridiem + return this.a().toUpperCase(); + }, + + B: function(){ + // summary: + // Swatch Internet time + // A day is 1,000 beats. All time is measured from GMT + 1 + var off = this.date.getTimezoneOffset() + 60; + var secs = (this.date.getHours() * 3600) + (this.date.getMinutes() * 60) + this.getSeconds() + (off * 60); + var beat = Math.abs(Math.floor(secs / 86.4) % 1000) + ""; + while(beat.length < 2) beat = "0" + beat; + return beat; + }, + + g: function(){ + // summary: 12-hour format of an hour without leading zeros + return (this.date.getHours() > 12) ? this.date.getHours() - 12 + "" : this.date.getHours() + ""; + }, + + G: function(){ + // summary: 24-hour format of an hour without leading zeros + return this.date.getHours() + ""; + }, + + h: function(){ + // summary: 12-hour format of an hour with leading zeros + var g = this.g(); + return (g.length == 1) ? "0" + g : g; + }, + + H: function(){ + // summary: 24-hour format of an hour with leading zeros + var G = this.G(); + return (G.length == 1) ? "0" + G : G; + }, + + i: function(){ + // summary: Minutes with leading zeros + var mins = this.date.getMinutes() + ""; + return (mins.length == 1) ? "0" + mins : mins; + }, + + s: function(){ + // summary: Seconds, with leading zeros + var secs = this.date.getSeconds() + ""; + return (secs.length == 1) ? "0" + secs : secs; + }, + + // Timezone + + e: function(){ + // summary: Timezone identifier (added in PHP 5.1.0) + return ddate.getTimezoneName(this.date); + }, + + I: function(){ + // summary: Whether or not the date is in daylight saving time + // TODO: Can dojo.date do this? + }, + + O: function(){ + // summary: Difference to Greenwich time (GMT) in hours + var off = Math.abs(this.date.getTimezoneOffset()); + var hours = Math.floor(off / 60) + ""; + var mins = (off % 60) + ""; + if(hours.length == 1) hours = "0" + hours; + if(mins.length == 1) hours = "0" + mins; + return ((this.date.getTimezoneOffset() < 0) ? "+" : "-") + hours + mins; + }, + + P: function(){ + // summary: Difference to Greenwich time (GMT) with colon between hours and minutes (added in PHP 5.1.3) + var O = this.O(); + return O.substring(0, 2) + ":" + O.substring(2, 4); + }, + + T: function(){ + // summary: Timezone abbreviation + + // Guess... + return this.e().substring(0, 3); + }, + + Z: function(){ + // summary: + // Timezone offset in seconds. The offset for timezones west of UTC is always negative, + // and for those east of UTC is always positive. + return this.date.getTimezoneOffset() * -60; + }, + + // Full Date/Time + + c: function(){ + // summary: ISO 8601 date (added in PHP 5) + return this.Y() + "-" + this.m() + "-" + this.d() + "T" + this.h() + ":" + this.i() + ":" + this.s() + this.P(); + }, + + r: function(){ + // summary: RFC 2822 formatted date + return this.D() + ", " + this.d() + " " + this.M() + " " + this.Y() + " " + this.H() + ":" + this.i() + ":" + this.s() + " " + this.O(); + }, + + U: function(){ + // summary: Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) + return Math.floor(this.date.getTime() / 1000); + } + +}); +return dojox.date.php; +}); +}, +'dojox/dtl/ext-dojo/NodeList':function(){ +define([ + "dojo/_base/lang", + "dojo/_base/NodeList", + "../_base" +], function(lang,Nodelist,dd){ + /*===== + Nodelist = dojo.Nodelist; + dd = dojox.dtl; + =====*/ + + var nl = lang.getObject("dojox.dtl.ext-dojo.NodeList", true); + + lang.extend(Nodelist, { + dtl: function(template, context){ + // summary: Renders the specified template in each of the Nodelist entries. + // template: dojox.dtl.__StringArgs|String + // The template string or location + // context: dojox.dtl.__ObjectArgs|Object + // The context object or location + var d = dd, self = this; + + var render = function(template, context){ + var content = template.render(new d._Context(context)); + self.forEach(function(node){ + node.innerHTML = content; + }); + } + + d.text._resolveTemplateArg(template).addCallback(function(templateString){ + template = new d.Template(templateString); + d.text._resolveContextArg(context).addCallback(function(context){ + render(template, context); + }); + }); + + return this; + } + }); + return nl; +}); +}, +'dojox/dtl/utils/date':function(){ +define("dojox/dtl/utils/date", [ + "dojo/_base/lang", + "dojox/date/php", + "../_base" +], function(lang,ddp,dd){ + /*===== + ddp = dojox.data.php; + dd = dojox.dtl; + =====*/ + lang.getObject("dojox.dtl.utils.date", true); + + dd.utils.date.DateFormat = ddp.DateFormat; + lang.extend(dd.utils.date.DateFormat, ddp.DateFormat.prototype, { + f: function(){ + // summary: + // Time, in 12-hour hours and minutes, with minutes left off if they're zero. + // description: + // Examples: '1', '1:30', '2:05', '2' + // Proprietary extension. + return (!this.date.getMinutes()) ? this.g() : this.g() + ":" + this.i(); + }, + N: function(){ + // summary: Month abbreviation in Associated Press style. Proprietary extension. + return dojox.dtl.utils.date._months_ap[this.date.getMonth()]; + }, + P: function(){ + // summary: + // Time, in 12-hour hours, minutes and 'a.m.'/'p.m.', with minutes left off + // if they're zero and the strings 'midnight' and 'noon' if appropriate. + // description: + // Examples: '1 a.m.', '1:30 p.m.', 'midnight', 'noon', '12:30 p.m.' + // Proprietary extension. + if(!this.date.getMinutes() && !this.date.getHours()){ + return 'midnight'; + } + if(!this.date.getMinutes() && this.date.getHours() == 12){ + return 'noon'; + } + return this.f() + " " + this.a(); + } + }); + + lang.mixin(dojox.dtl.utils.date, { + format: function(/*Date*/ date, /*String*/ format){ + var df = new dojox.dtl.utils.date.DateFormat(format); + return df.format(date); + }, + timesince: function(d, now){ + // summary: + // Takes two datetime objects and returns the time between then and now + // as a nicely formatted string, e.g "10 minutes" + // description: + // Adapted from http://blog.natbat.co.uk/archive/2003/Jun/14/time_since + if(!(d instanceof Date)){ + d = new Date(d.year, d.month, d.day); + } + if(!now){ + now = new Date(); + } + + var delta = Math.abs(now.getTime() - d.getTime()); + for(var i = 0, chunk; chunk = dojox.dtl.utils.date._chunks[i]; i++){ + var count = Math.floor(delta / chunk[0]); + if(count) break; + } + return count + " " + chunk[1](count); + }, + _chunks: [ + [60 * 60 * 24 * 365 * 1000, function(n){ return (n == 1) ? 'year' : 'years'; }], + [60 * 60 * 24 * 30 * 1000, function(n){ return (n == 1) ? 'month' : 'months'; }], + [60 * 60 * 24 * 7 * 1000, function(n){ return (n == 1) ? 'week' : 'weeks'; }], + [60 * 60 * 24 * 1000, function(n){ return (n == 1) ? 'day' : 'days'; }], + [60 * 60 * 1000, function(n){ return (n == 1) ? 'hour' : 'hours'; }], + [60 * 1000, function(n){ return (n == 1) ? 'minute' : 'minutes'; }] + ], + _months_ap: ["Jan.", "Feb.", "March", "April", "May", "June", "July", "Aug.", "Sept.", "Oct.", "Nov.", "Dec."] + }); + return dojox.dtl.utils.date; +}); + +}, +'dojox/dtl/tag/loop':function(){ +define("dojox/dtl/tag/loop", [ + "dojo/_base/lang", + "dojo/_base/array", + "dojo/_base/json", + "../_base", + "dojox/string/tokenize" +], function(lang,array,json,dd,Tokenize){ + /*===== + Tokenize = dojox.string.tokenize; + dd = dojox.dtl; + =====*/ + lang.getObject("dojox.dtl.tag.loop", true); + + var ddtl = dd.tag.loop; + + ddtl.CycleNode = lang.extend(function(cyclevars, name, text, shared){ + this.cyclevars = cyclevars; + this.name = name; + this.contents = text; + this.shared = shared || {counter: -1, map: {}}; + }, + { + render: function(context, buffer){ + if(context.forloop && !context.forloop.counter0){ + this.shared.counter = -1; + } + + ++this.shared.counter; + var value = this.cyclevars[this.shared.counter % this.cyclevars.length]; + + var map = this.shared.map; + if(!map[value]){ + map[value] = new dd._Filter(value); + } + value = map[value].resolve(context, buffer); + + if(this.name){ + context[this.name] = value; + } + this.contents.set(value); + return this.contents.render(context, buffer); + }, + unrender: function(context, buffer){ + return this.contents.unrender(context, buffer); + }, + clone: function(buffer){ + return new this.constructor(this.cyclevars, this.name, this.contents.clone(buffer), this.shared); + } + }); + + ddtl.IfChangedNode = lang.extend(function(nodes, vars, shared){ + this.nodes = nodes; + this._vars = vars; + this.shared = shared || {last: null, counter: 0}; + this.vars = array.map(vars, function(item){ + return new dojox.dtl._Filter(item); + }); + }, { + render: function(context, buffer){ + if(context.forloop){ + if(context.forloop.counter <= this.shared.counter){ + this.shared.last = null; + } + this.shared.counter = context.forloop.counter; + } + + var change; + if(this.vars.length){ + change = json.toJson(array.map(this.vars, function(item){ + return item.resolve(context); + })); + }else{ + change = this.nodes.dummyRender(context, buffer); + } + + if(change != this.shared.last){ + var firstloop = (this.shared.last === null); + this.shared.last = change; + context = context.push(); + context.ifchanged = {firstloop: firstloop}; + buffer = this.nodes.render(context, buffer); + context = context.pop(); + }else{ + buffer = this.nodes.unrender(context, buffer); + } + return buffer; + }, + unrender: function(context, buffer){ + return this.nodes.unrender(context, buffer); + }, + clone: function(buffer){ + return new this.constructor(this.nodes.clone(buffer), this._vars, this.shared); + } + }); + + ddtl.RegroupNode = lang.extend(function(expression, key, alias){ + this._expression = expression; + this.expression = new dd._Filter(expression); + this.key = key; + this.alias = alias; + }, + { + _push: function(container, grouper, stack){ + if(stack.length){ + container.push({ grouper: grouper, list: stack }); + } + }, + render: function(context, buffer){ + context[this.alias] = []; + var list = this.expression.resolve(context); + if(list){ + var last = null; + var stack = []; + for(var i = 0; i < list.length; i++){ + var id = list[i][this.key]; + if(last !== id){ + this._push(context[this.alias], last, stack); + last = id; + stack = [list[i]]; + }else{ + stack.push(list[i]); + } + } + this._push(context[this.alias], last, stack); + } + return buffer; + }, + unrender: function(context, buffer){ + return buffer; + }, + clone: function(context, buffer){ + return this; + } + }); + + lang.mixin(ddtl, { + cycle: function(parser, token){ + // summary: Cycle among the given strings each time this tag is encountered + var args = token.split_contents(); + + if(args.length < 2){ + throw new Error("'cycle' tag requires at least two arguments"); + } + + if(args[1].indexOf(",") != -1){ + var vars = args[1].split(","); + args = [args[0]]; + for(var i = 0; i < vars.length; i++){ + args.push('"' + vars[i] + '"'); + } + } + + if(args.length == 2){ + var name = args[args.length - 1]; + + if(!parser._namedCycleNodes){ + throw new Error("No named cycles in template: '" + name + "' is not defined"); + } + if(!parser._namedCycleNodes[name]){ + throw new Error("Named cycle '" + name + "' does not exist"); + } + + return parser._namedCycleNodes[name]; + } + + if(args.length > 4 && args[args.length - 2] == "as"){ + var name = args[args.length - 1]; + + var node = new ddtl.CycleNode(args.slice(1, args.length - 2), name, parser.create_text_node()); + + if(!parser._namedCycleNodes){ + parser._namedCycleNodes = {}; + } + parser._namedCycleNodes[name] = node; + }else{ + node = new ddtl.CycleNode(args.slice(1), null, parser.create_text_node()); + } + + return node; + }, + ifchanged: function(parser, token){ + var parts = token.contents.split(); + var nodes = parser.parse(["endifchanged"]); + parser.delete_first_token(); + return new ddtl.IfChangedNode(nodes, parts.slice(1)); + }, + regroup: function(parser, token){ + var tokens = Tokenize(token.contents, /(\s+)/g, function(spaces){ + return spaces; + }); + if(tokens.length < 11 || tokens[tokens.length - 3] != "as" || tokens[tokens.length - 7] != "by"){ + throw new Error("Expected the format: regroup list by key as newList"); + } + var expression = tokens.slice(2, -8).join(""); + var key = tokens[tokens.length - 5]; + var alias = tokens[tokens.length - 1]; + return new ddtl.RegroupNode(expression, key, alias); + } + }); + return dojox.dtl.tag.loop; +}); +}, +'dojox/string/Builder':function(){ +define("dojox/string/Builder", ["dojo/_base/lang"], + function(lang){ + lang.getObject("string", true, dojox).Builder = + function(/*String?*/str){ + // summary: + // A fast buffer for creating large strings. + // + // length: Number + // The current length of the internal string. + + // N.B. the public nature of the internal buffer is no longer + // needed because the IE-specific fork is no longer needed--TRT. + var b = ""; + this.length = 0; + + this.append = function(/* String... */s){ + // summary: Append all arguments to the end of the buffer + if(arguments.length>1){ + /* + This is a loop unroll was designed specifically for Firefox; + it would seem that static index access on an Arguments + object is a LOT faster than doing dynamic index access. + Therefore, we create a buffer string and take advantage + of JS's switch fallthrough. The peformance of this method + comes very close to straight up string concatenation (+=). + + If the arguments object length is greater than 9, we fall + back to standard dynamic access. + + This optimization seems to have no real effect on either + Safari or Opera, so we just use it for all. + + It turns out also that this loop unroll can increase performance + significantly with Internet Explorer, particularly when + as many arguments are provided as possible. + + Loop unroll per suggestion from Kris Zyp, implemented by + Tom Trenka. + + Note: added empty string to force a string cast if needed. + */ + var tmp="", l=arguments.length; + switch(l){ + case 9: tmp=""+arguments[8]+tmp; + case 8: tmp=""+arguments[7]+tmp; + case 7: tmp=""+arguments[6]+tmp; + case 6: tmp=""+arguments[5]+tmp; + case 5: tmp=""+arguments[4]+tmp; + case 4: tmp=""+arguments[3]+tmp; + case 3: tmp=""+arguments[2]+tmp; + case 2: { + b+=""+arguments[0]+arguments[1]+tmp; + break; + } + default: { + var i=0; + while(i<arguments.length){ + tmp += arguments[i++]; + } + b += tmp; + } + } + } else { + b += s; + } + this.length = b.length; + return this; // dojox.string.Builder + }; + + this.concat = function(/*String...*/s){ + // summary: + // Alias for append. + return this.append.apply(this, arguments); // dojox.string.Builder + }; + + this.appendArray = function(/*Array*/strings) { + // summary: + // Append an array of items to the internal buffer. + + // Changed from String.prototype.concat.apply because of IE. + return this.append.apply(this, strings); // dojox.string.Builder + }; + + this.clear = function(){ + // summary: + // Remove all characters from the buffer. + b = ""; + this.length = 0; + return this; // dojox.string.Builder + }; + + this.replace = function(/* String */oldStr, /* String */ newStr){ + // summary: + // Replace instances of one string with another in the buffer. + b = b.replace(oldStr,newStr); + this.length = b.length; + return this; // dojox.string.Builder + }; + + this.remove = function(/* Number */start, /* Number? */len){ + // summary: + // Remove len characters starting at index start. If len + // is not provided, the end of the string is assumed. + if(len===undefined){ len = b.length; } + if(len == 0){ return this; } + b = b.substr(0, start) + b.substr(start+len); + this.length = b.length; + return this; // dojox.string.Builder + }; + + this.insert = function(/* Number */index, /* String */str){ + // summary: + // Insert string str starting at index. + if(index == 0){ + b = str + b; + }else{ + b = b.slice(0, index) + str + b.slice(index); + } + this.length = b.length; + return this; // dojox.string.Builder + }; + + this.toString = function(){ + // summary: + // Return the string representation of the internal buffer. + return b; // String + }; + + // initialize the buffer. + if(str){ this.append(str); } + }; + return dojox.string.Builder; +}); + +}, +'dojox/string/tokenize':function(){ +define([ + "dojo/_base/lang", + "dojo/_base/sniff" +], function(lang, has){ + var tokenize = lang.getObject("dojox.string", true).tokenize; + + tokenize = function(/*String*/ str, /*RegExp*/ re, /*Function?*/ parseDelim, /*Object?*/ instance){ + // summary: + // Split a string by a regular expression with the ability to capture the delimeters + // parseDelim: + // Each group (excluding the 0 group) is passed as a parameter. If the function returns + // a value, it's added to the list of tokens. + // instance: + // Used as the "this" instance when calling parseDelim + var tokens = []; + var match, content, lastIndex = 0; + while(match = re.exec(str)){ + content = str.slice(lastIndex, re.lastIndex - match[0].length); + if(content.length){ + tokens.push(content); + } + if(parseDelim){ + if(has("opera")){ + var copy = match.slice(0); + while(copy.length < match.length){ + copy.push(null); + } + match = copy; + } + var parsed = parseDelim.apply(instance, match.slice(1).concat(tokens.length)); + if(typeof parsed != "undefined"){ + tokens.push(parsed); + } + } + lastIndex = re.lastIndex; + } + content = str.slice(lastIndex); + if(content.length){ + tokens.push(content); + } + return tokens; + }; + return tokenize; +}); + +}, +'dojox/dtl/tag/misc':function(){ +define("dojox/dtl/tag/misc", [ + "dojo/_base/lang", + "dojo/_base/array", + "dojo/_base/connect", + "../_base" +], function(lang,array,connect,dd){ + /*===== + dd = dojox.dtl; + =====*/ + lang.getObject("dojox.dtl.tag.misc", true); + + var ddtm = dd.tag.misc; + + ddtm.DebugNode = lang.extend(function(text){ + this.text = text; + }, + { + render: function(context, buffer){ + var keys = context.getKeys(); + var debug = []; + var only = {}; + for(var i = 0, key; key = keys[i]; i++){ + only[key] = context[key]; + debug += "[" + key + ": " + typeof context[key] + "]\n"; + } + console.debug(only); + return this.text.set(debug).render(context, buffer, this); + }, + unrender: function(context, buffer){ + return buffer; + }, + clone: function(buffer){ + return new this.constructor(this.text.clone(buffer)); + }, + toString: function(){ return "ddtm.DebugNode"; } + }); + + ddtm.FilterNode = lang.extend(function(varnode, nodelist){ + this._varnode = varnode; + this._nodelist = nodelist; + }, + { + render: function(context, buffer){ + // Doing this in HTML requires a different buffer with a fake root node + var output = this._nodelist.render(context, new dojox.string.Builder()); + context = context.update({ "var": output.toString() }); + var filtered = this._varnode.render(context, buffer); + context = context.pop(); + return buffer; + }, + unrender: function(context, buffer){ + return buffer; + }, + clone: function(buffer){ + return new this.constructor(this._expression, this._nodelist.clone(buffer)); + } + }); + + ddtm.FirstOfNode = lang.extend(function(vars, text){ + this._vars = vars; + this.vars = array.map(vars, function(item){ + return new dojox.dtl._Filter(item); + }); + this.contents = text; + }, + { + render: function(context, buffer){ + for(var i = 0, item; item = this.vars[i]; i++){ + var resolved = item.resolve(context); + if(typeof resolved != "undefined"){ + if(resolved === null){ + resolved = "null"; + } + this.contents.set(resolved); + return this.contents.render(context, buffer); + } + } + return this.contents.unrender(context, buffer); + }, + unrender: function(context, buffer){ + return this.contents.unrender(context, buffer); + }, + clone: function(buffer){ + return new this.constructor(this._vars, this.contents.clone(buffer)); + } + }); + + ddtm.SpacelessNode = lang.extend(function(nodelist, text){ + this.nodelist = nodelist; + this.contents = text; + }, + { + render: function(context, buffer){ + if(buffer.getParent){ + // Unfortunately, we have to branch here + var watch = [ + connect.connect(buffer, "onAddNodeComplete", this, "_watch"), + connect.connect(buffer, "onSetParent", this, "_watchParent") + ]; + buffer = this.nodelist.render(context, buffer); + connect.disconnect(watch[0]); + connect.disconnect(watch[1]); + }else{ + var value = this.nodelist.dummyRender(context); + this.contents.set(value.replace(/>\s+</g, '><')); + buffer = this.contents.render(context, buffer); + } + return buffer; + }, + unrender: function(context, buffer){ + return this.nodelist.unrender(context, buffer); + }, + clone: function(buffer){ + return new this.constructor(this.nodelist.clone(buffer), this.contents.clone(buffer)); + }, + _isEmpty: function(node){ + return (node.nodeType == 3 && !node.data.match(/[^\s\n]/)); + }, + _watch: function(node){ + if(this._isEmpty(node)){ + var remove = false; + if(node.parentNode.firstChild == node){ + node.parentNode.removeChild(node); + } + }else{ + var children = node.parentNode.childNodes; + if(node.nodeType == 1 && children.length > 2){ + for(var i = 2, child; child = children[i]; i++){ + if(children[i - 2].nodeType == 1 && this._isEmpty(children[i - 1])){ + node.parentNode.removeChild(children[i - 1]); + return; + } + } + } + } + }, + _watchParent: function(node){ + var children = node.childNodes; + if(children.length){ + while(node.childNodes.length){ + var last = node.childNodes[node.childNodes.length - 1]; + if(!this._isEmpty(last)){ + return; + } + node.removeChild(last); + } + } + } + }); + + ddtm.TemplateTagNode = lang.extend(function(tag, text){ + this.tag = tag; + this.contents = text; + }, + { + mapping: { + openblock: "{%", + closeblock: "%}", + openvariable: "{{", + closevariable: "}}", + openbrace: "{", + closebrace: "}", + opencomment: "{#", + closecomment: "#}" + }, + render: function(context, buffer){ + this.contents.set(this.mapping[this.tag]); + return this.contents.render(context, buffer); + }, + unrender: function(context, buffer){ + return this.contents.unrender(context, buffer); + }, + clone: function(buffer){ + return new this.constructor(this.tag, this.contents.clone(buffer)); + } + }); + + ddtm.WidthRatioNode = lang.extend(function(current, max, width, text){ + this.current = new dd._Filter(current); + this.max = new dd._Filter(max); + this.width = width; + this.contents = text; + }, + { + render: function(context, buffer){ + var current = +this.current.resolve(context); + var max = +this.max.resolve(context); + if(typeof current != "number" || typeof max != "number" || !max){ + this.contents.set(""); + }else{ + this.contents.set("" + Math.round((current / max) * this.width)); + } + return this.contents.render(context, buffer); + }, + unrender: function(context, buffer){ + return this.contents.unrender(context, buffer); + }, + clone: function(buffer){ + return new this.constructor(this.current.getExpression(), this.max.getExpression(), this.width, this.contents.clone(buffer)); + } + }); + + ddtm.WithNode = lang.extend(function(target, alias, nodelist){ + this.target = new dd._Filter(target); + this.alias = alias; + this.nodelist = nodelist; + }, + { + render: function(context, buffer){ + var target = this.target.resolve(context); + context = context.push(); + context[this.alias] = target; + buffer = this.nodelist.render(context, buffer); + context = context.pop(); + return buffer; + }, + unrender: function(context, buffer){ + return buffer; + }, + clone: function(buffer){ + return new this.constructor(this.target.getExpression(), this.alias, this.nodelist.clone(buffer)); + } + }); + + lang.mixin(ddtm, { + comment: function(parser, token){ + // summary: Ignore everything between {% comment %} and {% endcomment %} + parser.skip_past("endcomment"); + return dd._noOpNode; + }, + debug: function(parser, token){ + // summary: Output the current context, maybe add more stuff later. + return new ddtm.DebugNode(parser.create_text_node()); + }, + filter: function(parser, token){ + // summary: Filter the contents of the blog through variable filters. + var rest = token.contents.split(null, 1)[1]; + var varnode = parser.create_variable_node("var|" + rest); + var nodelist = parser.parse(["endfilter"]); + parser.next_token(); + return new ddtm.FilterNode(varnode, nodelist); + }, + firstof: function(parser, token){ + var parts = token.split_contents().slice(1); + if(!parts.length){ + throw new Error("'firstof' statement requires at least one argument"); + } + return new ddtm.FirstOfNode(parts, parser.create_text_node()); + }, + spaceless: function(parser, token){ + var nodelist = parser.parse(["endspaceless"]); + parser.delete_first_token(); + return new ddtm.SpacelessNode(nodelist, parser.create_text_node()); + }, + templatetag: function(parser, token){ + var parts = token.contents.split(); + if(parts.length != 2){ + throw new Error("'templatetag' statement takes one argument"); + } + var tag = parts[1]; + var mapping = ddtm.TemplateTagNode.prototype.mapping; + if(!mapping[tag]){ + var keys = []; + for(var key in mapping){ + keys.push(key); + } + throw new Error("Invalid templatetag argument: '" + tag + "'. Must be one of: " + keys.join(", ")); + } + return new ddtm.TemplateTagNode(tag, parser.create_text_node()); + }, + widthratio: function(parser, token){ + var parts = token.contents.split(); + if(parts.length != 4){ + throw new Error("widthratio takes three arguments"); + } + var width = +parts[3]; + if(typeof width != "number"){ + throw new Error("widthratio final argument must be an integer"); + } + return new ddtm.WidthRatioNode(parts[1], parts[2], width, parser.create_text_node()); + }, + with_: function(parser, token){ + var parts = token.split_contents(); + if(parts.length != 4 || parts[2] != "as"){ + throw new Error("do_width expected format as 'with value as name'"); + } + var nodelist = parser.parse(["endwith"]); + parser.next_token(); + return new ddtm.WithNode(parts[1], parts[3], nodelist); + } + }); + return dojox.dtl.tag.misc; +}); +}, +'dojox/dtl/Context':function(){ +define("dojox/dtl/Context", [ + "dojo/_base/lang", + "./_base" +], function(lang,dd){ + /*===== + dd = dojox.dtl; + =====*/ + + /*===== + dd.Context = function(dict){ + // summary: Represents a runtime context used by DTL templates. + } + + =====*/ + dd.Context = lang.extend(function(dict){ + this._this = {}; + dd._Context.call(this, dict); + }, dd._Context.prototype, + { + getKeys: function(){ + // summary: Returns the set of keys exported by this context. + var keys = []; + for(var key in this){ + if(this.hasOwnProperty(key) && key != "_this"){ + keys.push(key); + } + } + return keys; + }, + extend: function(/*dojox.dtl.Context|Object*/ obj){ + // summary: Returns a clone of this context object, with the items from the + // passed objecct mixed in. + return lang.delegate(this, obj); + }, + filter: function(/*dojox.dtl.Context|Object|String...*/ filter){ + // summary: Returns a clone of this context, only containing the items + // defined in the filter. + var context = new dd.Context(); + var keys = []; + var i, arg; + if(filter instanceof dd.Context){ + keys = filter.getKeys(); + }else if(typeof filter == "object"){ + for(var key in filter){ + keys.push(key); + } + }else{ + for(i = 0; arg = arguments[i]; i++){ + if(typeof arg == "string"){ + keys.push(arg); + } + } + } + + for(i = 0, key; key = keys[i]; i++){ + context[key] = this[key]; + } + + return context; + }, + setThis: function(/*Object*/ _this){ + // summary: Sets the object on which to perform operations. + // _this: the this ref. + this._this = _this; + }, + getThis: function(){ + // summary: Gets the object on which to perform operations. + return this._this; + }, + hasKey: function(/*String*/key){ + // summary: Indicates whether the specified key is defined on this context. + // key: The key to look up. + if(this._getter){ + var got = this._getter(key); + if(typeof got != "undefined"){ + return true; + } + } + + if(typeof this[key] != "undefined"){ + return true; + } + + return false; + } +}); +return dojox.dtl.Context; +}); +}, +'dojox/dtl/tag/logic':function(){ +define([ + "dojo/_base/lang", + "../_base" +], function(lang, dd){ + /*===== + dd = dojox.dtl; + =====*/ + lang.getObject("dojox.dtl.tag.logic", true); + + var ddt = dd.text; + var ddtl = dd.tag.logic; + + ddtl.IfNode = lang.extend(function(bools, trues, falses, type){ + this.bools = bools; + this.trues = trues; + this.falses = falses; + this.type = type; + }, + { + render: function(context, buffer){ + var i, bool, ifnot, filter, value; + if(this.type == "or"){ + for(i = 0; bool = this.bools[i]; i++){ + ifnot = bool[0]; + filter = bool[1]; + value = filter.resolve(context); + if((value && !ifnot) || (ifnot && !value)){ + if(this.falses){ + buffer = this.falses.unrender(context, buffer); + } + return (this.trues) ? this.trues.render(context, buffer, this) : buffer; + } + } + if(this.trues){ + buffer = this.trues.unrender(context, buffer); + } + return (this.falses) ? this.falses.render(context, buffer, this) : buffer; + }else{ + for(i = 0; bool = this.bools[i]; i++){ + ifnot = bool[0]; + filter = bool[1]; + value = filter.resolve(context); + // If we ever encounter a false value + if(value == ifnot){ + if(this.trues){ + buffer = this.trues.unrender(context, buffer); + } + return (this.falses) ? this.falses.render(context, buffer, this) : buffer; + } + } + if(this.falses){ + buffer = this.falses.unrender(context, buffer); + } + return (this.trues) ? this.trues.render(context, buffer, this) : buffer; + } + return buffer; + }, + unrender: function(context, buffer){ + buffer = (this.trues) ? this.trues.unrender(context, buffer) : buffer; + buffer = (this.falses) ? this.falses.unrender(context, buffer) : buffer; + return buffer; + }, + clone: function(buffer){ + var trues = (this.trues) ? this.trues.clone(buffer) : null; + var falses = (this.falses) ? this.falses.clone(buffer) : null; + return new this.constructor(this.bools, trues, falses, this.type); + } + }); + + ddtl.IfEqualNode = lang.extend(function(var1, var2, trues, falses, negate){ + this.var1 = new dd._Filter(var1); + this.var2 = new dd._Filter(var2); + this.trues = trues; + this.falses = falses; + this.negate = negate; + }, + { + render: function(context, buffer){ + var var1 = this.var1.resolve(context); + var var2 = this.var2.resolve(context); + var1 = (typeof var1 != "undefined") ? var1 : ""; + var2 = (typeof var1 != "undefined") ? var2 : ""; + if((this.negate && var1 != var2) || (!this.negate && var1 == var2)){ + if(this.falses){ + buffer = this.falses.unrender(context, buffer, this); + } + return (this.trues) ? this.trues.render(context, buffer, this) : buffer; + } + if(this.trues){ + buffer = this.trues.unrender(context, buffer, this); + } + return (this.falses) ? this.falses.render(context, buffer, this) : buffer; + }, + unrender: function(context, buffer){ + return ddtl.IfNode.prototype.unrender.call(this, context, buffer); + }, + clone: function(buffer){ + var trues = this.trues ? this.trues.clone(buffer) : null; + var falses = this.falses ? this.falses.clone(buffer) : null; + return new this.constructor(this.var1.getExpression(), this.var2.getExpression(), trues, falses, this.negate); + } + }); + + ddtl.ForNode = lang.extend(function(assign, loop, reversed, nodelist){ + this.assign = assign; + this.loop = new dd._Filter(loop); + this.reversed = reversed; + this.nodelist = nodelist; + this.pool = []; + }, + { + render: function(context, buffer){ + var i, j, k; + var dirty = false; + var assign = this.assign; + + for(k = 0; k < assign.length; k++){ + if(typeof context[assign[k]] != "undefined"){ + dirty = true; + context = context.push(); + break; + } + } + if(!dirty && context.forloop){ + dirty = true; + context = context.push(); + } + + var items = this.loop.resolve(context) || []; + for(i = items.length; i < this.pool.length; i++){ + this.pool[i].unrender(context, buffer, this); + } + if(this.reversed){ + items = items.slice(0).reverse(); + } + + var isObject = lang.isObject(items) && !lang.isArrayLike(items); + var arred = []; + if(isObject){ + for(var key in items){ + arred.push(items[key]); + } + }else{ + arred = items; + } + + var forloop = context.forloop = { + parentloop: context.get("forloop", {}) + }; + var j = 0; + for(i = 0; i < arred.length; i++){ + var item = arred[i]; + + forloop.counter0 = j; + forloop.counter = j + 1; + forloop.revcounter0 = arred.length - j - 1; + forloop.revcounter = arred.length - j; + forloop.first = !j; + forloop.last = (j == arred.length - 1); + + if(assign.length > 1 && lang.isArrayLike(item)){ + if(!dirty){ + dirty = true; + context = context.push(); + } + var zipped = {}; + for(k = 0; k < item.length && k < assign.length; k++){ + zipped[assign[k]] = item[k]; + } + lang.mixin(context, zipped); + }else{ + context[assign[0]] = item; + } + + if(j + 1 > this.pool.length){ + this.pool.push(this.nodelist.clone(buffer)); + } + buffer = this.pool[j++].render(context, buffer, this); + } + + delete context.forloop; + if(dirty){ + context = context.pop(); + }else{ + for(k = 0; k < assign.length; k++){ + delete context[assign[k]]; + } + } + return buffer; + }, + unrender: function(context, buffer){ + for(var i = 0, pool; pool = this.pool[i]; i++){ + buffer = pool.unrender(context, buffer); + } + return buffer; + }, + clone: function(buffer){ + return new this.constructor(this.assign, this.loop.getExpression(), this.reversed, this.nodelist.clone(buffer)); + } + }); + + lang.mixin(ddtl, { + if_: function(parser, token){ + var i, part, type, bools = [], parts = token.contents.split(); + parts.shift(); + token = parts.join(" "); + parts = token.split(" and "); + if(parts.length == 1){ + type = "or"; + parts = token.split(" or "); + }else{ + type = "and"; + for(i = 0; i < parts.length; i++){ + if(parts[i].indexOf(" or ") != -1){ + // Note, since we split by and, this is the only place we need to error check + throw new Error("'if' tags can't mix 'and' and 'or'"); + } + } + } + for(i = 0; part = parts[i]; i++){ + var not = false; + if(part.indexOf("not ") == 0){ + part = part.slice(4); + not = true; + } + bools.push([not, new dd._Filter(part)]); + } + var trues = parser.parse(["else", "endif"]); + var falses = false; + var token = parser.next_token(); + if(token.contents == "else"){ + falses = parser.parse(["endif"]); + parser.next_token(); + } + return new ddtl.IfNode(bools, trues, falses, type); + }, + _ifequal: function(parser, token, negate){ + var parts = token.split_contents(); + if(parts.length != 3){ + throw new Error(parts[0] + " takes two arguments"); + } + var end = 'end' + parts[0]; + var trues = parser.parse(["else", end]); + var falses = false; + var token = parser.next_token(); + if(token.contents == "else"){ + falses = parser.parse([end]); + parser.next_token(); + } + return new ddtl.IfEqualNode(parts[1], parts[2], trues, falses, negate); + }, + ifequal: function(parser, token){ + return ddtl._ifequal(parser, token); + }, + ifnotequal: function(parser, token){ + return ddtl._ifequal(parser, token, true); + }, + for_: function(parser, token){ + var parts = token.contents.split(); + if(parts.length < 4){ + throw new Error("'for' statements should have at least four words: " + token.contents); + } + var reversed = parts[parts.length - 1] == "reversed"; + var index = (reversed) ? -3 : -2; + if(parts[parts.length + index] != "in"){ + throw new Error("'for' tag received an invalid argument: " + token.contents); + } + var loopvars = parts.slice(1, index).join(" ").split(/ *, */); + for(var i = 0; i < loopvars.length; i++){ + if(!loopvars[i] || loopvars[i].indexOf(" ") != -1){ + throw new Error("'for' tag received an invalid argument: " + token.contents); + } + } + var nodelist = parser.parse(["endfor"]); + parser.next_token(); + return new ddtl.ForNode(loopvars, parts[parts.length + index + 1], reversed, nodelist); + } + }); + return dojox.dtl.tag.logic; +}); +}, +'dojox/dtl/tag/date':function(){ +define("dojox/dtl/tag/date", [ + "dojo/_base/lang", + "../_base", + "../utils/date" +], function(lang,dd,ddud){ + /*===== + dd = dojox.dtl; + =====*/ + lang.getObject("dojox.dtl.tag.date", true); + + dojox.dtl.tag.date.NowNode = function(format, node){ + this._format = format; + this.format = new ddud.DateFormat(format); + this.contents = node; + } + lang.extend(dd.tag.date.NowNode, { + render: function(context, buffer){ + this.contents.set(this.format.format(new Date())); + return this.contents.render(context, buffer); + }, + unrender: function(context, buffer){ + return this.contents.unrender(context, buffer); + }, + clone: function(buffer){ + return new this.constructor(this._format, this.contents.clone(buffer)); + } + }); + + dojox.dtl.tag.date.now = function(parser, token){ + // Split by either :" or :' + var parts = token.split_contents(); + if(parts.length != 2){ + throw new Error("'now' statement takes one argument"); + } + return new dojox.dtl.tag.date.NowNode(parts[1].slice(1, -1), parser.create_text_node()); + }; + return dojox.dtl.tag.date; +}); + +}}}); + +require(["dojo/i18n"], function(i18n){ +i18n._preloadLocalizations("dojox/nls/dtl", []); +}); +define("dojox/dtl", ["./dtl/_base"], function(dxdtl){ + return dxdtl; +});
\ No newline at end of file |
