1 var accessID = 'simples'+ new Date().getTime(), 2 // The following elements throw uncatchable exceptions if you 3 // attempt to add data properties to them. 4 noData = { 5 "embed": true, 6 "object": true, 7 "applet": true 8 }, 9 /** @private */ 10 canDoData = function( elem ){ 11 return elem && elem.nodeName && !( elem == WIN || noData[ elem.nodeName.toLowerCase() ] ); 12 }, 13 /** @private */ 14 removeHTML5Data = function( elem, key ){ 15 16 var data = elem.dataset; 17 18 if( data && data[ key ] ){ 19 delete elem.dataset[ key ]; 20 } else if( !data ){ 21 Simples.attr( elem, "data-" + key, null ); 22 } 23 }, 24 /** @private */ 25 readHTML5Data = function( elem, key, original ){ 26 27 var data = elem.dataset; 28 29 if( key ){ 30 var val = data ? data[ key ] : Simples.attr( elem, "data-" + key ); 31 return ( val == null || val == "" ) ? UNDEF : val; 32 } else { 33 if (!data) { 34 data = {}; 35 var attrs = elem.attributes, i = attrs ? attrs.length : 0; 36 while (i) { 37 var attr = attrs[ --i ]; 38 if (attr.name.indexOf('data-') === 0) { 39 data[attr.name.substr(5)] = attr.value; 40 } 41 } 42 } else { 43 var newData = {}; 44 for( var name in data ){ 45 newData[ name ] = data[ name ]; 46 } 47 data = newData; 48 } 49 return Simples.merge( data, original || {} ); 50 } 51 }; 52 53 Simples.merge( /** @lends Simples */ { 54 /** 55 * @description for the provided element you can save data to the elements dataset where a simple string or read data off of the element 56 * @param {Element} elem the element to read and manipulate dataset 57 * @param {String} key the name of the dataset to work with 58 * @param {All} value the value to write to the dataset, where value is undefined will read, where value is null will remove the key and data 59 * @returns {Object|Null|All} returns dataset object for read where no key, returns value where read and null for eveything else 60 */ 61 data : function( elem, key, value ){ 62 if ( canDoData( elem ) && ( key === UNDEF || typeof key === "string" ) ) { 63 var data = !elem[ accessID ] ? elem[ accessID ] = {} : elem[ accessID ]; 64 65 if( key && value !== UNDEF ){ 66 // To remove the existing data-* attribute as well as the data value 67 removeHTML5Data( elem, key ); 68 if( value !== null ){ 69 data[ key ] = value; 70 } else { 71 delete data[ key ]; 72 } 73 } else if( value === UNDEF ){ 74 if( !key ){ 75 return Simples.merge( data, readHTML5Data( elem, null, data ) ); 76 } else { 77 var val = data[ key ]; 78 return typeof val === "undefined" ? readHTML5Data( elem, key ) : val; 79 } 80 } 81 } 82 return null; 83 }, 84 /** 85 * @description for the provided element you can save data to the elements dataset where a simple string or read data off of the element 86 * @param {Element} elem the element to clean all data off of the children 87 * @param {Boolean} andSelf whether to include the provided element in with its children in the cleaning process 88 */ 89 cleanData : function( elem, andSelf ){ 90 // Remove element nodes and prevent memory leaks 91 var canClean = canDoData( elem ), 92 elems = canClean ? Simples.makeArray( elem.getElementsByTagName("*") ) : []; 93 94 if( canClean && andSelf !== false ){ 95 elems.push( elem ); 96 } 97 var i=elems.length; 98 while( i ){ 99 // decrement to ensure correct array position 100 i--; 101 if ( elems[ i ].nodeType === 1 ) { 102 // Clean up the element expando 103 try { 104 delete elems[ i ][ accessID ]; 105 } catch( e ) { 106 // IE has trouble directly removing the expando 107 // but it's ok with using removeAttribute 108 if ( elems[ i ].removeAttribute ) { 109 elems[ i ].removeAttribute( accessID ); 110 } 111 } 112 } 113 } 114 } 115 }); 116 117 Simples.extend( /** @lends Simples.fn */ { 118 /** 119 * Simples( '*' ).data: for the elements on the Simples object you can save data to the elements dataset where a simple string or read data off of the element, Simples.data for more information 120 * @param {String} key the name of the dataset to work with 121 * @param {All} value the value to write to the dataset 122 * @returns {Simples|All} returns Simples object for write and delete and the value for read 123 */ 124 data : function( key, value ){ 125 if( typeof key === "string" ){ 126 if( value !== UNDEF ){ 127 var l=this.length; 128 while( l ){ 129 Simples.data( this[--l], key, value ); 130 } 131 } else { 132 return this[0] ? Simples.data( this[0], key ) : null; 133 } 134 } 135 return this; 136 } 137 });