68 lines
2.2 KiB
JavaScript
68 lines
2.2 KiB
JavaScript
/**
|
|
* Copyright (c) 2017 ESHA Research
|
|
* Dual licensed under the MIT and GPL licenses:
|
|
* http://www.opensource.org/licenses/mit-license.php
|
|
* http://www.gnu.org/licenses/gpl.html
|
|
*
|
|
* Declarative, persistent DOM content.
|
|
*
|
|
* <input store name="whatever">
|
|
* <div store="somekey" store-area="session" contenteditable>Some content</div>
|
|
*
|
|
* Status: BETA - uses store, doesn't extend it, deserves standalone project
|
|
*/
|
|
;(function(document, store, _, Array) {
|
|
|
|
// expose internal functions on store._.dom for extensibility
|
|
var DOM = _.dom = function() {
|
|
var nodes = document.querySelectorAll(DOM.selector),
|
|
array = Array.prototype.slice.call(nodes);
|
|
for (var i=0; i<array.length; i++) {
|
|
DOM.node(array[i], i);
|
|
}
|
|
return array;
|
|
};
|
|
DOM.selector = '[store],[store-area]';
|
|
DOM.event = 'input';// beforeunload is tempting
|
|
DOM.node = function(node, i) {
|
|
var key = DOM.key(node, i),
|
|
area = DOM.area(node),
|
|
value = area(key);
|
|
if (value == null) {
|
|
value = DOM.get(node);
|
|
} else {
|
|
DOM.set(node, value);
|
|
}
|
|
if (!node.storeListener) {
|
|
node.addEventListener(DOM.event, function() {
|
|
area(key, DOM.get(node));
|
|
});
|
|
node.storeListener = true;
|
|
}
|
|
};
|
|
DOM.area = function(node) {
|
|
return store[node.getAttribute('store-area') || 'local'];
|
|
};
|
|
// prefer store attribute value, then name attribute, use nodeName+index as last resort
|
|
DOM.key = function(node, i) {
|
|
return node.getAttribute('store') ||
|
|
node.getAttribute('name') ||
|
|
('dom.'+node.nodeName.toLowerCase() + (i||''));
|
|
};
|
|
// both get and set should prefer value property to innerHTML
|
|
DOM.get = function(node) {
|
|
return node.value || node.innerHTML;
|
|
};
|
|
DOM.set = function(node, value) {
|
|
if ('value' in node) {
|
|
node.value = value;
|
|
} else {
|
|
node.innerHTML = typeof value === "string" ? value : _.stringify(value);
|
|
}
|
|
};
|
|
|
|
// initialize
|
|
document.addEventListener('DOMContentLoaded', DOM);
|
|
|
|
})(document, window.store, window.store._, Array);
|