/*
loadHTML5Data plugin
The purpose of this plugin is to reimplement jQuery's handling of
the HTML5 data-* attributes. When a page is loaded (or new content
is loaded into the page) jQuery adds HTML5 data-* attributes into
the .data() stores of each element. For example, data-myvar='foo'
can be read with $element.data('myvar').
The problem is that jQuery does automatic type conversion. Sometimes
this is beneficial, such as converting 'true' into a real boolean,
but usually the behavoir is too unpredictable to be useful. Consider
that data-password='12e2' is returned by .data('password') as the
number 1200. It would make more sense to store all data as strings
and force the developer to do any type conversion.
This plugin takes the HTML5 data-* attributes of the elements
specified and stores them into the .data() stores of the elements
as jQuery would, except as strings. This overwrites anything already
stored, including jQuery's poorly converted values.
On page load, it should be called on all elements. Whenever new
elements are added to the DOM or new page content is loaded, the
plugin should be called on those elements immediately. The plugin is
fully chainable.
Syntax:
$elements.loadHTML5Data();
*/
// plugin definition
// function is not assigned to a variable, therefore it is executed immediately
// notice that the jQuery object is passed to the function as $
(function( $ ){
// main function call passes to other methods in namespace
$.fn.loadHTML5Data = function() {
return this.each( function(index){
var allAttributes = this.attributes;
for (var attribute in allAttributes){
// this is annoying. Not all attributes will have nodeName and nodeValue
// so we have to test if they exist for the attribute, but first
// we have to make sure the object isn't empty, and before that we
// have to make sure the object is even defined. blah.
if((typeof(allAttributes[attribute]) == 'object') &&
(allAttributes[attribute] !== null) &&
(typeof(allAttributes[attribute]['nodeName']) != 'undefined') &&
(typeof(allAttributes[attribute]['nodeValue']) != 'undefined')){
var attributeName = allAttributes[attribute]['nodeName'];
var attributeValue = allAttributes[attribute]['nodeValue'];
if (/^data-/.test(attributeName)){
// this is a data-* attribute, we have to format the
// name from 'data-foo-bar-sucks' to 'fooBarSucks'
attributeName = attributeName.replace(/^data-/, '');
attributeName = attributeName.replace(/-([a-zA-Z])/g, function(character){
return character.toUpperCase();
});
attributeName = attributeName.replace(/-/g, '');
// now update the data store without type conversion
$(this).data(attributeName, attributeValue);
}
}
}
});
};
})( jQuery ); // here is where the jQuery object is passed into the function