dd2496be22783310acb2019f3bda56d7092b9769768299970599467bb4aff8c45a039e39194216b98fe190bc7ba9affc3349885fd3c26c2ef730cd61f573ef 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. /**
  2. * Copyright (c) 2017 ESHA Research
  3. * Dual licensed under the MIT and GPL licenses:
  4. * http://www.opensource.org/licenses/mit-license.php
  5. * http://www.gnu.org/licenses/gpl.html
  6. *
  7. * Declarative, persistent DOM content.
  8. *
  9. * <input store name="whatever">
  10. * <div store="somekey" store-area="session" contenteditable>Some content</div>
  11. *
  12. * Status: BETA - uses store, doesn't extend it, deserves standalone project
  13. */
  14. ;(function(document, store, _, Array) {
  15. // expose internal functions on store._.dom for extensibility
  16. var DOM = _.dom = function() {
  17. var nodes = document.querySelectorAll(DOM.selector),
  18. array = Array.prototype.slice.call(nodes);
  19. for (var i=0; i<array.length; i++) {
  20. DOM.node(array[i], i);
  21. }
  22. return array;
  23. };
  24. DOM.selector = '[store],[store-area]';
  25. DOM.event = 'input';// beforeunload is tempting
  26. DOM.node = function(node, i) {
  27. var key = DOM.key(node, i),
  28. area = DOM.area(node),
  29. value = area(key);
  30. if (value == null) {
  31. value = DOM.get(node);
  32. } else {
  33. DOM.set(node, value);
  34. }
  35. if (!node.storeListener) {
  36. node.addEventListener(DOM.event, function() {
  37. area(key, DOM.get(node));
  38. });
  39. node.storeListener = true;
  40. }
  41. };
  42. DOM.area = function(node) {
  43. return store[node.getAttribute('store-area') || 'local'];
  44. };
  45. // prefer store attribute value, then name attribute, use nodeName+index as last resort
  46. DOM.key = function(node, i) {
  47. return node.getAttribute('store') ||
  48. node.getAttribute('name') ||
  49. ('dom.'+node.nodeName.toLowerCase() + (i||''));
  50. };
  51. // both get and set should prefer value property to innerHTML
  52. DOM.get = function(node) {
  53. return node.value || node.innerHTML;
  54. };
  55. DOM.set = function(node, value) {
  56. if ('value' in node) {
  57. node.value = value;
  58. } else {
  59. node.innerHTML = typeof value === "string" ? value : _.stringify(value);
  60. }
  61. };
  62. // initialize
  63. document.addEventListener('DOMContentLoaded', DOM);
  64. })(document, window.store, window.store._, Array);