public
Last active — forked from neilj/gist:1532562

DOM sugar

  • Download Gist
domsugar.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
// DOM sugar
// ==================================================================
// Modified version of Neil Jenkins' "Sugared DOM" <https://gist.github.com/3524145>
//
// Usage
// ------------------------------------------------------------------
// var make = domsugar(document);
//
// make( 'p.foo#bar', { hidden: true }, [ make( 'span' ) ] );
// => <p class="foo" id="bar" hidden><span></span></p>
//
// make( '.bar', [ '<b></b>' ] );
// make( '.bar', { text: '<b></b>' } );
// => <div class="bar">&lt;b&gt;&lt/b&gt;</div>
//
// make( 'div', [ make( 'b', [ 'Foo', make( 'i' ) ] ) ] );
// make( 'div', { html: '<b>Foo<i></i></b>' } );
// => <div><b>Foo<i></i></b></div>
//
// var myDiv = document.createElement( 'div' );
// make( myDiv, { id: 'foo' } );
// => <div id="foo"></div>
 
(function () {
 
'use strict';
 
var domsugar = function ( doc ) {
 
// instanceOf is faster, but not when used with a custom document.
var isArray = Array.isArray || function( obj ) {
return Object.prototype.toString.call( obj ) === '[object Array]';
};
 
// Some properties need to be direct, other are common ones and setting
// them directly is faster than setAttribute.
var directProperties = { 'class': 'className', className: 'className',
defaultValue: 'defaultValue', 'for': 'htmlFor', html: 'innerHTML',
id: 'id', name: 'name', src: 'src', text: 'textContent',
title: 'title', value: 'value' };
// Object lookup is faster than indexOf.
var booleanProperties = { checked: 1, defaultChecked: 1, disabled: 1,
hidden: 1, multiple: 1, selected: 1 };
 
var setProperty = function ( el, key, value ) {
var prop = directProperties[ key ];
if ( prop ) {
el[ prop ] = ( value == null ? '' : '' + value );
} else if ( booleanProperties[ key ] ) {
el[ key ] = !!value;
} else if ( value == null ) {
el.removeAttribute( key );
} else {
el.setAttribute( key, '' + value );
}
};
 
var appendChildren = function ( el, children ) {
var i, l, node;
for ( i = 0, l = children.length; i < l; i += 1 ) {
node = children[i];
if ( node ) {
if ( isArray( node ) ) {
appendChildren( el, node );
} else {
if ( typeof node === 'string' ) {
node = doc.createTextNode( node );
}
el.appendChild( node );
}
}
}
};
 
var splitter = /(#|\.)/;
 
return function ( tag, props, children ) {
if ( isArray( props ) ) {
children = props;
props = null;
}
if ( !tag ) { tag = 'div'; }
 
var parts, name, el,
i, j, l, node, prop;
if ( typeof tag === 'string' && splitter.test( tag ) ) {
parts = tag.split( splitter );
tag = parts[0];
if ( !props ) { props = {}; }
for ( i = 1, j = 2, l = parts.length; j < l; i += 2, j += 2 ) {
name = parts[j];
if ( parts[i] === '#' ) {
props.id = name;
} else {
props.className = props.className ?
props.className + ' ' + name : name;
}
}
}
el = typeof tag === 'string' ? doc.createElement( tag ) : tag;
if ( props ) {
for ( prop in props ) {
setProperty( el, prop, props[ prop ] );
}
}
if ( children ) {
appendChildren( el, children );
}
return el;
};
};
 
// Export as CommonJS module or as browser global
if ( typeof module !== 'undefined' && module.exports ) {
module.exports = domsugar;
} else {
window.domsugar = domsugar;
}
 
})();

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.