dom-layer
Version:
Virtual DOM implementation.
111 lines (100 loc) • 2.77 kB
JavaScript
var dataset = require('./dataset');
var stringifyClass = require('../../util/stringify-class');
/**
* Maintains state of element properties.
*
* @param Object element A DOM element.
* @param Object previous The previous state of properties.
* @param Object props The properties to match on.
* @return Object props The element properties state.
*/
function patch(element, previous, props) {
if (!previous && !props) {
return props;
}
var name, value;
previous = previous || {};
props = props || {};
for (name in previous) {
if (previous[name] === undefined || props[name] !== undefined) {
continue;
}
unset(name, element, previous);
}
for (name in props) {
set(name, element, previous, props);
}
return props;
}
/**
* Sets a property.
*
* @param String name The property name to set.
* @param Object element A DOM element.
* @param Object previous The previous state of properties.
* @param Object props The properties to match on.
*/
function set(name, element, previous, props) {
if (set.handlers[name]) {
set.handlers[name](name, element, previous, props);
} else if (previous[name] !== props[name]) {
element[name] = props[name];
}
};
set.handlers = Object.create(null);
/**
* Unsets a property.
*
* @param String name The property name to unset.
* @param Object element A DOM element.
* @param Object previous The previous state of properties.
*/
function unset(name, element, previous) {
if (unset.handlers[name]) {
unset.handlers[name](name, element, previous);
} else {
element[name] = null;
}
};
unset.handlers = Object.create(null);
/**
* Custom set handler for the type attribute.
* When changed the value is restored (IE compatibility).
*/
set.handlers.type = function(name, element, previous, props) {
if (previous[name] === props[name]) {
return;
}
var value = element.value;
element[name] = props[name];
element.value = value;
};
/**
* Custom set handler for the class attribute.
*/
set.handlers.className = function(name, element, previous, props) {
element.className = props[name] ? stringifyClass(props[name]) : '';
};
/**
* Custom set handler for the dataset attribute.
*/
set.handlers.dataset = function(name, element, previous, props) {
dataset.patch(element, previous[name], props[name]);
};
/**
* Custom unset handler for the class attribute.
*/
unset.handlers.className = function(name, element, previous) {
element.className = '';
};
/**
* Custom unset handler for the dataset attribute.
*/
unset.handlers.dataset = function(name, element, previous) {
dataset.patch(element, previous[name], {});
};
module.exports = {
patch: patch,
set: set,
unset: unset
};