aboutsummaryrefslogtreecommitdiffstats
path: root/trunk/infrastructure/framework-src/modules/ejs.js
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/infrastructure/framework-src/modules/ejs.js')
-rw-r--r--trunk/infrastructure/framework-src/modules/ejs.js471
1 files changed, 471 insertions, 0 deletions
diff --git a/trunk/infrastructure/framework-src/modules/ejs.js b/trunk/infrastructure/framework-src/modules/ejs.js
new file mode 100644
index 0000000..bf14ed3
--- /dev/null
+++ b/trunk/infrastructure/framework-src/modules/ejs.js
@@ -0,0 +1,471 @@
+/*--------------------------------------------------------------------------
+ * EJS - Embedded JavaScript, version 0.1.0
+ * Copyright (c) 2007 Edward Benson
+ * http://www.edwardbenson.com/projects/ejs
+ * ------------------------------------------------------------------------
+ *
+ * EJS is freely distributable under the terms of an MIT-style license.
+ *
+ * EJS is a client-side preprocessing engine written in and for JavaScript.
+ * If you have used PHP, ASP, JSP, or ERB then you get the idea: code embedded
+ * in <% // Code here %> tags will be executed, and code embedded in <%= .. %>
+ * tags will be evaluated and appended to the output.
+ *
+ * This is essentially a direct JavaScript port of Masatoshi Seki's erb.rb
+ * from the Ruby Core, though it contains a subset of ERB's functionality.
+ *
+ * Requirements:
+ * prototype.js
+ *
+ * Usage:
+ * // source should be either a string or a DOM node whose innerHTML
+ * // contains EJB source.
+ * var source = "<% var ejb="EJB"; %><h1>Hello, <%= ejb %>!</h1>";
+ * var compiler = new EjsCompiler(source);
+ * compiler.compile();
+ * var output = eval(compiler.out);
+ * alert(output); // -> "<h1>Hello, EJB!</h1>"
+ *
+ * For a demo: see demo.html
+ * For the license: see license.txt
+ *
+ *--------------------------------------------------------------------------*/
+
+import("jsutils.*");
+import("funhtml");
+
+jimport("java.lang.System.out.println");
+jimport("net.appjet.ajstdlib.execution.executeCodeInNewScope");
+
+/* Make a split function like Ruby's: "abc".split(/b/) -> ['a', 'b', 'c'] */
+function rsplit(x, regex) {
+ var item = x;
+ var result = regex.exec(item);
+ var retArr = new Array();
+ while (result != null)
+ {
+ var first_idx = result.index;
+ var last_idx = regex.lastIndex;
+ if ((first_idx) != 0)
+ {
+ var first_bit = item.substring(0,first_idx);
+ retArr.push(item.substring(0,first_idx));
+ item = item.slice(first_idx);
+ }
+ retArr.push(result[0]);
+ item = item.slice(result[0].length);
+ result = regex.exec(item);
+ }
+ if (! item == '')
+ {
+ retArr.push(item);
+ }
+ return retArr;
+};
+
+/* Chop is nice to have too */
+function chop(x) {
+ return x.substr(0, x.length - 1);
+}
+
+/* Adaptation from the Scanner of erb.rb */
+var EjsScanner = function(source, left, right) {
+ this.left_delimiter = left +'%'; //<%
+ this.right_delimiter = '%'+right; //>
+ this.double_left = left+'%%';
+ this.double_right = '%%'+right;
+ this.left_equal = left+'%=';
+ this.left_comment = left+'%#';
+ if(left=='[') {
+ this.SplitRegexp = /(\[%%)|(%%\])|(\[%=)|(\[%#)|(\[%)|(%\]\n)|(%\])|(\n)/;
+ }
+ else {
+ this.SplitRegexp = new RegExp('('+this.double_left+')|(%%'+this.double_right+')|('+this.left_equal+')|('+this.left_comment+')|('+this.left_delimiter+')|('+this.right_delimiter+'\n)|('+this.right_delimiter+')|(\n)')
+ }
+
+ this.source = source;
+ this.stag = null;
+ this.lines = 0;
+};
+EjsView = function(data) {
+ this.data = data;
+};
+EjsView.prototype.partial = function(options, data){
+ if(!data) data = this.data;
+ return new EJS(options).render(data);
+};
+
+EjsScanner.to_text = function(input){
+ if(input == null || input === undefined)
+ return '';
+ if(input instanceof Date)
+ return input.toDateString();
+ if(input.toString)
+ return input.toString();
+ return '';
+}
+
+EjsScanner.prototype = {
+
+ /* For each line, scan! */
+ scan: function(block) {
+ scanline = this.scanline;
+ regex = this.SplitRegexp;
+ if (! this.source == '')
+ {
+ var source_split = rsplit(this.source, /\n/);
+ for(var i=0; i<source_split.length; i++) {
+ var item = source_split[i];
+ this.scanline(item, regex, block);
+ }
+ }
+ },
+
+ /* For each token, block! */
+ scanline: function(line, regex, block) {
+ this.lines++;
+ var line_split = rsplit(line, regex);
+ for(var i=0; i<line_split.length; i++) {
+ var token = line_split[i];
+ if (token != null) {
+ try{
+ block(token, this);
+ }catch(e){
+ throw {type: 'EjsScanner', line: this.lines};
+ }
+ }
+ }
+ }
+};
+
+/* Adaptation from the Buffer of erb.rb */
+var EjsBuffer = function(pre_cmd, post_cmd) {
+ this.line = new Array();
+ this.script = "";
+ this.pre_cmd = pre_cmd;
+ this.post_cmd = post_cmd;
+
+ for (var i=0; i<this.pre_cmd.length; i++)
+ {
+ this.push(pre_cmd[i]);
+ }
+}
+EjsBuffer.prototype = {
+
+ push: function(cmd) {
+ this.line.push(cmd);
+ },
+
+ cr: function() {
+ this.script = this.script + this.line.join('; ');
+ this.line = new Array();
+ this.script = this.script + "\n";
+ },
+
+ close: function() {
+ if (this.line.length > 0)
+ {
+ for (var i=0; i<this.post_cmd.length; i++)
+ {
+ this.push(pre_cmd[i]);
+ }
+ this.script = this.script + this.line.join('; ');
+ line = null;
+ }
+ }
+
+};
+
+/* Adaptation from the Compiler of erb.rb */
+EjsCompiler = function(source, left) {
+ this.pre_cmd = ['var ___ejsO = "";'];
+ this.post_cmd = new Array();
+ this.source = ' ';
+ if (source != null)
+ {
+ if (typeof source == 'string')
+ {
+ source = source.replace(/\r\n/g, "\n");
+ source = source.replace(/\r/g, "\n");
+ this.source = source;
+ }
+ else if (source.innerHTML)
+ {
+ this.source = source.innerHTML;
+ }
+ if (typeof this.source != 'string')
+ {
+ this.source = "";
+ }
+ }
+ left = left || '<'
+ var right = '>'
+ switch(left) {
+ case '[':
+ right = ']'
+ break;
+ case '<':
+ break;
+ default:
+ throw left+' is not a supported deliminator'
+ break;
+ }
+ this.scanner = new EjsScanner(this.source, left, right);
+ this.out = '';
+}
+EjsCompiler.prototype = {
+ compile: function(options) {
+ options = options || {};
+ this.out = '';
+ var put_cmd = "___ejsO += ";
+ var insert_cmd = put_cmd;
+ var buff = new EjsBuffer(this.pre_cmd, this.post_cmd);
+ var content = '';
+ var clean = function(content)
+ {
+ content = content.replace(/\\/g, '\\\\');
+ content = content.replace(/\n/g, '\\n');
+ content = content.replace(/\"/g, '\\"');
+ return content;
+ };
+ this.scanner.scan(function(token, scanner) {
+ if (scanner.stag == null)
+ {
+ //alert(token+'|'+(token == "\n"))
+ switch(token) {
+ case '\n':
+ content = content + "\n";
+ buff.push(put_cmd + '"' + clean(content) + '";');
+ buff.cr();
+ content = '';
+ break;
+ case scanner.left_delimiter:
+ case scanner.left_equal:
+ case scanner.left_comment:
+ scanner.stag = token;
+ if (content.length > 0)
+ {
+ // Chould be content.dump in Ruby
+
+ buff.push(put_cmd + '"' + clean(content) + '"');
+ }
+ content = '';
+ break;
+ case scanner.double_left:
+ content = content + scanner.left_delimiter;
+ break;
+ default:
+ content = content + token;
+ break;
+ }
+ }
+ else {
+ switch(token) {
+ case scanner.right_delimiter:
+ switch(scanner.stag) {
+ case scanner.left_delimiter:
+ if (content[content.length - 1] == '\n')
+ {
+ content = chop(content);
+ buff.push(content);
+ buff.cr();
+ }
+ else {
+ buff.push(content);
+ }
+ break;
+ case scanner.left_equal:
+ buff.push(insert_cmd + "(EjsScanner.to_text(" + content + "))");
+ break;
+ }
+ scanner.stag = null;
+ content = '';
+ break;
+ case scanner.double_right:
+ content = content + scanner.right_delimiter;
+ break;
+ default:
+ content = content + token;
+ break;
+ }
+ }
+ });
+ if (content.length > 0)
+ {
+ // Chould be content.dump in Ruby
+ buff.push(put_cmd + '"' + clean(content) + '"');
+ }
+ buff.close();
+ this.out = buff.script + ";";
+ var to_be_evaled = [
+ 'var process = function(_CONTEXT,_VIEW) {',
+ ' with(_VIEW) {',
+ ' with (_CONTEXT) {',
+ this.out,
+ ' return ___ejsO;',
+ ' }',
+ ' }',
+ '};'
+ ].join('');
+ // make funhtml.* available in parent scope.
+ var parentScope = {};
+ parentScope.EjsScanner = EjsScanner;
+ keys(funhtml).forEach(function(k) {
+ parentScope[k] = funhtml[k];
+ });
+ var ret = executeCodeInNewScope(
+ parentScope,
+ to_be_evaled,
+ (options.name || "template"),
+ 1
+ );
+ this.process = ret.process;
+ }
+}
+
+
+//type, cache, folder
+EJS = function( options ){
+ this.set_options(options);
+
+ if(options.url){
+ var template = EJS.get(options.url, this.cache);
+ if (template) return template;
+ if (template == EJS.INVALID_PATH) return null;
+ this.text = EJS.request(options.url);
+ if(this.text == null){
+ //EJS.update(options.url, this.INVALID_PATH);
+ throw 'There is no template at '+options.url;
+ }
+ this.name = options.url;
+ }else if(options.element)
+ {
+ if(typeof options.element == 'string'){
+ var name = options.element;
+ options.element = document.getElementById( options.element );
+ if(options.element == null) throw name+'does not exist!';
+ }
+ if(options.element.value){
+ this.text = options.element.value;
+ }else{
+ this.text = options.element.innerHTML;
+ }
+ this.name = options.element.id;
+ this.type = '[';
+ }
+ var template = new EjsCompiler(this.text, this.type);
+
+ template.compile(options);
+
+
+ EJS.update(this.name, this);
+ this.template = template;
+};
+EJS.config = function(options){
+ EJS.cache = options.cache != null ? options.cache : EJS.cache;
+ EJS.type = options.type != null ? options.type : EJS.type;
+ var templates_directory = {}; //nice and private container
+
+ EJS.get = function(path, cache){
+ if(cache == false) return null;
+ if(templates_directory[path]) return templates_directory[path];
+ return null;
+ };
+
+ EJS.update = function(path, template) {
+ if(path == null) return;
+ templates_directory[path] = template;
+ };
+
+ EJS.INVALID_PATH = -1;
+
+
+};
+EJS.config( {cache: true, type: '<' } );
+
+EJS.prototype = {
+ render : function(object){
+ var v = new EjsView(object);
+ return this.template.process.call(v, object, v);
+ },
+ out : function(){
+ return this.template.out;
+ },
+ set_options : function(options){
+ this.type = options.type != null ? options.type : EJS.type;
+ this.cache = options.cache != null ? options.cache : EJS.cache;
+ this.text = options.text != null ? options.text : null;
+ this.name = options.name != null ? options.name : null;
+ },
+ // called without options, returns a function that takes the object
+ // called with options being a string, uses that as a url
+ // called with options as an object
+ update : function(element, options){
+ if(typeof element == 'string'){
+ element = document.getElementById(element);
+ }
+ if(options == null){
+ _template = this;
+ return function(object){
+ EJS.prototype.update.call(_template, element, object);
+ };
+ }
+ if(typeof options == 'string'){
+ params = {};
+ params.url = options;
+ _template = this;
+ params.onComplete = function(request){
+ var object = eval( request.responseText );
+ EJS.prototype.update.call(_template, element, object);
+ };
+ EJS.ajax_request(params);
+ }else
+ {
+ element.innerHTML = this.render(options);
+ }
+ }
+};
+
+ EJS.newRequest = function(){
+ var factories = [function() { return new ActiveXObject("Msxml2.XMLHTTP"); },function() { return new XMLHttpRequest(); },function() { return new ActiveXObject("Microsoft.XMLHTTP"); }];
+ for(var i = 0; i < factories.length; i++) {
+ try {
+ var request = factories[i]();
+ if (request != null) return request;
+ }
+ catch(e) { continue;}
+ }
+ };
+
+ EJS.request = function(path){
+ var request = new EJS.newRequest();
+ request.open("GET", path, false);
+
+ try{request.send(null);}
+ catch(e){return null;}
+
+ if ( request.status == 404 || request.status == 2 ||(request.status == 0 && request.responseText == '') ) return null;
+
+ return request.responseText
+ };
+ EJS.ajax_request = function(params){
+ params.method = ( params.method ? params.method : 'GET');
+
+ var request = new EJS.newRequest();
+ request.onreadystatechange = function(){
+ if(request.readyState == 4){
+ if(request.status == 200){
+ params.onComplete(request);
+ }else
+ {
+ params.onComplete(request);
+ }
+ }
+ };
+ request.open(params.method, params.url);
+ request.send(null);
+ };
+
+//}
+
+