src/conbo/binding/BindingUtils.js
function(name, handler, readOnly, raw)
		{
			if (!conbo.isString(name) || !conbo.isFunction(handler))
			{
				conbo.warn("registerAttribute: both 'name' and 'handler' parameters are required");
				return this;
			}
			
			var split = conbo.toUnderscoreCase(name).split('_');
			
			if (split.length < 2)
			{
				conbo.warn("registerAttribute: "+name+" does not include a namespace, e.g. "+conbo.toCamelCase('my-'+name));
				return this;
			}
			
			var ns = split[0];
			
			if (BindingUtils__reservedNamespaces.indexOf(ns) != -1)
			{
				conbo.warn("registerAttribute: custom attributes cannot to use the "+ns+" namespace");
				return this;
			}
			
			BindingUtils__registeredNamespaces = conbo.union(BindingUtils__registeredNamespaces, [ns]);
			
			conbo.assign(handler, 
			{
				readOnly: !!readOnly,
				raw: !!raw
			});
			
			BindingUtils__customAttrs[name] = handler;
			
			return this;
		}
function(name, handler, readOnly, raw)
		{
			if (!conbo.isString(name) || !conbo.isFunction(handler))
			{
				conbo.warn("registerAttribute: both 'name' and 'handler' parameters are required");
				return this;
			}
			
			var split = conbo.toUnderscoreCase(name).split('_');
			
			if (split.length < 2)
			{
				conbo.warn("registerAttribute: "+name+" does not include a namespace, e.g. "+conbo.toCamelCase('my-'+name));
				return this;
			}
			
			var ns = split[0];
			
			if (BindingUtils__reservedNamespaces.indexOf(ns) != -1)
			{
				conbo.warn("registerAttribute: custom attributes cannot to use the "+ns+" namespace");
				return this;
			}
			
			BindingUtils__registeredNamespaces = conbo.union(BindingUtils__registeredNamespaces, [ns]);
			
			conbo.assign(handler, 
			{
				readOnly: !!readOnly,
				raw: !!raw
			});
			
			BindingUtils__customAttrs[name] = handler;
			
			return this;
		}
function ( name , handler , readOnly , raw ) { if ( ! conbo . isString ( name ) || ! conbo . isFunction ( handler ) ) { conbo . warn ( "registerAttribute: both 'name' and 'handler' parameters are required" ) ; return this ; } var split = conbo . toUnderscoreCase ( name ) . split ( '_' ) ; if ( split . length < 2 ) { conbo . warn ( "registerAttribute: " + name + " does not include a namespace, e.g. " + conbo . toCamelCase ( 'my-' + name ) ) ; return this ; } var ns = split [ 0 ] ; if ( BindingUtils__reservedNamespaces . indexOf ( ns ) != - 1 ) { conbo . warn ( "registerAttribute: custom attributes cannot to use the " + ns + " namespace" ) ; return this ; } BindingUtils__registeredNamespaces = conbo . union ( BindingUtils__registeredNamespaces , [ ns ] ) ; conbo . assign ( handler , { readOnly : ! ! readOnly , raw : ! ! raw } ) ; BindingUtils__customAttrs [ name ] = handler ; return this ; }
Register a custom attribute handler

@param		{string}	name - camelCase version of the attribute name (must include a namespace prefix)
@param		{Function}	handler - function that will handle the data bound to the element
@param 		{boolean}	readOnly - Whether or not the attribute is read-only (default: false)
@param 		{boolean}	[raw=false] - Whether or not parameters should be passed to the handler as a raw String instead of a bound value
@returns		{conbo.BindingUtils}	A reference to this object

@example
// HTML: <div my-font-name="myProperty"></div>
conbo.bindingUtils.registerAttribute('myFontName', function(el, value, options, param)
{
el.style.fontName = value;
});
Register a custom attribute handler