treeloom 0.0.0-stage → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (289) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +91 -2
  3. package/browser/treeloom.js +11232 -0
  4. package/browser/treeloom.min.js +1 -0
  5. package/browser/treeloomRenderOnly.js +11115 -0
  6. package/browser/treeloomRenderOnly.min.js +1 -0
  7. package/dist/deflate/domItemToJson.d.ts +14 -0
  8. package/dist/deflate/domItemToJson.js +43 -0
  9. package/dist/deflate/domItemToJson.min.js +1 -0
  10. package/dist/deflate/index.d.ts +7 -0
  11. package/dist/deflate/index.js +19 -0
  12. package/dist/deflate/index.min.js +1 -0
  13. package/dist/deflate/removeEmptyProperties.d.ts +8 -0
  14. package/dist/deflate/removeEmptyProperties.js +43 -0
  15. package/dist/deflate/removeEmptyProperties.min.js +1 -0
  16. package/dist/diff/appliedSnapshot.d.ts +34 -0
  17. package/dist/diff/appliedSnapshot.js +134 -0
  18. package/dist/diff/appliedSnapshot.min.js +1 -0
  19. package/dist/diff/createChangeList.d.ts +9 -0
  20. package/dist/diff/createChangeList.js +44 -0
  21. package/dist/diff/createChangeList.min.js +1 -0
  22. package/dist/diff/domItemChanges.d.ts +9 -0
  23. package/dist/diff/domItemChanges.js +167 -0
  24. package/dist/diff/domItemChanges.min.js +1 -0
  25. package/dist/diff/domItemHasAttribute.d.ts +11 -0
  26. package/dist/diff/domItemHasAttribute.js +63 -0
  27. package/dist/diff/domItemHasAttribute.min.js +1 -0
  28. package/dist/diff/elementChanges.d.ts +10 -0
  29. package/dist/diff/elementChanges.js +151 -0
  30. package/dist/diff/elementChanges.min.js +1 -0
  31. package/dist/diff/elementHasAttribute.d.ts +10 -0
  32. package/dist/diff/elementHasAttribute.js +70 -0
  33. package/dist/diff/elementHasAttribute.min.js +1 -0
  34. package/dist/diff/getAssignedStyles.d.ts +9 -0
  35. package/dist/diff/getAssignedStyles.js +22 -0
  36. package/dist/diff/getAssignedStyles.min.js +1 -0
  37. package/dist/diff/index.d.ts +9 -0
  38. package/dist/diff/index.js +27 -0
  39. package/dist/diff/index.min.js +1 -0
  40. package/dist/diff/types.d.ts +17 -0
  41. package/dist/diff/types.js +8 -0
  42. package/dist/diff/types.min.js +1 -0
  43. package/dist/domItem/index.d.ts +34 -0
  44. package/dist/domItem/index.js +81 -0
  45. package/dist/domItem/index.min.js +1 -0
  46. package/dist/domItem/objects/addDomItemProperties.d.ts +7 -0
  47. package/dist/domItem/objects/addDomItemProperties.js +27 -0
  48. package/dist/domItem/objects/addDomItemProperties.min.js +1 -0
  49. package/dist/domItem/objects/createCoreItem.d.ts +9 -0
  50. package/dist/domItem/objects/createCoreItem.js +53 -0
  51. package/dist/domItem/objects/createCoreItem.min.js +1 -0
  52. package/dist/domItem/objects/createDomItem.d.ts +10 -0
  53. package/dist/domItem/objects/createDomItem.js +40 -0
  54. package/dist/domItem/objects/createDomItem.min.js +1 -0
  55. package/dist/domItem/objects/documentDomItem.d.ts +12 -0
  56. package/dist/domItem/objects/documentDomItem.js +36 -0
  57. package/dist/domItem/objects/documentDomItem.min.js +1 -0
  58. package/dist/domItem/objects/documentItem.d.ts +18 -0
  59. package/dist/domItem/objects/documentItem.js +40 -0
  60. package/dist/domItem/objects/documentItem.min.js +1 -0
  61. package/dist/domItem/objects/initChildren.d.ts +6 -0
  62. package/dist/domItem/objects/initChildren.js +44 -0
  63. package/dist/domItem/objects/initChildren.min.js +1 -0
  64. package/dist/domItem/objects/initRoot.d.ts +9 -0
  65. package/dist/domItem/objects/initRoot.js +32 -0
  66. package/dist/domItem/objects/initRoot.min.js +1 -0
  67. package/dist/domItem/query/gatherChildItems.d.ts +12 -0
  68. package/dist/domItem/query/gatherChildItems.js +19 -0
  69. package/dist/domItem/query/gatherChildItems.min.js +1 -0
  70. package/dist/domItem/query/getChildTest.d.ts +8 -0
  71. package/dist/domItem/query/getChildTest.js +15 -0
  72. package/dist/domItem/query/getChildTest.min.js +1 -0
  73. package/dist/domItem/query/getChildrenByClass.d.ts +11 -0
  74. package/dist/domItem/query/getChildrenByClass.js +26 -0
  75. package/dist/domItem/query/getChildrenByClass.min.js +1 -0
  76. package/dist/domItem/query/getChildrenByName.d.ts +9 -0
  77. package/dist/domItem/query/getChildrenByName.js +23 -0
  78. package/dist/domItem/query/getChildrenByName.min.js +1 -0
  79. package/dist/domItem/query/getChildrenFromAttribute.d.ts +13 -0
  80. package/dist/domItem/query/getChildrenFromAttribute.js +28 -0
  81. package/dist/domItem/query/getChildrenFromAttribute.min.js +1 -0
  82. package/dist/domItem/query/getItemByElement.d.ts +11 -0
  83. package/dist/domItem/query/getItemByElement.js +29 -0
  84. package/dist/domItem/query/getItemByElement.min.js +1 -0
  85. package/dist/domItem/query/getParentsByClass.d.ts +12 -0
  86. package/dist/domItem/query/getParentsByClass.js +40 -0
  87. package/dist/domItem/query/getParentsByClass.min.js +1 -0
  88. package/dist/domItem/query/getParentsByName.d.ts +9 -0
  89. package/dist/domItem/query/getParentsByName.js +23 -0
  90. package/dist/domItem/query/getParentsByName.min.js +1 -0
  91. package/dist/domItem/query/getParentsByTagName.d.ts +9 -0
  92. package/dist/domItem/query/getParentsByTagName.js +23 -0
  93. package/dist/domItem/query/getParentsByTagName.min.js +1 -0
  94. package/dist/domItem/query/getParentsFromAttribute.d.ts +13 -0
  95. package/dist/domItem/query/getParentsFromAttribute.js +39 -0
  96. package/dist/domItem/query/getParentsFromAttribute.min.js +1 -0
  97. package/dist/domItem/traits/defineTrait.d.ts +10 -0
  98. package/dist/domItem/traits/defineTrait.js +26 -0
  99. package/dist/domItem/traits/defineTrait.min.js +1 -0
  100. package/dist/domItem/traits/definitions.d.ts +7 -0
  101. package/dist/domItem/traits/definitions.js +20 -0
  102. package/dist/domItem/traits/definitions.min.js +1 -0
  103. package/dist/domItem/traits/getNonSerializableKeys.d.ts +9 -0
  104. package/dist/domItem/traits/getNonSerializableKeys.js +25 -0
  105. package/dist/domItem/traits/getNonSerializableKeys.min.js +1 -0
  106. package/dist/domItem/traits/getTraitDefinition.d.ts +7 -0
  107. package/dist/domItem/traits/getTraitDefinition.js +20 -0
  108. package/dist/domItem/traits/getTraitDefinition.min.js +1 -0
  109. package/dist/domItem/traits/hasTrait.d.ts +8 -0
  110. package/dist/domItem/traits/hasTrait.js +15 -0
  111. package/dist/domItem/traits/hasTrait.min.js +1 -0
  112. package/dist/domItem/traits/hasTraits.d.ts +9 -0
  113. package/dist/domItem/traits/hasTraits.js +16 -0
  114. package/dist/domItem/traits/hasTraits.min.js +1 -0
  115. package/dist/domItem/traits/isDomItem.d.ts +8 -0
  116. package/dist/domItem/traits/isDomItem.js +21 -0
  117. package/dist/domItem/traits/isDomItem.min.js +1 -0
  118. package/dist/domItem/traits/withTrait.d.ts +11 -0
  119. package/dist/domItem/traits/withTrait.js +30 -0
  120. package/dist/domItem/traits/withTrait.min.js +1 -0
  121. package/dist/domItem/tree/appendChild.d.ts +8 -0
  122. package/dist/domItem/tree/appendChild.js +19 -0
  123. package/dist/domItem/tree/appendChild.min.js +1 -0
  124. package/dist/domItem/tree/getItemByPath.d.ts +10 -0
  125. package/dist/domItem/tree/getItemByPath.js +23 -0
  126. package/dist/domItem/tree/getItemByPath.min.js +1 -0
  127. package/dist/domItem/tree/getItemPath.d.ts +9 -0
  128. package/dist/domItem/tree/getItemPath.js +31 -0
  129. package/dist/domItem/tree/getItemPath.min.js +1 -0
  130. package/dist/domItem/tree/getTopParentItem.d.ts +8 -0
  131. package/dist/domItem/tree/getTopParentItem.js +29 -0
  132. package/dist/domItem/tree/getTopParentItem.min.js +1 -0
  133. package/dist/domItem/tree/insertChild.d.ts +11 -0
  134. package/dist/domItem/tree/insertChild.js +22 -0
  135. package/dist/domItem/tree/insertChild.min.js +1 -0
  136. package/dist/domItem/tree/itemIdIndex.d.ts +43 -0
  137. package/dist/domItem/tree/itemIdIndex.js +118 -0
  138. package/dist/domItem/tree/itemIdIndex.min.js +1 -0
  139. package/dist/domItem/tree/removeChild.d.ts +8 -0
  140. package/dist/domItem/tree/removeChild.js +21 -0
  141. package/dist/domItem/tree/removeChild.min.js +1 -0
  142. package/dist/domItem/tree/setParentItemReferences.d.ts +7 -0
  143. package/dist/domItem/tree/setParentItemReferences.js +24 -0
  144. package/dist/domItem/tree/setParentItemReferences.min.js +1 -0
  145. package/dist/domItem/types.d.ts +131 -0
  146. package/dist/domItem/types.js +8 -0
  147. package/dist/domItem/types.min.js +1 -0
  148. package/dist/events/functions/activateListener.d.ts +10 -0
  149. package/dist/events/functions/activateListener.js +45 -0
  150. package/dist/events/functions/activateListener.min.js +1 -0
  151. package/dist/events/functions/addEventListener.d.ts +23 -0
  152. package/dist/events/functions/addEventListener.js +54 -0
  153. package/dist/events/functions/addEventListener.min.js +1 -0
  154. package/dist/events/functions/applyActiveListeners.d.ts +9 -0
  155. package/dist/events/functions/applyActiveListeners.js +52 -0
  156. package/dist/events/functions/applyActiveListeners.min.js +1 -0
  157. package/dist/events/functions/assignListener.d.ts +12 -0
  158. package/dist/events/functions/assignListener.js +39 -0
  159. package/dist/events/functions/assignListener.min.js +1 -0
  160. package/dist/events/functions/bindAllListeners.d.ts +10 -0
  161. package/dist/events/functions/bindAllListeners.js +28 -0
  162. package/dist/events/functions/bindAllListeners.min.js +1 -0
  163. package/dist/events/functions/bindElementListeners.d.ts +7 -0
  164. package/dist/events/functions/bindElementListeners.js +34 -0
  165. package/dist/events/functions/bindElementListeners.min.js +1 -0
  166. package/dist/events/functions/bindListeners.d.ts +9 -0
  167. package/dist/events/functions/bindListeners.js +23 -0
  168. package/dist/events/functions/bindListeners.min.js +1 -0
  169. package/dist/events/functions/deactivateListener.d.ts +13 -0
  170. package/dist/events/functions/deactivateListener.js +58 -0
  171. package/dist/events/functions/deactivateListener.min.js +1 -0
  172. package/dist/events/functions/deactivateListeners.d.ts +7 -0
  173. package/dist/events/functions/deactivateListeners.js +22 -0
  174. package/dist/events/functions/deactivateListeners.min.js +1 -0
  175. package/dist/events/functions/findEventListener.d.ts +22 -0
  176. package/dist/events/functions/findEventListener.js +61 -0
  177. package/dist/events/functions/findEventListener.min.js +1 -0
  178. package/dist/events/functions/fullAddEventListener.d.ts +20 -0
  179. package/dist/events/functions/fullAddEventListener.js +45 -0
  180. package/dist/events/functions/fullAddEventListener.min.js +1 -0
  181. package/dist/events/functions/fullRemoveEventListener.d.ts +22 -0
  182. package/dist/events/functions/fullRemoveEventListener.js +37 -0
  183. package/dist/events/functions/fullRemoveEventListener.min.js +1 -0
  184. package/dist/events/functions/listenerOptions.d.ts +12 -0
  185. package/dist/events/functions/listenerOptions.js +31 -0
  186. package/dist/events/functions/listenerOptions.min.js +1 -0
  187. package/dist/events/functions/makeEventHandler.d.ts +10 -0
  188. package/dist/events/functions/makeEventHandler.js +23 -0
  189. package/dist/events/functions/makeEventHandler.min.js +1 -0
  190. package/dist/events/functions/makeForwardingListener.d.ts +11 -0
  191. package/dist/events/functions/makeForwardingListener.js +46 -0
  192. package/dist/events/functions/makeForwardingListener.min.js +1 -0
  193. package/dist/events/functions/receiveForwardedEvent.d.ts +23 -0
  194. package/dist/events/functions/receiveForwardedEvent.js +40 -0
  195. package/dist/events/functions/receiveForwardedEvent.min.js +1 -0
  196. package/dist/events/functions/registerListener.d.ts +11 -0
  197. package/dist/events/functions/registerListener.js +25 -0
  198. package/dist/events/functions/registerListener.min.js +1 -0
  199. package/dist/events/functions/registerListeners.d.ts +10 -0
  200. package/dist/events/functions/registerListeners.js +26 -0
  201. package/dist/events/functions/registerListeners.min.js +1 -0
  202. package/dist/events/functions/removeEventListener.d.ts +18 -0
  203. package/dist/events/functions/removeEventListener.js +42 -0
  204. package/dist/events/functions/removeEventListener.min.js +1 -0
  205. package/dist/events/functions/retrieveListener.d.ts +14 -0
  206. package/dist/events/functions/retrieveListener.js +39 -0
  207. package/dist/events/functions/retrieveListener.min.js +1 -0
  208. package/dist/events/functions/revokeActiveListeners.d.ts +12 -0
  209. package/dist/events/functions/revokeActiveListeners.js +54 -0
  210. package/dist/events/functions/revokeActiveListeners.min.js +1 -0
  211. package/dist/events/functions/setForwardEvents.d.ts +11 -0
  212. package/dist/events/functions/setForwardEvents.js +26 -0
  213. package/dist/events/functions/setForwardEvents.min.js +1 -0
  214. package/dist/events/functions/unassignListener.d.ts +12 -0
  215. package/dist/events/functions/unassignListener.js +32 -0
  216. package/dist/events/functions/unassignListener.min.js +1 -0
  217. package/dist/events/index.d.ts +37 -0
  218. package/dist/events/index.js +72 -0
  219. package/dist/events/index.min.js +1 -0
  220. package/dist/events/objects/createEventListener.d.ts +13 -0
  221. package/dist/events/objects/createEventListener.js +30 -0
  222. package/dist/events/objects/createEventListener.min.js +1 -0
  223. package/dist/events/objects/createEventProxy.d.ts +10 -0
  224. package/dist/events/objects/createEventProxy.js +48 -0
  225. package/dist/events/objects/createEventProxy.min.js +1 -0
  226. package/dist/events/objects/createEventResponder.d.ts +8 -0
  227. package/dist/events/objects/createEventResponder.js +27 -0
  228. package/dist/events/objects/createEventResponder.min.js +1 -0
  229. package/dist/events/objects/options/getListenerOptions.d.ts +6 -0
  230. package/dist/events/objects/options/getListenerOptions.js +22 -0
  231. package/dist/events/objects/options/getListenerOptions.min.js +1 -0
  232. package/dist/events/objects/options/numberToOptions.d.ts +8 -0
  233. package/dist/events/objects/options/numberToOptions.js +21 -0
  234. package/dist/events/objects/options/numberToOptions.min.js +1 -0
  235. package/dist/events/objects/options/optionsToNumber.d.ts +9 -0
  236. package/dist/events/objects/options/optionsToNumber.js +27 -0
  237. package/dist/events/objects/options/optionsToNumber.min.js +1 -0
  238. package/dist/events/objects/options.d.ts +6 -0
  239. package/dist/events/objects/options.js +24 -0
  240. package/dist/events/objects/options.min.js +1 -0
  241. package/dist/events/types.d.ts +87 -0
  242. package/dist/events/types.js +8 -0
  243. package/dist/events/types.min.js +1 -0
  244. package/dist/inflate/index.d.ts +4 -0
  245. package/dist/inflate/index.js +17 -0
  246. package/dist/inflate/index.min.js +1 -0
  247. package/dist/inflate/jsonToDomItem.d.ts +7 -0
  248. package/dist/inflate/jsonToDomItem.js +30 -0
  249. package/dist/inflate/jsonToDomItem.min.js +1 -0
  250. package/dist/main.d.ts +2 -0
  251. package/dist/main.js +24 -0
  252. package/dist/main.min.js +1 -0
  253. package/dist/render/generateElement.d.ts +7 -0
  254. package/dist/render/generateElement.js +41 -0
  255. package/dist/render/generateElement.min.js +1 -0
  256. package/dist/render/index.d.ts +9 -0
  257. package/dist/render/index.js +27 -0
  258. package/dist/render/index.min.js +1 -0
  259. package/dist/render/reconcile.d.ts +16 -0
  260. package/dist/render/reconcile.js +169 -0
  261. package/dist/render/reconcile.min.js +1 -0
  262. package/dist/render/renderHtml.d.ts +16 -0
  263. package/dist/render/renderHtml.js +57 -0
  264. package/dist/render/renderHtml.min.js +1 -0
  265. package/dist/render/updateChildNodes.d.ts +7 -0
  266. package/dist/render/updateChildNodes.js +53 -0
  267. package/dist/render/updateChildNodes.min.js +1 -0
  268. package/dist/render/updateElement.d.ts +14 -0
  269. package/dist/render/updateElement.js +113 -0
  270. package/dist/render/updateElement.min.js +1 -0
  271. package/dist/render/updateElements.d.ts +9 -0
  272. package/dist/render/updateElements.js +33 -0
  273. package/dist/render/updateElements.min.js +1 -0
  274. package/dist/renderOnly.d.ts +2 -0
  275. package/dist/renderOnly.js +27 -0
  276. package/dist/renderOnly.min.js +1 -0
  277. package/dist/sync/index.d.ts +6 -0
  278. package/dist/sync/index.js +21 -0
  279. package/dist/sync/index.min.js +1 -0
  280. package/dist/sync/updateChildren.d.ts +7 -0
  281. package/dist/sync/updateChildren.js +38 -0
  282. package/dist/sync/updateChildren.min.js +1 -0
  283. package/dist/sync/updateDomItem.d.ts +8 -0
  284. package/dist/sync/updateDomItem.js +53 -0
  285. package/dist/sync/updateDomItem.min.js +1 -0
  286. package/dist/sync/updateDomItems.d.ts +9 -0
  287. package/dist/sync/updateDomItems.js +33 -0
  288. package/dist/sync/updateDomItems.min.js +1 -0
  289. package/package.json +74 -4
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+
3
+ /* This Source Code Form is subject to the terms of the Mozilla Public
4
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
5
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
6
+ require("core-js/modules/es.array.includes.js");
7
+ var __importDefault = void 0 && (void 0).__importDefault || function (mod) {
8
+ return mod && mod.__esModule ? mod : {
9
+ "default": mod
10
+ };
11
+ };
12
+ Object.defineProperty(exports, "__esModule", {
13
+ value: true
14
+ });
15
+ exports.changesFromApplied = exports.forgetApplied = exports.recordApplied = void 0;
16
+ const si_funciona_1 = __importDefault(require("si-funciona"));
17
+ const createChangeList_1 = __importDefault(require("./createChangeList"));
18
+ /**
19
+ * Properties the person using the page changes directly (typing, ticking, choosing), so the element is their real current
20
+ * state, not what was last written. These are compared with the element itself, as before, so an item still puts them
21
+ * back (a controlled input: the item says '' and what was typed is cleared on the next update).
22
+ */
23
+ const LIVE_PROPERTIES = ['value', 'checked', 'selected', 'indeterminate'];
24
+ // Kept beside the item, not on it, so it never travels with the item (deflate, JSON) and goes away with the element
25
+ const snapshots = new WeakMap();
26
+ /**
27
+ * Whether an item's attributes can be compared through a snapshot: its style, when it has one, is an object of
28
+ * properties. Anything else (a style written as one string) is compared against the element, as before.
29
+ * @param domItem
30
+ */
31
+ const canSnapshot = domItem => typeof domItem.attributes.style === 'undefined' || si_funciona_1.default.isObject(domItem.attributes.style);
32
+ /**
33
+ * The class names in a className string.
34
+ * @param className
35
+ */
36
+ const classNames = className => typeof className === 'string' ? className.split(/\s+/).filter(Boolean) : [];
37
+ /**
38
+ * An item's attributes in the snapshot's form.
39
+ * @param domItem
40
+ */
41
+ const describe = domItem => {
42
+ const snapshot = {
43
+ attributes: {},
44
+ classes: [],
45
+ style: {}
46
+ };
47
+ for (const name in domItem.attributes) {
48
+ const value = domItem.attributes[name];
49
+ if (name === 'className') {
50
+ snapshot.classes = classNames(value);
51
+ continue;
52
+ }
53
+ if (name === 'style') {
54
+ for (const property in value) {
55
+ snapshot.style[si_funciona_1.default.kabobCase(property)] = value[property];
56
+ }
57
+ continue;
58
+ }
59
+ snapshot.attributes[si_funciona_1.default.kabobCase(name)] = value;
60
+ }
61
+ return snapshot;
62
+ };
63
+ /**
64
+ * Remember what was just written to the item's element (call it after the element has been updated to match the item).
65
+ * Does nothing for an item without an element, a text or comment node, or a style that is not an object.
66
+ * @param domItem
67
+ */
68
+ const recordApplied = domItem => {
69
+ if (!domItem.element || domItem.nodeValue !== null || !canSnapshot(domItem)) {
70
+ return;
71
+ }
72
+ snapshots.set(domItem.element, describe(domItem));
73
+ };
74
+ exports.recordApplied = recordApplied;
75
+ /**
76
+ * Forget what was written to an element, so its next update compares against the element itself again.
77
+ * @param element
78
+ */
79
+ const forgetApplied = element => {
80
+ if (element) {
81
+ snapshots.delete(element);
82
+ }
83
+ };
84
+ exports.forgetApplied = forgetApplied;
85
+ /**
86
+ * The changes that make the item's element match the item, worked out from what was last written to the element rather
87
+ * than from the element itself: no style or attribute is read back from the DOM, and a value the browser stores in
88
+ * another form ('#333' as 'rgb(51, 51, 51)', `border` as longhands) is not mistaken for a change. Undefined when there is
89
+ * no snapshot to compare with (the element was never written by treeloom, or was captured from existing HTML), so the
90
+ * caller compares against the element instead.
91
+ * @param domItem
92
+ * @param propertyName - The name to set a plain attribute by: the element's own property name when it has one
93
+ * (innerHTML), otherwise the attribute's name (aria-label). Same rule as the element comparison.
94
+ */
95
+ const changesFromApplied = (domItem, propertyName) => {
96
+ const previous = domItem.element ? snapshots.get(domItem.element) : undefined;
97
+ if (!previous || domItem.nodeValue !== null || !canSnapshot(domItem)) {
98
+ return undefined;
99
+ }
100
+ const next = describe(domItem);
101
+ const changes = (0, createChangeList_1.default)();
102
+ const element = domItem.element;
103
+ for (const key in next.attributes) {
104
+ const live = LIVE_PROPERTIES.includes(key) && key in element;
105
+ const current = live ? element[key] : previous.attributes[key];
106
+ const differs = live && typeof current === 'string' ? String(next.attributes[key] ?? '') !== current : next.attributes[key] !== current;
107
+ if (differs) {
108
+ changes.added[propertyName(key)] = next.attributes[key];
109
+ }
110
+ }
111
+ previous.classes.forEach((name, index) => {
112
+ if (!next.classes.includes(name)) {
113
+ changes.removed[`class.${index}`] = name;
114
+ }
115
+ });
116
+ next.classes.forEach((name, index) => {
117
+ if (!previous.classes.includes(name)) {
118
+ changes.added[`class.${index}`] = name;
119
+ }
120
+ });
121
+ for (const property in previous.style) {
122
+ if (!(property in next.style)) {
123
+ changes.removed[`style.${property}`] = previous.style[property];
124
+ }
125
+ }
126
+ for (const property in next.style) {
127
+ // A changed value is simply set again (setProperty replaces it): no remove first, so one write, not two
128
+ if (next.style[property] !== previous.style[property]) {
129
+ changes.added[`style.${property}`] = next.style[property];
130
+ }
131
+ }
132
+ return changes;
133
+ };
134
+ exports.changesFromApplied = changesFromApplied;
@@ -0,0 +1 @@
1
+ "use strict";require("core-js/modules/es.array.includes.js");var __importDefault=function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.changesFromApplied=exports.forgetApplied=exports.recordApplied=void 0;const si_funciona_1=__importDefault(require("si-funciona")),createChangeList_1=__importDefault(require("./createChangeList")),LIVE_PROPERTIES=["value","checked","selected","indeterminate"],snapshots=new WeakMap,canSnapshot=e=>void 0===e.attributes.style||si_funciona_1.default.isObject(e.attributes.style),classNames=e=>"string"==typeof e?e.split(/\s+/).filter(Boolean):[],describe=e=>{const s={attributes:{},classes:[],style:{}};for(const t in e.attributes){const a=e.attributes[t];if("className"!==t)if("style"!==t)s.attributes[si_funciona_1.default.kabobCase(t)]=a;else for(const e in a)s.style[si_funciona_1.default.kabobCase(e)]=a[e];else s.classes=classNames(a)}return s},recordApplied=e=>{e.element&&null===e.nodeValue&&canSnapshot(e)&&snapshots.set(e.element,describe(e))};exports.recordApplied=recordApplied;const forgetApplied=e=>{e&&snapshots.delete(e)};exports.forgetApplied=forgetApplied;const changesFromApplied=(e,s)=>{const t=e.element?snapshots.get(e.element):void 0;if(!t||null!==e.nodeValue||!canSnapshot(e))return;const a=describe(e),r=(0,createChangeList_1.default)(),n=e.element;for(const e in a.attributes){const i=LIVE_PROPERTIES.includes(e)&&e in n,o=i?n[e]:t.attributes[e];(i&&"string"==typeof o?String(a.attributes[e]??"")!==o:a.attributes[e]!==o)&&(r.added[s(e)]=a.attributes[e])}t.classes.forEach((e,s)=>{a.classes.includes(e)||(r.removed[`class.${s}`]=e)}),a.classes.forEach((e,s)=>{t.classes.includes(e)||(r.added[`class.${s}`]=e)});for(const e in t.style)e in a.style||(r.removed[`style.${e}`]=t.style[e]);for(const e in a.style)a.style[e]!==t.style[e]&&(r.added[`style.${e}`]=a.style[e]);return r};exports.changesFromApplied=changesFromApplied;
@@ -0,0 +1,9 @@
1
+ import type { ChangeList } from './types';
2
+ /**
3
+ * Create the change list template.
4
+ * @param changeList
5
+ * @param changeList.removed
6
+ * @param changeList.added
7
+ */
8
+ declare const createChangeList: ({ removed, added }?: Partial<Pick<ChangeList, "removed" | "added">>) => ChangeList;
9
+ export default createChangeList;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+
3
+ /* This Source Code Form is subject to the terms of the Mozilla Public
4
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
5
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
6
+ require("core-js/modules/es.array.includes.js");
7
+ var __importDefault = void 0 && (void 0).__importDefault || function (mod) {
8
+ return mod && mod.__esModule ? mod : {
9
+ "default": mod
10
+ };
11
+ };
12
+ Object.defineProperty(exports, "__esModule", {
13
+ value: true
14
+ });
15
+ const si_funciona_1 = __importDefault(require("si-funciona"));
16
+ /**
17
+ * Initialize the appendChanges method with the changeList, return the appendChanges method.
18
+ * @param changeList
19
+ * @private
20
+ */
21
+ const appendChangesTo = changeList => (changeType, changes) => {
22
+ if (!['added', 'removed'].includes(changeType)) {
23
+ throw Error(`Method appendChanges change type must be 'added' or 'removed'; ${changeType} given.`);
24
+ }
25
+ return si_funciona_1.default.mergeObjects(changeList[changeType], changes);
26
+ };
27
+ /**
28
+ * Create the change list template.
29
+ * @param changeList
30
+ * @param changeList.removed
31
+ * @param changeList.added
32
+ */
33
+ const createChangeList = ({
34
+ removed = {},
35
+ added = {}
36
+ } = {}) => {
37
+ const changeList = {
38
+ removed: Object.assign({}, removed),
39
+ added: Object.assign({}, added)
40
+ };
41
+ changeList.appendChanges = appendChangesTo(changeList);
42
+ return changeList;
43
+ };
44
+ exports.default = createChangeList;
@@ -0,0 +1 @@
1
+ "use strict";require("core-js/modules/es.array.includes.js");var __importDefault=function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0});const si_funciona_1=__importDefault(require("si-funciona")),appendChangesTo=e=>(r,a)=>{if(!["added","removed"].includes(r))throw Error(`Method appendChanges change type must be 'added' or 'removed'; ${r} given.`);return si_funciona_1.default.mergeObjects(e[r],a)},createChangeList=({removed:e={},added:r={}}={})=>{const a={removed:Object.assign({},e),added:Object.assign({},r)};return a.appendChanges=appendChangesTo(a),a};exports.default=createChangeList;
@@ -0,0 +1,9 @@
1
+ import type { DomItem } from '../domItem/types';
2
+ import type { ChangeList } from './types';
3
+ /**
4
+ * Given a domGeneral.DomItem as domItem, this function will return the changes to be applied
5
+ * to the stored element property.
6
+ * @param domItem - The DomItem having changes to be applied to its element
7
+ */
8
+ declare const domItemChanges: (domItem: DomItem) => ChangeList;
9
+ export default domItemChanges;
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+
3
+ /* This Source Code Form is subject to the terms of the Mozilla Public
4
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
5
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
6
+ var __importDefault = void 0 && (void 0).__importDefault || function (mod) {
7
+ return mod && mod.__esModule ? mod : {
8
+ "default": mod
9
+ };
10
+ };
11
+ Object.defineProperty(exports, "__esModule", {
12
+ value: true
13
+ });
14
+ const si_funciona_1 = __importDefault(require("si-funciona"));
15
+ const elementHasAttribute_1 = __importDefault(require("./elementHasAttribute"));
16
+ const createChangeList_1 = __importDefault(require("./createChangeList"));
17
+ const appliedSnapshot_1 = require("./appliedSnapshot");
18
+ /**
19
+ * Given some config, provide a function to testing attribute and key existence in that config.
20
+ * @param element
21
+ */
22
+ const checkAttribute = element => (attr, key) => {
23
+ if (typeof attr === 'object') {
24
+ const styles = attr;
25
+ const elementStyle = () => element.style;
26
+ const styleDiff = (0, elementHasAttribute_1.default)(element, key, attr);
27
+ if (Array.isArray(styleDiff) && styleDiff.length === 1 && styleDiff[0].result[0] === 0 && elementStyle()[styleDiff[0].value] === styles[styleDiff[0].value]) {
28
+ return 0;
29
+ }
30
+ // Check new, removed, or changed styles
31
+ return si_funciona_1.default.filterObject(styleDiff, arrayDiff => arrayDiff.result[0] !== 0 || elementStyle()[arrayDiff.value] !== styles[arrayDiff.value]);
32
+ }
33
+ if (key === 'class') {
34
+ const classDiff = (0, elementHasAttribute_1.default)(element, key, attr);
35
+ if (Array.isArray(classDiff) && classDiff.length === 1 && classDiff[0].result[0] === 0) {
36
+ return 0;
37
+ }
38
+ return si_funciona_1.default.filterObject(classDiff, arrayDiff => arrayDiff.result[0] !== 0);
39
+ }
40
+ return (0, elementHasAttribute_1.default)(element, key, attr);
41
+ };
42
+ /**
43
+ * Updates all the keys to be kabob-case
44
+ * @param attributesToSet
45
+ */
46
+ const kabobCaseAttributes = attributesToSet => si_funciona_1.default.reduceObject(attributesToSet, (attributes, value, name) => {
47
+ let attrValue = attributesToSet[name] ?? value;
48
+ if (si_funciona_1.default.isObject(attrValue)) {
49
+ attrValue = kabobCaseAttributes(attrValue);
50
+ }
51
+ const kabobKey = name === 'className' ? 'class' : si_funciona_1.default.kabobCase(name);
52
+ attributes[kabobKey] = attrValue;
53
+ return attributes;
54
+ }, {});
55
+ /**
56
+ * Find the name an attribute was given on the item from its kabob-case name: innerHTML is compared as inner-html, and
57
+ * camelCase cannot turn that back into innerHTML.
58
+ * @private
59
+ */
60
+ const attributeName = (attributes, kabobKey) => Object.keys(attributes).find(name => (name === 'className' ? 'class' : si_funciona_1.default.kabobCase(name)) === kabobKey) ?? si_funciona_1.default.camelCase(kabobKey);
61
+ /**
62
+ * Given a domGeneral.DomItem as domItem, this function will return the changes to be applied
63
+ * to the stored element property.
64
+ * @param domItem - The DomItem having changes to be applied to its element
65
+ */
66
+ const domItemChanges = domItem => {
67
+ const changeList = (0, createChangeList_1.default)();
68
+ if (!domItem.element) {
69
+ changeList.added.nodeName = domItem.nodeName.toLowerCase();
70
+ }
71
+ if (domItem.element && domItem.element.nodeName.toLowerCase() !== domItem.nodeName.toLowerCase()) {
72
+ // This should trigger new element creation
73
+ changeList.removed.nodeName = domItem.element.nodeName.toLowerCase();
74
+ changeList.added.nodeName = domItem.nodeName.toLowerCase();
75
+ }
76
+ if (domItem.nodeValue !== null) {
77
+ if (!si_funciona_1.default.emptyObject(domItem.attributes)) {
78
+ changeList.added = changeList.appendChanges('added', si_funciona_1.default.dotNotate(domItem.attributes));
79
+ }
80
+ if (!domItem.element) {
81
+ changeList.added.nodeValue = domItem.nodeValue;
82
+ return changeList;
83
+ }
84
+ changeList.removed.nodeValue = domItem.element.nodeValue;
85
+ if (domItem.element.nodeValue !== domItem.nodeValue) {
86
+ changeList.added.nodeValue = domItem.nodeValue;
87
+ }
88
+ return changeList;
89
+ }
90
+ // Compared with what treeloom last wrote to the element when it knows that (see appliedSnapshot): nothing is read
91
+ // back from the DOM. Not when the node is being replaced (nodeName changed): its new element starts fresh.
92
+ if (!changeList.added.nodeName) {
93
+ const fromApplied = (0, appliedSnapshot_1.changesFromApplied)(domItem, kabobKey => {
94
+ const name = attributeName(domItem.attributes, kabobKey);
95
+ const element = domItem.element;
96
+ return element && name in element && name !== 'form' ? name : kabobKey;
97
+ });
98
+ if (fromApplied) {
99
+ return fromApplied;
100
+ }
101
+ }
102
+ const domItemAttributes = kabobCaseAttributes(domItem.attributes);
103
+ const diffMap = si_funciona_1.default.mapObject(domItemAttributes, (attr, key) => checkAttribute(domItem.element)(attr, key));
104
+ return si_funciona_1.default.reduceObject(diffMap, (changed, result, key) => {
105
+ const isArray = Array.isArray(result);
106
+ if (!isArray && !result) {
107
+ // Skip if the attribute is not changed (false and not an array)
108
+ return changed;
109
+ }
110
+ if (!isArray && key === 'class') {
111
+ // Full class name string set
112
+ changed.added.className = domItem.attributes.className;
113
+ return changed;
114
+ }
115
+ if (!isArray) {
116
+ // Not an array, simply set the attribute as added
117
+ const name = attributeName(domItem.attributes, key);
118
+ // A property of the element (innerHTML) is set by its own name, anything else as an attribute (aria-label)
119
+ const element = domItem.element;
120
+ changed.added[element && name in element && name !== 'form' ? name : key] = domItem.attributes[name];
121
+ return changed;
122
+ }
123
+ if (key !== 'class' && key !== 'style') {
124
+ // Is an array, but not class or style; we don't know what this is, so we skip it.
125
+ return changed;
126
+ }
127
+ if (key === 'class') {
128
+ changed.removed = result.reduce((removed, results) => {
129
+ if (results.result[0] === -1) {
130
+ removed[`class.${results.keys[1]}`] = results.value;
131
+ }
132
+ return removed;
133
+ }, changed.removed);
134
+ changed.added = result.reduce((added, results) => {
135
+ if (results.result[0] === 1) {
136
+ added[`class.${results.keys[0]}`] = results.value;
137
+ }
138
+ return added;
139
+ }, changed.added);
140
+ return changed;
141
+ }
142
+ const elementStyle = () => domItem.element.style;
143
+ changed.removed = result.reduce((removed, results) => {
144
+ if (!domItem.element) {
145
+ return removed;
146
+ }
147
+ if (results.result[0] === -1) {
148
+ removed[`style.${results.value}`] = elementStyle()[results.value];
149
+ }
150
+ if (results.result[0] === 0 && elementStyle()[results.value] !== domItemAttributes.style[results.value]) {
151
+ removed[`style.${results.value}`] = elementStyle()[results.value];
152
+ }
153
+ return removed;
154
+ }, changed.removed);
155
+ changed.added = result.reduce((added, results) => {
156
+ if (results.result[0] === 1) {
157
+ added[`style.${results.value}`] = domItemAttributes.style[results.value];
158
+ }
159
+ if (results.result[0] === 0 && elementStyle()[results.value] !== domItemAttributes.style[results.value]) {
160
+ added[`style.${results.value}`] = domItemAttributes.style[results.value];
161
+ }
162
+ return added;
163
+ }, changed.added);
164
+ return changed;
165
+ }, changeList);
166
+ };
167
+ exports.default = domItemChanges;
@@ -0,0 +1 @@
1
+ "use strict";var __importDefault=function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0});const si_funciona_1=__importDefault(require("si-funciona")),elementHasAttribute_1=__importDefault(require("./elementHasAttribute")),createChangeList_1=__importDefault(require("./createChangeList")),appliedSnapshot_1=require("./appliedSnapshot"),checkAttribute=e=>(t,a)=>{if("object"==typeof t){const u=t,s=()=>e.style,r=(0,elementHasAttribute_1.default)(e,a,t);return Array.isArray(r)&&1===r.length&&0===r[0].result[0]&&s()[r[0].value]===u[r[0].value]?0:si_funciona_1.default.filterObject(r,e=>0!==e.result[0]||s()[e.value]!==u[e.value])}if("class"===a){const u=(0,elementHasAttribute_1.default)(e,a,t);return Array.isArray(u)&&1===u.length&&0===u[0].result[0]?0:si_funciona_1.default.filterObject(u,e=>0!==e.result[0])}return(0,elementHasAttribute_1.default)(e,a,t)},kabobCaseAttributes=e=>si_funciona_1.default.reduceObject(e,(t,a,u)=>{let s=e[u]??a;si_funciona_1.default.isObject(s)&&(s=kabobCaseAttributes(s));return t["className"===u?"class":si_funciona_1.default.kabobCase(u)]=s,t},{}),attributeName=(e,t)=>Object.keys(e).find(e=>("className"===e?"class":si_funciona_1.default.kabobCase(e))===t)??si_funciona_1.default.camelCase(t),domItemChanges=e=>{const t=(0,createChangeList_1.default)();if(e.element||(t.added.nodeName=e.nodeName.toLowerCase()),e.element&&e.element.nodeName.toLowerCase()!==e.nodeName.toLowerCase()&&(t.removed.nodeName=e.element.nodeName.toLowerCase(),t.added.nodeName=e.nodeName.toLowerCase()),null!==e.nodeValue)return si_funciona_1.default.emptyObject(e.attributes)||(t.added=t.appendChanges("added",si_funciona_1.default.dotNotate(e.attributes))),e.element?(t.removed.nodeValue=e.element.nodeValue,e.element.nodeValue!==e.nodeValue&&(t.added.nodeValue=e.nodeValue),t):(t.added.nodeValue=e.nodeValue,t);if(!t.added.nodeName){const t=(0,appliedSnapshot_1.changesFromApplied)(e,t=>{const a=attributeName(e.attributes,t),u=e.element;return u&&a in u&&"form"!==a?a:t});if(t)return t}const a=kabobCaseAttributes(e.attributes),u=si_funciona_1.default.mapObject(a,(t,a)=>checkAttribute(e.element)(t,a));return si_funciona_1.default.reduceObject(u,(t,u,s)=>{const r=Array.isArray(u);if(!r&&!u)return t;if(!r&&"class"===s)return t.added.className=e.attributes.className,t;if(!r){const a=attributeName(e.attributes,s),u=e.element;return t.added[u&&a in u&&"form"!==a?a:s]=e.attributes[a],t}if("class"!==s&&"style"!==s)return t;if("class"===s)return t.removed=u.reduce((e,t)=>(-1===t.result[0]&&(e[`class.${t.keys[1]}`]=t.value),e),t.removed),t.added=u.reduce((e,t)=>(1===t.result[0]&&(e[`class.${t.keys[0]}`]=t.value),e),t.added),t;const l=()=>e.element.style;return t.removed=u.reduce((t,u)=>e.element?(-1===u.result[0]&&(t[`style.${u.value}`]=l()[u.value]),0===u.result[0]&&l()[u.value]!==a.style[u.value]&&(t[`style.${u.value}`]=l()[u.value]),t):t,t.removed),t.added=u.reduce((e,t)=>(1===t.result[0]&&(e[`style.${t.value}`]=a.style[t.value]),0===t.result[0]&&l()[t.value]!==a.style[t.value]&&(e[`style.${t.value}`]=a.style[t.value]),e),t.added),t},t)};exports.default=domItemChanges;
@@ -0,0 +1,11 @@
1
+ import type { DomItem } from '../domItem/types';
2
+ import type { AttributeComparison } from './types';
3
+ /**
4
+ * Check if the provided DomItem has the provided attributes.
5
+ * Returns a boolean, or an array of 1 / 0 / -1 based on the comparison status.
6
+ * @param domItem - Receive the DomItem to be assessed
7
+ * @param key - The attribute name to search for
8
+ * @param attr - The expected value of the attribute to compare against
9
+ */
10
+ declare const domItemHasAttribute: (domItem: DomItem, key: string, attr: unknown) => AttributeComparison;
11
+ export default domItemHasAttribute;
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+
3
+ /* This Source Code Form is subject to the terms of the Mozilla Public
4
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
5
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
6
+ var __importDefault = void 0 && (void 0).__importDefault || function (mod) {
7
+ return mod && mod.__esModule ? mod : {
8
+ "default": mod
9
+ };
10
+ };
11
+ Object.defineProperty(exports, "__esModule", {
12
+ value: true
13
+ });
14
+ const si_funciona_1 = __importDefault(require("si-funciona"));
15
+ const getAssignedStyles_1 = __importDefault(require("./getAssignedStyles"));
16
+ /**
17
+ * For attributes which are objects or multi-part strings -1 = remove attribute, 0 = no change, 1 = add attribute
18
+ * @param domItem
19
+ * @param attr
20
+ */
21
+ const checkStyles = (domItem, attr = {}) => {
22
+ const assignedStyles = domItem.attributes.style ?? {};
23
+ if (si_funciona_1.default.emptyObject(assignedStyles)) {
24
+ return 1;
25
+ }
26
+ return si_funciona_1.default.compareArrays(Object.keys((0, getAssignedStyles_1.default)(attr)).map(si_funciona_1.default.camelCase), Object.keys(assignedStyles));
27
+ };
28
+ /**
29
+ * For attributes which are objects or multipart strings -1 = remove attribute, 0 = no change, 1 = add attribute
30
+ * @param domItem
31
+ * @param attr
32
+ */
33
+ const checkClasses = (domItem, attr = '') => {
34
+ const assignedClasses = domItem.attributes.className ?? '';
35
+ if (!assignedClasses.length) {
36
+ return 1;
37
+ }
38
+ return si_funciona_1.default.compareArrays(attr.split(' '), assignedClasses.split(' '));
39
+ };
40
+ /**
41
+ * Check if the provided DomItem has the provided attributes.
42
+ * Returns a boolean, or an array of 1 / 0 / -1 based on the comparison status.
43
+ * @param domItem - Receive the DomItem to be assessed
44
+ * @param key - The attribute name to search for
45
+ * @param attr - The expected value of the attribute to compare against
46
+ */
47
+ const domItemHasAttribute = (domItem, key, attr) => {
48
+ if (key === 'style') {
49
+ return checkStyles(domItem, attr);
50
+ }
51
+ if (key === 'className') {
52
+ return checkClasses(domItem, attr);
53
+ }
54
+ const camelKey = si_funciona_1.default.camelCase(key);
55
+ if (typeof domItem.attributes[camelKey] === 'undefined') {
56
+ return 1;
57
+ }
58
+ if (domItem.attributes[camelKey] === attr) {
59
+ return 0;
60
+ }
61
+ return 1;
62
+ };
63
+ exports.default = domItemHasAttribute;
@@ -0,0 +1 @@
1
+ "use strict";var __importDefault=function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0});const si_funciona_1=__importDefault(require("si-funciona")),getAssignedStyles_1=__importDefault(require("./getAssignedStyles")),checkStyles=(e,t={})=>{const s=e.attributes.style??{};return si_funciona_1.default.emptyObject(s)?1:si_funciona_1.default.compareArrays(Object.keys((0,getAssignedStyles_1.default)(t)).map(si_funciona_1.default.camelCase),Object.keys(s))},checkClasses=(e,t="")=>{const s=e.attributes.className??"";return s.length?si_funciona_1.default.compareArrays(t.split(" "),s.split(" ")):1},domItemHasAttribute=(e,t,s)=>{if("style"===t)return checkStyles(e,s);if("className"===t)return checkClasses(e,s);const a=si_funciona_1.default.camelCase(t);return void 0===e.attributes[a]?1:e.attributes[a]===s?0:1};exports.default=domItemHasAttribute;
@@ -0,0 +1,10 @@
1
+ import type { DomItem } from '../domItem/types';
2
+ import type { ChangeList } from './types';
3
+ /**
4
+ * Given a domGeneral.DomItem as config, this function will return the changes from the element
5
+ * to be applied to the domItem.
6
+ * @param domItem - The DomItem having the element which changes to be applied to the config
7
+ * element
8
+ */
9
+ declare const elementChanges: (domItem: DomItem) => ChangeList;
10
+ export default elementChanges;
@@ -0,0 +1,151 @@
1
+ "use strict";
2
+
3
+ /* This Source Code Form is subject to the terms of the Mozilla Public
4
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
5
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
6
+ var __importDefault = void 0 && (void 0).__importDefault || function (mod) {
7
+ return mod && mod.__esModule ? mod : {
8
+ "default": mod
9
+ };
10
+ };
11
+ Object.defineProperty(exports, "__esModule", {
12
+ value: true
13
+ });
14
+ const si_funciona_1 = __importDefault(require("si-funciona"));
15
+ const domItemHasAttribute_1 = __importDefault(require("./domItemHasAttribute"));
16
+ const createChangeList_1 = __importDefault(require("./createChangeList"));
17
+ /**
18
+ * Given some config, provide a function to testing attribute and key existence in that config.
19
+ * @param domItem
20
+ */
21
+ const checkAttribute = domItem => (attr, key) => {
22
+ if (key === 'className') {
23
+ const diff = (0, domItemHasAttribute_1.default)(domItem, key, attr);
24
+ if (Array.isArray(diff) && diff.length === 1 && diff[0].result[0] === 0) {
25
+ return 0;
26
+ }
27
+ return si_funciona_1.default.filterObject(diff, arrayDiff => arrayDiff.result[0] !== 0);
28
+ }
29
+ if (key === 'style') {
30
+ const diff = (0, domItemHasAttribute_1.default)(domItem, key, attr);
31
+ const styles = attr;
32
+ const itemStyle = () => domItem.attributes.style;
33
+ if (Array.isArray(diff) && diff.length === 1 && diff[0].result[0] === 0 && itemStyle()[diff[0].value] === styles[diff[0].value]) {
34
+ return 0;
35
+ }
36
+ return si_funciona_1.default.filterObject(diff, arrayDiff => arrayDiff.result[0] !== 0 || itemStyle()[arrayDiff.value] !== styles[arrayDiff.value]);
37
+ }
38
+ return (0, domItemHasAttribute_1.default)(domItem, key, attr);
39
+ };
40
+ /**
41
+ * Updates all the keys to be camelCase
42
+ * @param domItem
43
+ */
44
+ const camelCaseAttributes = domItem => domItem.element ? si_funciona_1.default.reduceObject(domItem.element.attributes, (attributes, attr) => {
45
+ if (!attr.name) {
46
+ return attributes;
47
+ }
48
+ const camelKey = attr.name === 'class' ? 'className' : si_funciona_1.default.camelCase(attr.name);
49
+ const attributeValue = domItem.element[attr.name] ?? attr.value;
50
+ if (typeof attributeValue === 'undefined') {
51
+ return attributes;
52
+ }
53
+ attributes[camelKey] = attributeValue;
54
+ return attributes;
55
+ }, {}) : {};
56
+ /**
57
+ * Given a domGeneral.DomItem as config, this function will return the changes from the element
58
+ * to be applied to the domItem.
59
+ * @param domItem - The DomItem having the element which changes to be applied to the config
60
+ * element
61
+ */
62
+ const elementChanges = domItem => {
63
+ const changeList = (0, createChangeList_1.default)();
64
+ if (!domItem.element) {
65
+ changeList.removed.nodeName = domItem.nodeName.toLowerCase();
66
+ }
67
+ if (domItem.element && domItem.element.nodeName.toLowerCase() !== domItem.nodeName.toLowerCase()) {
68
+ changeList.removed.nodeName = domItem.nodeName.toLowerCase();
69
+ changeList.added.nodeName = domItem.element.nodeName.toLowerCase();
70
+ }
71
+ if (!domItem.element && domItem.nodeValue !== null) {
72
+ changeList.removed.nodeValue = domItem.nodeValue;
73
+ if (!si_funciona_1.default.emptyObject(domItem.attributes)) {
74
+ changeList.removed = changeList.appendChanges('removed', si_funciona_1.default.dotNotate({
75
+ attributes: domItem.attributes
76
+ }));
77
+ }
78
+ return changeList;
79
+ }
80
+ if (domItem.element && !(domItem.element instanceof Element)) {
81
+ if (domItem.element.nodeValue !== domItem.nodeValue) {
82
+ changeList.added.nodeValue = domItem.element.nodeValue;
83
+ }
84
+ if (!si_funciona_1.default.emptyObject(domItem.attributes)) {
85
+ changeList.removed = changeList.appendChanges('removed', si_funciona_1.default.dotNotate({
86
+ attributes: domItem.attributes
87
+ }));
88
+ }
89
+ return changeList;
90
+ }
91
+ if (!(domItem.element && domItem.element.hasAttributes()) && !si_funciona_1.default.emptyObject(domItem.attributes)) {
92
+ changeList.removed = changeList.appendChanges('removed', si_funciona_1.default.dotNotate({
93
+ attributes: domItem.attributes
94
+ }));
95
+ return changeList;
96
+ }
97
+ const elementAttributes = camelCaseAttributes(domItem);
98
+ const diffMap = si_funciona_1.default.mapObject(elementAttributes, (attr, key) => checkAttribute(domItem)(attr, key));
99
+ return si_funciona_1.default.reduceObject(diffMap, (changed, result, key) => {
100
+ const isArray = Array.isArray(result);
101
+ if (!isArray && !result) {
102
+ // Skip if the attribute is not changed (false and not an array)
103
+ return changed;
104
+ }
105
+ if (!isArray) {
106
+ // Not an array, simply set the attribute as added
107
+ changed.added[`attributes.${key}`] = domItem.element[key] ?? domItem.element.getAttribute(si_funciona_1.default.kabobCase(key));
108
+ return changed;
109
+ }
110
+ if (key !== 'className' && key !== 'style') {
111
+ // Is an array, but not class or style; we don't know what this is, so we skip it.
112
+ return changed;
113
+ }
114
+ if (key === 'className') {
115
+ changed.removed = result.reduce((removed, results) => {
116
+ if (results.result[0] === -1) {
117
+ removed[`attributes.className.${results.keys[1]}`] = results.value;
118
+ }
119
+ return removed;
120
+ }, changed.removed);
121
+ changed.added = result.reduce((added, results) => {
122
+ if (results.result[0] === 1) {
123
+ added[`attributes.className.${results.keys[0]}`] = results.value;
124
+ }
125
+ return added;
126
+ }, changed.added);
127
+ return changed;
128
+ }
129
+ const itemStyle = () => domItem.attributes.style;
130
+ changed.removed = result.reduce((removed, results) => {
131
+ if (results.result[0] === -1) {
132
+ removed[`attributes.style.${results.value}`] = itemStyle()[results.value];
133
+ }
134
+ if (results.result[0] === 0 && itemStyle()[results.value] !== elementAttributes.style[results.value]) {
135
+ removed[`attributes.style.${results.value}`] = itemStyle()[results.value];
136
+ }
137
+ return removed;
138
+ }, changed.removed);
139
+ changed.added = result.reduce((added, results) => {
140
+ if (results.result[0] === 1) {
141
+ added[`attributes.style.${results.value}`] = elementAttributes.style[results.value];
142
+ }
143
+ if (results.result[0] === 0 && itemStyle()[results.value] !== elementAttributes.style[results.value]) {
144
+ added[`attributes.style.${results.value}`] = elementAttributes.style[results.value];
145
+ }
146
+ return added;
147
+ }, changed.added);
148
+ return changed;
149
+ }, changeList);
150
+ };
151
+ exports.default = elementChanges;
@@ -0,0 +1 @@
1
+ "use strict";var __importDefault=function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0});const si_funciona_1=__importDefault(require("si-funciona")),domItemHasAttribute_1=__importDefault(require("./domItemHasAttribute")),createChangeList_1=__importDefault(require("./createChangeList")),checkAttribute=e=>(t,a)=>{if("className"===a){const u=(0,domItemHasAttribute_1.default)(e,a,t);return Array.isArray(u)&&1===u.length&&0===u[0].result[0]?0:si_funciona_1.default.filterObject(u,e=>0!==e.result[0])}if("style"===a){const u=(0,domItemHasAttribute_1.default)(e,a,t),r=t,s=()=>e.attributes.style;return Array.isArray(u)&&1===u.length&&0===u[0].result[0]&&s()[u[0].value]===r[u[0].value]?0:si_funciona_1.default.filterObject(u,e=>0!==e.result[0]||s()[e.value]!==r[e.value])}return(0,domItemHasAttribute_1.default)(e,a,t)},camelCaseAttributes=e=>e.element?si_funciona_1.default.reduceObject(e.element.attributes,(t,a)=>{if(!a.name)return t;const u="class"===a.name?"className":si_funciona_1.default.camelCase(a.name),r=e.element[a.name]??a.value;return void 0===r||(t[u]=r),t},{}):{},elementChanges=e=>{const t=(0,createChangeList_1.default)();if(e.element||(t.removed.nodeName=e.nodeName.toLowerCase()),e.element&&e.element.nodeName.toLowerCase()!==e.nodeName.toLowerCase()&&(t.removed.nodeName=e.nodeName.toLowerCase(),t.added.nodeName=e.element.nodeName.toLowerCase()),!e.element&&null!==e.nodeValue)return t.removed.nodeValue=e.nodeValue,si_funciona_1.default.emptyObject(e.attributes)||(t.removed=t.appendChanges("removed",si_funciona_1.default.dotNotate({attributes:e.attributes}))),t;if(e.element&&!(e.element instanceof Element))return e.element.nodeValue!==e.nodeValue&&(t.added.nodeValue=e.element.nodeValue),si_funciona_1.default.emptyObject(e.attributes)||(t.removed=t.appendChanges("removed",si_funciona_1.default.dotNotate({attributes:e.attributes}))),t;if(!(e.element&&e.element.hasAttributes()||si_funciona_1.default.emptyObject(e.attributes)))return t.removed=t.appendChanges("removed",si_funciona_1.default.dotNotate({attributes:e.attributes})),t;const a=camelCaseAttributes(e),u=si_funciona_1.default.mapObject(a,(t,a)=>checkAttribute(e)(t,a));return si_funciona_1.default.reduceObject(u,(t,u,r)=>{const s=Array.isArray(u);if(!s&&!u)return t;if(!s)return t.added[`attributes.${r}`]=e.element[r]??e.element.getAttribute(si_funciona_1.default.kabobCase(r)),t;if("className"!==r&&"style"!==r)return t;if("className"===r)return t.removed=u.reduce((e,t)=>(-1===t.result[0]&&(e[`attributes.className.${t.keys[1]}`]=t.value),e),t.removed),t.added=u.reduce((e,t)=>(1===t.result[0]&&(e[`attributes.className.${t.keys[0]}`]=t.value),e),t.added),t;const n=()=>e.attributes.style;return t.removed=u.reduce((e,t)=>(-1===t.result[0]&&(e[`attributes.style.${t.value}`]=n()[t.value]),0===t.result[0]&&n()[t.value]!==a.style[t.value]&&(e[`attributes.style.${t.value}`]=n()[t.value]),e),t.removed),t.added=u.reduce((e,t)=>(1===t.result[0]&&(e[`attributes.style.${t.value}`]=a.style[t.value]),0===t.result[0]&&n()[t.value]!==a.style[t.value]&&(e[`attributes.style.${t.value}`]=a.style[t.value]),e),t.added),t},t)};exports.default=elementChanges;
@@ -0,0 +1,10 @@
1
+ import type { AttributeComparison } from './types';
2
+ /**
3
+ * Check if the provided Element has the provided attributes.
4
+ * Returns a boolean, or an array of 1 / 0 / -1 based on the comparison status.
5
+ * @param element - Receive the element to be assessed
6
+ * @param key - The attribute name to search for
7
+ * @param attr - The expected value of the attribute to compare against
8
+ */
9
+ declare const elementHasAttribute: (element: HTMLElement | null | undefined, key: string, attr: unknown) => AttributeComparison;
10
+ export default elementHasAttribute;