mirror of
https://github.com/marko-js/marko.git
synced 2025-12-08 19:26:05 +00:00
121 lines
3.1 KiB
JavaScript
121 lines
3.1 KiB
JavaScript
'use strict';
|
|
var isArray = Array.isArray;
|
|
|
|
function isFunction(arg) {
|
|
return typeof arg === 'function';
|
|
}
|
|
|
|
function classListHelper(arg, classNames) {
|
|
var len;
|
|
|
|
if (arg) {
|
|
if (typeof arg === 'string') {
|
|
if (arg) {
|
|
classNames.push(arg);
|
|
}
|
|
} else if (typeof (len = arg.length) === 'number') {
|
|
for (var i=0; i<len; i++) {
|
|
classListHelper(arg[i], classNames);
|
|
}
|
|
} else if (typeof arg === 'object') {
|
|
for (var name in arg) {
|
|
if (arg.hasOwnProperty(name)) {
|
|
var value = arg[name];
|
|
if (value) {
|
|
classNames.push(name);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function classList(classList) {
|
|
var classNames = [];
|
|
classListHelper(classList, classNames);
|
|
return classNames.join(' ');
|
|
}
|
|
|
|
function createDeferredRenderer(handler) {
|
|
function deferredRenderer(input, out) {
|
|
deferredRenderer.renderer(input, out);
|
|
}
|
|
|
|
// This is the initial function that will do the rendering. We replace
|
|
// the renderer with the actual renderer func on the first render
|
|
deferredRenderer.renderer = function(input, out) {
|
|
var rendererFunc = handler.renderer || handler._ || handler.render;
|
|
if (!isFunction(rendererFunc)) {
|
|
throw Error('Invalid renderer');
|
|
}
|
|
// Use the actual renderer from now on
|
|
deferredRenderer.renderer = rendererFunc;
|
|
rendererFunc(input, out);
|
|
};
|
|
|
|
return deferredRenderer;
|
|
}
|
|
|
|
function resolveRenderer(handler) {
|
|
var renderer = handler.renderer || handler._;
|
|
|
|
if (renderer) {
|
|
return renderer;
|
|
}
|
|
|
|
if (isFunction(handler)) {
|
|
return handler;
|
|
}
|
|
|
|
// If the user code has a circular function then the renderer function
|
|
// may not be available on the module. Since we can't get a reference
|
|
// to the actual renderer(input, out) function right now we lazily
|
|
// try to get access to it later.
|
|
return createDeferredRenderer(handler);
|
|
}
|
|
|
|
/**
|
|
* Internal helper method to prevent null/undefined from being written out
|
|
* when writing text that resolves to null/undefined
|
|
* @private
|
|
*/
|
|
exports.s = function strHelper(str) {
|
|
return (str == null) ? '' : str.toString();
|
|
};
|
|
|
|
/**
|
|
* Internal helper method to handle loops without a status variable
|
|
* @private
|
|
*/
|
|
exports.f = function forEachHelper(array, callback) {
|
|
if (isArray(array)) {
|
|
for (var i=0; i<array.length; i++) {
|
|
callback(array[i]);
|
|
}
|
|
} else if (isFunction(array)) {
|
|
// Also allow the first argument to be a custom iterator function
|
|
array(callback);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Helper to load a custom tag
|
|
*/
|
|
exports.t = function loadTagHelper(renderer, targetProperty, isRepeated) {
|
|
if (renderer) {
|
|
renderer = resolveRenderer(renderer);
|
|
}
|
|
|
|
return renderer;
|
|
};
|
|
|
|
/**
|
|
* classList(a, b, c, ...)
|
|
* Joines a list of class names with spaces. Empty class names are omitted.
|
|
*
|
|
* classList('a', undefined, 'b') --> 'a b'
|
|
*
|
|
*/
|
|
exports.cl = function classListHelper() {
|
|
return classList(arguments);
|
|
}; |