Blame | Last modification | View Log | RSS feed
if(!dojo._hasResource["dojox.dtl._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.dojo._hasResource["dojox.dtl._base"] = true;dojo.provide("dojox.dtl._base");dojo.require("dojox.string.Builder");dojo.require("dojox.string.tokenize");dojox.dtl.Context = function(dict){dojo.mixin(this, dict || {});this._dicts = [];this._this = {};}dojo.extend(dojox.dtl.Context, {_dicts: [],_this: {},extend: function(/*dojox.dtl.Context|Object*/ obj){// summary: Returns a clone of this context object, with the items from the// passed objecct mixed in.var context = new dojox.dtl.Context();var keys = this.getKeys();for(var i = 0, key; key = keys[i]; i++){if(typeof obj[key] != "undefined"){context[key] = obj[key];}else{context[key] = this[key];}}if(obj instanceof dojox.dtl.Context){keys = obj.getKeys();}else if(typeof obj == "object"){keys = [];for(var key in obj){keys.push(key);}}for(var i = 0, key; key = keys[i]; i++){context[key] = obj[key];}return context;},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 dojox.dtl.Context();var keys = [];if(filter instanceof dojox.dtl.Context){keys = filter.getKeys();}else if(typeof filter == "object"){for(var key in filter){keys.push(key);}}else{for(var i = 0, arg; arg = arguments[i]; i++){if(typeof arg == "string"){keys.push(arg);}}}for(var i = 0, key; key = keys[i]; i++){context[key] = this[key];}return context;},setThis: function(/*Object*/ _this){this._this = _this;},getThis: function(){return this._this;},push: function(){var dict = {};var keys = this.getKeys();for(var i = 0, key; key = keys[i]; i++){dict[key] = this[key];delete this[key];}this._dicts.unshift(dict);},pop: function(){if(!this._dicts.length){throw new Error("pop() has been called more times than push() on the Context");}var dict = this._dicts.shift();dojo.mixin(this, dict);},hasKey: function(key){if(typeof this[key] != "undefined"){return true;}for(var i = 0, dict; dict = this._dicts[i]; i++){if(typeof dict[key] != "undefined"){return true;}}return false;},getKeys: function(){var keys = [];for(var key in this){if(isNaN(key)){var found = false;for(var protoKey in dojox.dtl.Context.prototype){if(key == protoKey){found = true;break;}}if(!found){keys.push(key);}}}return keys;},get: function(key, otherwise){if(typeof this[key] != "undefined"){return this[key];}for(var i = 0, dict; dict = this._dicts[i]; i++){if(typeof dict[key] != "undefined"){return dict[key];}}return otherwise;},update: function(dict){this.push();if(dict){dojo.mixin(this, dict);}},toString: function(){ return "dojox.dtl.Context"; }});dojox.dtl.text = {types: {tag: -1, varr: -2, text: 3},pySplit: function(str){// summary: Split a string according to Python's split functionstr = str.replace(/^\s+|\s+$/, "");if(!str.length){return [];}return str.split(/\s+/g);},urlquote: function(/*String*/ url, /*String?*/ safe){if(!safe){safe = "/";}return dojox.string.tokenize(url, /([^\w-_.])/g, function(token){if(safe.indexOf(token) == -1){if(token == " "){return "+";}else{return "%" + token.charCodeAt(0).toString(16).toUpperCase();}}return token;}).join("");},_get: function(module, name, errorless){// summary: Used to find both tags and filtersvar params = dojox.dtl.register.get(module, name, errorless);if(!params) return;var require = params.getRequire();var obj = params.getObj();var fn = params.getFn();if(fn.indexOf(":") != -1){var parts = fn.split(":");fn = parts.pop();}dojo.requireIf(true, require);var parent = window;var parts = obj.split(".");for(var i = 0, part; part = parts[i]; i++){if(!parent[part]) return;parent = parent[part];}return parent[fn || name] || parent[name + "_"];},getTag: function(name, errorless){return dojox.dtl.text._get("tag", name, errorless);},getFilter: function(name, errorless){return dojox.dtl.text._get("filter", name, errorless);},getTemplate: function(file){return new dojox.dtl.Template(dojox.dtl.getTemplateString(file));},getTemplateString: function(file){return dojo._getText(file.toString()) || "";},_re: /(?:\{\{\s*(.+?)\s*\}\}|\{%\s*(.+?)\s*%\})/g,tokenize: function(str){return dojox.string.tokenize(str, dojox.dtl.text._re, dojox.dtl.text._parseDelims);},_parseDelims: function(varr, tag){var types = dojox.dtl.text.types;if(varr){return [types.varr, varr];}else{return [types.tag, tag];}}}dojox.dtl.Template = function(str){var st = dojox.dtl;var tokens = st.text.tokenize(str);var parser = new st.Parser(tokens);this.nodelist = parser.parse();}dojo.extend(dojox.dtl.Template, {render: function(context, /*concatenatable?*/ buffer){context = context || new dojox.dtl.Context({});if(!buffer){dojo.require("dojox.string.Builder");buffer = new dojox.string.Builder();}return this.nodelist.render(context, buffer) + "";},toString: function(){ return "dojox.dtl.Template"; }});dojox.dtl.Filter = function(token){// summary: Uses a string to find (and manipulate) a variableif(!token) throw new Error("Filter must be called with variable name");this.contents = token;var key = null;var re = this._re;var matches, filter, arg, fn;var filters = [];while(matches = re.exec(token)){if(key === null){if(this._exists(matches, 3)){// variablekey = matches[3];}else if(this._exists(matches, 1)){// _("text")key = '"' + matches[1] + '"';}else if(this._exists(matches, 2)){// "text"key = '"' + matches[2] + '"';}else if(this._exists(matches, 9)){// 'text'key = '"' + matches[9] + '"';}}else{if(this._exists(matches, 7)){// :variablearg = [true, matches[7]];}else if(this._exists(matches, 5)){// :_("text")arg = [false, dojox.dtl.replace(matches[5], '\\"', '"')];}else if(this._exists(matches, 6)){// :"text"arg = [false, dojox.dtl.replace(matches[6], '\\"', '"')];}else if(this._exists(matches, 8)){// :"text"arg = [false, dojox.dtl.replace(matches[8], "\\'", "'")];}// Get a named filterfn = dojox.dtl.text.getFilter(matches[4]);if(typeof fn != "function") throw new Error(matches[4] + " is not registered as a filter");filters.push([fn, arg]);}}this.key = key;this.filters = filters;}dojo.extend(dojox.dtl.Filter, {_re: /(?:^_\("([^\\"]*(?:\\.[^\\"])*)"\)|^"([^\\"]*(?:\\.[^\\"]*)*)"|^([a-zA-Z0-9_.]+)|\|(\w+)(?::(?:_\("([^\\"]*(?:\\.[^\\"])*)"\)|"([^\\"]*(?:\\.[^\\"]*)*)"|([a-zA-Z0-9_.]+)|'([^\\']*(?:\\.[^\\']*)*)'))?|^'([^\\']*(?:\\.[^\\']*)*)')/g,_exists: function(arr, index){if(typeof arr[index] != "undefined" && arr[index] !== ""){return true;}return false;},resolve: function(context){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.charAt(path.length - 1);if(!isNaN(parseInt(first))){current = (path.indexOf(".") == -1) ? parseInt(path) : parseFloat(path);}else if(first == '"' && first == last){current = path.substring(1, path.length - 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.shift());while(parts.length){if(current && typeof current[parts[0]] != "undefined"){current = current[parts[0]];if(typeof current == "function"){if(current.alters_data){current = "";}else{current = current();}}}else{return "";}parts.shift();}}return current;},toString: function(){ return "dojox.dtl.Filter"; }});dojox.dtl.Node = function(/*Object*/ obj){// summary: Basic catch-all nodethis.contents = obj;}dojo.extend(dojox.dtl.Node, {render: function(context, buffer){// summary: Adds content onto the bufferreturn buffer.concat(this.contents);},toString: function(){ return "dojox.dtl.Node"; }});dojox.dtl.NodeList = function(/*Node[]*/ nodes){// summary: Allows us to render a group of nodesthis.contents = nodes || [];}dojo.extend(dojox.dtl.NodeList, {push: function(node){// summary: Add a new node to the listthis.contents.push(node);},render: function(context, buffer){// summary: Adds all content onto the bufferfor(var i = 0; i < this.contents.length; i++){buffer = this.contents[i].render(context, buffer);if(!buffer) throw new Error("Template node render functions must return their buffer");}return buffer;},unrender: function(context, buffer){ return buffer; },clone: function(){ return this; },toString: function(){ return "dojox.dtl.NodeList"; }});dojox.dtl.TextNode = dojox.dtl.Node;dojox.dtl.VarNode = function(str){// summary: A node to be processed as a variablethis.contents = new dojox.dtl.Filter(str);}dojo.extend(dojox.dtl.VarNode, {render: function(context, buffer){var str = this.contents.resolve(context);return buffer.concat(str);},toString: function(){ return "dojox.dtl.VarNode"; }});dojox.dtl.Parser = function(tokens){// summary: Parser used during initialization and for tag groups.this.contents = tokens;}dojo.extend(dojox.dtl.Parser, {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 st = dojox.dtl;var types = st.text.types;var terminators = {};var tokens = this.contents;stop_at = stop_at || [];for(var i = 0; i < stop_at.length; i++){terminators[stop_at[i]] = true;}var nodelist = new st.NodeList();while(tokens.length){token = tokens.shift();if(typeof token == "string"){nodelist.push(new st.TextNode(token));}else{var type = token[0];var text = token[1];if(type == types.varr){nodelist.push(new st.VarNode(text));}else if(type == types.tag){if(terminators[text]){tokens.unshift(token);return nodelist;}var cmd = text.split(/\s+/g);if(cmd.length){cmd = cmd[0];var fn = dojox.dtl.text.getTag(cmd);if(fn){nodelist.push(fn(this, text));}}}}}if(stop_at.length){throw new Error("Could not find closing tag(s): " + stop_at.toString());}return nodelist;},next: function(){// summary: Returns the next token in the list.var token = this.contents.shift();return {type: token[0], text: token[1]};},skipPast: function(endtag){var types = dojox.dtl.text.types;while(this.contents.length){var token = this.contents.shift();if(token[0] == types.tag && token[1] == endtag){return;}}throw new Error("Unclosed tag found when looking for " + endtag);},getVarNode: function(){return dojox.dtl.VarNode;},getTextNode: function(){return dojox.dtl.TextNode;},getTemplate: function(file){return new dojox.dtl.Template(file);},toString: function(){ return "dojox.dtl.Parser"; }});dojox.dtl.register = function(module, cols, args, /*Function*/ normalize){// summary: Used to create dojox.dtl.register[module] function, and as a namespace// expand: Used if the call structure is reformatted for a more compact view.// Should return an array of normalized arguments.// description: The function produced will accept a "name"// as the first parameter and all other parameters will// be associated with the parameter names listed in cols.var ddr = dojox.dtl.register;var registry = ddr._mod[module] = {params: [],Getter: function(params){ddr._params = params || {};}};cols.unshift("name");for(var i = 0, col; col = cols[i]; i++){registry.Getter.prototype["get" + col.substring(0, 1).toUpperCase() + col.substring(1, col.length)] = ddr._ret(i);}ddr[module] = function(/*String*/ name, /*mixed...*/ parameters){if(normalize){var normalized = normalize(arguments);}else{var normalized = [arguments];}for(var i = 0, args; args = normalized[i]; i++){var params = [];for(var j = 0; j < cols.length; j++){params.push(args[j] || null);}if(typeof args[0] == "string"){// Strings before regexes for speedregistry.params.unshift(params);}else{// break// module RegExpregistry.params.push(params);}}}ddr[module].apply(null, args);}dojo.mixin(dojox.dtl.register, {_mod: {},_ret: function(i){// summary: Just lets use i and _params within a closurereturn function(){return dojox.dtl.register._params[i] || "";}},get: function(/*String*/ module, /*String*/ name, /*Boolean*/ errorless){// summary: Returns a "Getter", based on the registry// description: The getter functions correspond with the registered cols// used in dojo.registervar registry = this._mod[module] || {};if(registry.params){for(var i = 0, param; param = registry.params[i]; i++){var search = param[0];if(typeof search == "string"){if(search == name){return new registry.Getter(param);}}else if(name.match(search)){var matches = search.exec(name);var mixin = [];dojo.mixin(mixin, param);mixin[0] = matches[1];return new registry.Getter(param);}}}if(!errorless) throw new Error("'" + module + "' of name '" + name + "' does not exist");},_normalize: function(args){// summary:// Translates to the signature (/*String*/ name, /*String*/ require, /*String*/ obj, /*String*/ fn)var items = args[2];var output = [];for(var i = 0, item; item = items[i]; i++){if(typeof item == "string"){output.push([item, args[0], args[1], item]);}else{output.push([item[0], args[0], args[1], item[1]]);}}return output;},tag: function(/*String*/ require, /*String*/ obj, /*String[]|[RegExp, String][]*/ fns){// summary:// Specify the location of a given tag function.// require:// The file this function is in// obj:// The base object to use for lookups// fn:// List of functions within obj to use// description:// When we are looking up a tag as specified in a template, we either use a// string in the fns array, or the RegExp item of the [RegExp, String] pair.// When that string is found, it requires the file specified in the require// parameter, uses the base object as a starting point and checks for obj.fn// or obj.fn_ in case fn is a reserved word.this("tag", ["require", "obj", "fn"], arguments, this._normalize);},filter: function(/*String*/ require, /*String*/ obj, /*String[]|[RegExp, String][]*/ fns){// summary:// Specify the location of a given filter function.// require:// The file this function is in// obj:// The base object to use for lookups// fn:// List of functions within obj to use// description:// When we are looking up a tag as specified in a template, we either use a// string in the fns array, or the RegExp item of the [RegExp, String] pair.// When that string is found, it requires the file specified in the require// parameter, uses the base object as a starting point and checks for obj.fn// or obj.fn_ in case fn is a reserved word.this("filter", ["require", "obj", "fn"], arguments, this._normalize);}});(function(){var register = dojox.dtl.register;var dtt = "dojox.dtl.tag";register.tag(dtt + ".logic", dtt + ".logic", ["if", "for"]);register.tag(dtt + ".loader", dtt + ".loader", ["extends", "block"]);register.tag(dtt + ".misc", dtt + ".misc", ["comment", "debug", "filter"]);register.tag(dtt + ".loop", dtt + ".loop", ["cycle"]);var dtf = "dojox.dtl.filter";register.filter(dtf + ".dates", dtf + ".dates", ["date", "time", "timesince", "timeuntil"]);register.filter(dtf + ".htmlstrings", dtf + ".htmlstrings", ["escape", "linebreaks", "linebreaksbr", "removetags", "striptags"]);register.filter(dtf + ".integers", dtf + ".integers", ["add", "get_digit"]);register.filter(dtf + ".lists", dtf + ".lists", ["dictsort", "dictsortreversed", "first", "join", "length", "length_is", "random", "slice", "unordered_list"]);register.filter(dtf + ".logic", dtf + ".logic", ["default", "default_if_none", "divisibleby", "yesno"]);register.filter(dtf + ".misc", dtf + ".misc", ["filesizeformat", "pluralize", "phone2numeric", "pprint"]);register.filter(dtf + ".strings", dtf + ".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"]);})();dojox.dtl.replace = function(str, token, repl){repl = repl || "";var pos, len = token.length;while(1){pos = str.indexOf(token);if(pos == -1) break;str = str.substring(0, pos) + repl + str.substring(pos + len);}return str;}dojox.dtl.resolveVariable = function(token, context){// summary: Quickly resolve a variablesvar filter = new dojox.dtl.Filter(token);return filter.resolve(context);}}