Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added html5data methods set/get #91

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 83 additions & 3 deletions src/prototype/dom/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -3103,12 +3103,92 @@

return value;
}


//simple test for native HTML5 dataset existence
var NATIVEHTML5DATASET = (function (){
DIV.setAttribute('data-test-this-thing','test');
return (typeof DIV.dataset !== 'undefined' && DIV.dataset.testThisThing === 'test') ? true : false;
})();
DIV.removeAttribute('data-test-this-thing');
/**
* Element.gethtml5data(@element[, datakey]) -> Object
*
* Retrieves HTML5 data-* attributes set on `element`.
*
* This will clear up any problems retreiving these data attributes on browsers
* that don't support them.
*
* ##### Example
*
* language: html
* <div id="dataitem" data-old-url="http://prototypejs.org"></div>
*
*
* $('dataitem').gethtml5data();
* // -> {'oldUrl':'http://prototypejs.org'}
* $('dataitem').gethtml5data('oldUrl');
* // -> 'http://prototypejs.org'
**/
function gethtml5data(element,datalabel){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var getHtml5Data = NATIVEHTML5DATASET ? function(element, datalabel) {
  if (!(element = $(element))) return;
  return datalabel ? element.dataset[datalabel.camelize()] : element.dataset;
} : function(element, datalabel) {
  // skipped
};
  1. You can make two different implementations (native/emulated) rather than check each time.
  2. You return object {someCamelizedProperty: value} instead of plain value when datalabel is provided. IMHO when I call element.getHtml5Data('my-data') I just want my data back without any extra effort to extract it from an object.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for 1 - thats a good idea - the other code changes were simple ones - let me work on separating them out

for 2 I was thinking of doing that - but I wanted to be consistent with the return value (an object) vs "if you ask for one value you'll get a string - otherwise you get an object" what do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of time similar methods in other frameworks are used to retrieve exactly one value. Compare

var data1 = element1.getHtml5Data('my-data'), data2 = element2.getHtml5Data('my-data');

with

var data1 = element1.getHtml5Data('my-data')['my-data'], data2 = element2.getHtml5Data('my-data')['my-data'];

Even if you need two or three values from the same element

var a = element.getHtml5Data('my-data-a'), b = element.getHtml5Data('my-data-b');

looks not worser than

var data = element.getHtml5Data(), a = data['my-data-a'], b = data['my-data-b'];

Also in this example count the time needed for enumerating all attributes of an element and retrieving all data- attributes in order to get just few attributes with known names.

P.S. Everything is an object :)

if(!(element = $(element))) return;
if(datalabel != undefined) return element.dataset[datalabel];
else return element.dataset;
}
//if the easy native html5 dataset is not supported do it the hard way
function gethtml5data_simulated(element,datalabel){
if(!(element = $(element))) return;
var returnobject = {};
if(typeof datalabel !== 'undefined') return element.readAttribute('data-'+datalabel.underscore().dasherize());
else{
var label = "";
var numberattributes = element.attributes.length;
for(var t = 0; t < numberattributes ; t++){
if(element.attributes[t].name.startsWith('data-')){
label = element.attributes[t].name.substring(5).camelize();
returnobject[label] = element.attributes[t].value;
}
}
}
return returnobject;
}
/**
* Element.sethtml5data(@element,datakey [,value]) -> Object
*
* Sets/Removes HTML5 data-* attributes on `element`. If `value` is not defined or null it will clear the data value on the element.
*
* This will clear up any problems setting these data attributes on browsers
* that don't support them.
*
* ##### Example
*
* language: html
* <div id="dataitem" data-old-url="http://prototypejs.org"></div>
*
* Then:
* $("dataitem").sethtml5data('newUrl','http://api.prototypejs.org');
* $("dataitem").sethtml5data('oldUrl',null);
*
* language: html
* <div id="dataitem" data-new-url="http://api.prototypejs.org"></div>
**/
function sethtml5data(element,datalabel,value){
if(typeof value !== 'undefined'){
element.dataset[datalabel.camelize()] = value;
}else{
delete element.dataset[datalabel.camelize()];
value = null;
}
element.writeAttribute("data-"+datalabel.underscore().dasherize(),value);
}
function sethtml5data_simulated(element,datalabel,value){
value = value || null;
element.writeAttribute("data-"+datalabel.underscore().dasherize(),value);
}
Object.extend(methods, {
getStorage: getStorage,
store: store,
retrieve: retrieve
retrieve: retrieve,
gethtml5data: NATIVEHTML5DATASET ? gethtml5data : gethtml5data_simulated,
sethtml5data: NATIVEHTML5DATASET ? sethtml5data : sethtml5data_simulated
});


Expand Down