(function($, undefined) { /* TrafficCop Author: Jim Cowart License: Dual licensed MIT (http://www.opensource.org/licenses/mit-license) & GPL (http://www.opensource.org/licenses/gpl-license) Version 0.3.0 */ var inProgress = {}; $.trafficCop = function(url, options) { var reqOptions = url, key; if(arguments.length === 2) { reqOptions = $.extend(true, options, { url: url }); } key = JSON.stringify(reqOptions); if (key in inProgress) { for (var i in {success: 1, error: 1, complete: 1}) { inProgress[key][i](reqOptions[i]); } } else { inProgress[key] = $.ajax(reqOptions).always(function () { delete inProgress[key]; }); } return inProgress[key]; }; })(jQuery); (function($, global, undefined) { /* infuser.js Author: Jim Cowart License: Dual licensed MIT (http://www.opensource.org/licenses/mit-license) & GPL (http://www.opensource.org/licenses/gpl-license) Version 0.2.0 */ var hashStorage = { templates: {}, storeTemplate: function(templateId, templateContent) { this.templates[templateId] = templateContent; }, getTemplate: function(templateId) { return this.templates[templateId]; }, purge: function() { this.templates = {}; } }; var scriptStorage = { templateIds: [], storeTemplate: function(templateId, templateContent) { var node = document.getElementById(templateId); if(node === null) { this.templateIds.push(templateId); node = document.createElement("script"); node.type = "text/html"; node.id = templateId; document.body.appendChild(node); } node.text = templateContent; }, getTemplate: function(templateId) { return document.getElementById(templateId); }, purge: function() { for(var i = 0; i < this.templateIds.length; i++) { document.body.removeChild(document.getElementById(this.templateIds[i])); } this.templateIds = []; } }; var errorHtml = "
The template {TEMPLATEID} could not be loaded. {STATUS}
", returnErrorTemplate = function(status, templateId, templatePath) { return errorHtml.replace('{STATUS}', status).replace('{TEMPLATEID}', templateId).replace('{TEMPLATEURL}', templatePath); }, errors = []; var helpers = { getTemplatePath: function(templateOptions) { var templateFile = templateOptions.templatePrefix + templateOptions.templateId + templateOptions.templateSuffix; return templateOptions.templateUrl === undefined || templateOptions.templateUrl === "" ? templateFile : templateOptions.templateUrl + "/" + templateFile; }, templateGetSuccess: function(templateId, callback) { return function(response) { infuser.store.storeTemplate(templateId, response); callback(infuser.store.getTemplate(templateId)); }; }, templateGetError: function(templateId, templatePath, callback) { return function(exception) { if($.inArray(templateId, errors) === -1) { errors.push(templateId); } var templateHtml = returnErrorTemplate("HTTP Status code: " + exception.status, templateId, templatePath); infuser.store.storeTemplate(templateId, templateHtml); callback(infuser.store.getTemplate(templateId)); }; }, getAjaxOptions: function(templateOptions) { } }, infuserOptions = ['target','loadingTemplate','postRender','preRender','render','bindingInstruction','useLoadingTemplate','model','templateUrl','templateSuffix','templatePrefix','']; var infuser = { storageOptions: { hash: hashStorage, script: scriptStorage }, store: hashStorage, defaults: { // Template name conventions templateUrl: "", templateSuffix: ".html", templatePrefix: "", // AJAX Options ajax: { "async": true, "dataType": "html", "type": "GET" }, // infuse() specific options - NOT used for "get" or "getSync" target: function(templateId) { return "#" + templateId; }, // DEFAULT MAPPING loadingTemplate: { content: '
Loading...
', transitionIn: function(target, content) { var tgt = $(target); tgt.hide(); tgt.html(content); tgt.fadeIn(); }, transitionOut: function(target) { $(target).html(""); } }, postRender: function(targetElement) { }, // NO_OP effectively by default preRender: function(targetElement, template) { }, // NO_OP effectively by default render: function(target, template) { var tgt = $(target); if(tgt.children().length === 0) { tgt.append($(template)); } else { tgt.children().replaceWith($(template)); } }, bindingInstruction: function(template, model) { return template; }, // NO_OP effectively by default useLoadingTemplate: true // true/false }, get: function(options, callback) { var templateOptions = $.extend({}, infuser.defaults, (typeof options === "object" ? options : { templateId: options })), template; templateOptions.ajax.url = helpers.getTemplatePath(templateOptions); template = infuser.store.getTemplate(templateOptions.ajax.url); if(!template || $.inArray(templateOptions.ajax.url, errors) !== -1) { templateOptions.ajax.success = helpers.templateGetSuccess(templateOptions.ajax.url, callback); templateOptions.ajax.error = helpers.templateGetError(templateOptions.templateId, templateOptions.ajax.url, callback); $.trafficCop(templateOptions.ajax); } else { callback(template); } }, getSync: function(options) { var templateOptions = $.extend({}, infuser.defaults, (typeof options === "object" ? options : { templateId: options }), { ajax: { async: false } }), template, templateHtml; templateOptions.ajax.url = helpers.getTemplatePath(templateOptions); template = infuser.store.getTemplate(templateOptions.ajax.url); if(!template || $.inArray(templateOptions.ajax.url, errors) !== -1) { templateHtml = null; templateOptions.ajax.success = function(response) { templateHtml = response; }; templateOptions.ajax.error = function(exception) { if($.inArray(templateOptions.ajax.url) === -1) { errors.push(templateOptions.ajax.url); } templateHtml = returnErrorTemplate("HTTP Status code: exception.status", templateOptions.templateId, templateOptions.ajax.url); }; $.ajax(templateOptions.ajax); if(templateHtml === null) { templateHtml = returnErrorTemplate("An unknown error occurred.", templateOptions.templateId, templateOptions.ajax.url); } else { infuser.store.storeTemplate(templateOptions.ajax.url, templateHtml); template = infuser.store.getTemplate(templateOptions.ajax.url); } } return template; }, infuse: function(templateId, renderOptions) { var templateOptions = $.extend({}, infuser.defaults, (typeof templateId === "object" ? templateId : renderOptions), (typeof templateId === "string" ? { templateId: templateId } : undefined )), targetElement = typeof templateOptions.target === 'function' ? templateOptions.target(templateId) : templateOptions.target; if(templateOptions.useLoadingTemplate) { templateOptions.loadingTemplate.transitionIn(targetElement, templateOptions.loadingTemplate.content); } infuser.get(templateOptions, function(template) { var _template = template; templateOptions.preRender(targetElement, _template); _template = templateOptions.bindingInstruction(_template, templateOptions.model); if(templateOptions.useLoadingTemplate) { templateOptions.loadingTemplate.transitionOut(targetElement); } templateOptions.render(targetElement, _template); templateOptions.postRender(targetElement); }); } }; global.infuser = infuser; })(jQuery, window); // Knockout External Template Engine // Author: Jim Cowart // License: MIT (http://www.opensource.org/licenses/mit-license) // Version 2.0.5 (function ( global, ko, jQuery, infuser, undefined ) { var ExternalTemplateSource = function(templateId, options) { var self = this, origAfterRender; self.templateId = templateId; self.loaded = false; self.template = ko.observable(infuser.defaults.useLoadingTemplate ? infuser.defaults.loadingTemplate.content : undefined); self.template.data = {}; self.options = ko.utils.extend({},options); self.options.templateId = templateId; if(self.options && self.options.afterRender) { origAfterRender = self.options.afterRender; self.options.afterRender = function() { if(self.loaded) { origAfterRender.apply(self.options, arguments); } }; } }; ko.utils.extend(ExternalTemplateSource.prototype, { data: function(key, value) { if (arguments.length === 1) { if(key === "precompiled") { this.template(); } return this.template.data[key]; } this.template.data[key] = value; }, text: function(value) { if (!this.loaded) { this.getTemplate(); } if (arguments.length === 0) { return this.template(); } else { this.template(arguments[0]); } }, getTemplate: function() { var self = this; infuser.get(self.options, function(tmpl) { self.data("precompiled",null); self.template(tmpl); self.loaded = true; }); } }); var KoExternalTemplateEngine = function(koEngineType) { var engine = koEngineType ? new koEngineType() : new ko.nativeTemplateEngine(); engine.templates = {}; engine.makeTemplateSource = function(template, bindingContext, options) { // Named template if (typeof template == "string") { var elem = document.getElementById(template); if (elem) return new ko.templateSources.domElement(elem); else { if(!engine.templates[template]) { engine.templates[template] = new ExternalTemplateSource(template, options); } return engine.templates[template]; } } else if ((template.nodeType == 1) || (template.nodeType == 8)) { // Anonymous template return new ko.templateSources.anonymousTemplate(template); } }; engine.renderTemplate = function (template, bindingContext, options) { var templateSource = engine.makeTemplateSource(template, bindingContext, options); return engine.renderTemplateSource(templateSource, bindingContext, options); }; return engine; }; ko.KoExternalTemplateEngine = KoExternalTemplateEngine; if (jQuery.tmpl && jQuery.tmpl.tag.tmpl.open.toString().indexOf('__') >= 0) { ko.setTemplateEngine(new KoExternalTemplateEngine(ko.jqueryTmplTemplateEngine)); } else { ko.setTemplateEngine(new KoExternalTemplateEngine()); } })( window, ko, jQuery, infuser );