/* * Copyright 2011 eBay Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ 'use strict'; var escapeXml = require('raptor-util/escapeXml'); var escapeXmlAttr = escapeXml.attr; var runtime = require('./'); // Circular dependency, but that is okay var attr = require('raptor-util/attr'); var attrs = require('raptor-util/attrs'); var isArray = Array.isArray; var STYLE_ATTR = 'style'; var CLASS_ATTR = 'class'; function notEmpty(o) { if (o == null) { return false; } else if (Array.isArray(o)) { return !!o.length; } else if (o === '') { return false; } return true; } function classListArray(classList) { var classNames = []; for (var i=0, len=classList.length; i ' style="color: red; font-weight: bold"' * sa({color: 'red', 'font-weight': 'bold'}) ==> ' style="color: red; font-weight: bold"' */ sa: function(style) { if (!style) { return ''; } if (typeof style === 'string') { return attr(STYLE_ATTR, style, false); } else if (typeof style === 'object') { var parts = []; for (var name in style) { if (style.hasOwnProperty(name)) { var value = style[name]; if (value) { parts.push(name + ':' + value); } } } return parts ? attr(STYLE_ATTR, parts.join(';'), false) : ''; } else { return ''; } }, /** * Internal helper method to handle the "class" attribute. The value can either * be a string, an array or an object. For example: * * ca('foo bar') ==> ' class="foo bar"' * ca({foo: true, bar: false, baz: true}) ==> ' class="foo baz"' * ca(['foo', 'bar']) ==> ' class="foo bar"' */ ca: function(classNames) { if (!classNames) { return ''; } if (typeof classNames === 'string') { return attr(CLASS_ATTR, classNames, false); } else if (isArray(classNames)) { return attr(CLASS_ATTR, classListArray(classNames), false); } else if (typeof classNames === 'object') { var classList = []; for (var name in classNames) { if (classNames.hasOwnProperty(name)) { var value = classNames[name]; if (value) { classList.push(name); } } } return attr(CLASS_ATTR, classListArray(classList), false); } else { return ''; } }, /** * Loads a template */ l: function(path) { if (typeof path === 'string') { return runtime.load(path); } else { // Assume it is already a pre-loaded template return path; } }, // ---------------------------------- // The helpers listed below require an out // ---------------------------------- /** * Invoke a tag handler render function */ t: function (renderer, targetProperty, isRepeated, hasNestedTags) { if (renderer) { renderer = resolveRenderer(renderer); } if (targetProperty || hasNestedTags) { return function(input, out, parent, renderBody) { // Handle nested tags if (renderBody) { renderBody(out, input); } if (targetProperty) { // If we are nested tag then we do not have a renderer if (isRepeated) { var existingArray = parent[targetProperty]; if (existingArray) { existingArray.push(input); } else { parent[targetProperty] = [input]; } } else { parent[targetProperty] = input; } } else { // We are a tag with nested tags, but we have already found // our nested tags by rendering the body renderer(input, out); } }; } else { return renderer; } }, /** * Internal method to handle includes/partials * @private */ i: function(out, template, data) { if (!template) { return; } if (typeof template.render === 'function') { template.render(data, out); } else { throw new Error('Invalid template: ' + template); } return this; }, /** * Merges object properties * @param {[type]} object [description] * @param {[type]} source [description] * @return {[type]} [description] */ m: function(into, source) { for (var k in source) { if (source.hasOwnProperty(k) && !into.hasOwnProperty(k)) { into[k] = source[k]; } } return into; }, /** * classList(a, b, c, ...) * Joines a list of class names with spaces. Empty class names are omitted. * * classList('a', undefined, 'b') --> 'a b' * */ cl: function() { return classListArray(arguments); } };