chicago
Version:
A front-end JavaScript library for user-interface developers.
212 lines (183 loc) • 5.19 kB
JavaScript
// @name: Chicago.factory
// @description: Methods that create DOM elements and style
// @since: 1.0.5
var shouldVendorize = [
'box-sizing',
'transition',
'transform',
'perspective',
'calc',
'border-radius',
'background-clip',
];
_c.factory = {
template : function(str, data) {
var tokens = str.replace(/\n/g, '\\n').replace(/\{\{\{\s*(.+?)\s*\}\}\}/g, "{{!$1}}").split(/(\{\{\s*(.+?)\s*\}\})/g),
i = 0,
toc,
cmd,
prop,
val,
fn,
output = [],
openblocks = 0;
while(i < tokens.length) {
toc = tokens[i];
if(toc.match(/\{\{\s*(.+?)\s*\}\}/)) {
i = i + 1;
toc = tokens[i];
cmd = toc[0];
prop = toc.substring(toc.match(/^(\^|\#|\!|\~|\:)/) ? 1:0);
switch(cmd) {
// case '~':
// output.push("for(var $i=0;$i<" + prop + ".length;$i++) { var $item = " + prop + "[$i];");
// openblocks++;
// break;
// case ':':
// output.push("for(var $key in " + prop + ") { var $val = " + prop + "[$key];");
// openblocks++;
// break;
case '#':
// output.push("if(typeof " + prop + " !== 'undefined' && " + prop + " && " + prop + ".length) {");
output.push("if(" + prop + ") {");
openblocks++;
break;
// case '^':
// output.push("if(!" + prop + ") {");
// openblocks++;
// break;
case '/':
output.push("}");
openblocks--;
break;
case '!':
output.push("__ret.push(" + prop + ");");
break;
default:
output.push("__ret.push(" + prop + ");");
// output.push("__ret.push(escape(" + prop + "));");
break;
}
} else {
output.push("__ret.push('"+toc.replace(/\'/g, "\\'")+"');");
}
i = i + 1;
}
fn = new Function('$data', [
'var __ret = [];',
'try {',
'with($data){', ( ! openblocks ? output.join('') : '__ret = ["Not all blocks are closed correctly."]'), '};',
'}catch(e){__ret = [e.message];}',
'return __ret.join("").replace(/\\n\\n/g, "\\n");',
'function escape(html) { return String(html).replace(/&/g, \'&\').replace(/\"/g, \'"\').replace(/</g, \'<\').replace(/>/g, \'>\');}'
].join("\n"));
return data ? fn(data) : fn;
},
make : function( name, options ) {
if( ! _c[name] || ! _c[name].template ) {
return;
}
options = options || {};
var templateOptions = {},
ele;
if( _c[name].template.options ) {
for( var prop in options ) {
if( ! _c.utils.is.undefined( _c[name].template.options[prop] ) ) {
if( prop === 'id' ) {
options[prop] = _c.utils.stringToSlug( options[prop] );
}
templateOptions[prop] = options[prop];
}
}
templateOptions = _c.extend(true, {}, _c[name].template.options, templateOptions);
}
if( _c[name].template.css && ! _c.css[name] ) {
_c.css[name] = true;
var css = _c.factory.css( _c[name].template.css, name );
_c.$head.prepend( css );
}
if( _c[name].template.html ) {
var html = _c.factory.template( _c[name].template.html, templateOptions );
ele = _c.$(html);
_c.$body.append( ele );
} else {
ele = _c.$doc;
}
return _c[name]( ele, options );
},
vendorize : function( property, value ) {
if( _c.utils.is.numeric( value ) ) {
return property + ':' + value + ';';
}
property = String( property );
value = String( value );
var prefixes = [
'-webkit-',
'-moz-',
],
output = property + ':' + value + ';\n';
for( var i = 0; i < shouldVendorize.length; i++ ) {
var prop = shouldVendorize[i];
if( output.indexOf( prop ) > -1 ) {
var prefix = _c.browser.getPrefix( prop );
output = output.replace( new RegExp( prop, 'g' ), prefix + prop );
}
}
return output;
},
needsUnit : function( property ) {
var needsUnit = [
'width',
'height',
'top',
'left',
'bottom',
'right',
'margin',
'padding',
'font-size',
];
return _c.utils.inArray( needsUnit, property )
},
css : function( object, name ) {
name = name || 'module';
// ensure `object` is a plain object
if( ! _c.utils.is.object( object ) ) {
throw new Error( '_c.factory.css requires an object' );
}
var output = ['<style data-css="' + name + '-css">', '</style>'];
for( var selector in object ) {
var len = output.length,
index = len - 1,
set = object[ selector ];
if( ! _c.utils.is.object( set ) ) {
continue;
}
// add selectors to output
output.splice( index, 0, selector );
// create css as a string
var setString = '{';
for( var prop in set ) {
var value = set[prop];
// add units
// if the value is greater than 0, assume the unit is px
if( value && _c.utils.is.numeric( value ) ) {
value = _c.factory.needsUnit( prop ) ? value += 'px' : value;
}
setString += _c.factory.vendorize( prop, value );
}
len = output.length;
index = len - 1;
// add css value set to output
output.splice( index, 0, setString + '}' );
}
return output.join( '' );
},
};
_c.factory.make.css = function( name ) {
if( _c[name] && _c[name].template.css && ! _c.css[name] ) {
_c.css[name] = true;
var css = _c.factory.css( _c[name].template.css, name );
_c.$head.prepend( css );
}
};