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.
- package/LICENSE +373 -0
- package/README.md +91 -2
- package/browser/treeloom.js +11232 -0
- package/browser/treeloom.min.js +1 -0
- package/browser/treeloomRenderOnly.js +11115 -0
- package/browser/treeloomRenderOnly.min.js +1 -0
- package/dist/deflate/domItemToJson.d.ts +14 -0
- package/dist/deflate/domItemToJson.js +43 -0
- package/dist/deflate/domItemToJson.min.js +1 -0
- package/dist/deflate/index.d.ts +7 -0
- package/dist/deflate/index.js +19 -0
- package/dist/deflate/index.min.js +1 -0
- package/dist/deflate/removeEmptyProperties.d.ts +8 -0
- package/dist/deflate/removeEmptyProperties.js +43 -0
- package/dist/deflate/removeEmptyProperties.min.js +1 -0
- package/dist/diff/appliedSnapshot.d.ts +34 -0
- package/dist/diff/appliedSnapshot.js +134 -0
- package/dist/diff/appliedSnapshot.min.js +1 -0
- package/dist/diff/createChangeList.d.ts +9 -0
- package/dist/diff/createChangeList.js +44 -0
- package/dist/diff/createChangeList.min.js +1 -0
- package/dist/diff/domItemChanges.d.ts +9 -0
- package/dist/diff/domItemChanges.js +167 -0
- package/dist/diff/domItemChanges.min.js +1 -0
- package/dist/diff/domItemHasAttribute.d.ts +11 -0
- package/dist/diff/domItemHasAttribute.js +63 -0
- package/dist/diff/domItemHasAttribute.min.js +1 -0
- package/dist/diff/elementChanges.d.ts +10 -0
- package/dist/diff/elementChanges.js +151 -0
- package/dist/diff/elementChanges.min.js +1 -0
- package/dist/diff/elementHasAttribute.d.ts +10 -0
- package/dist/diff/elementHasAttribute.js +70 -0
- package/dist/diff/elementHasAttribute.min.js +1 -0
- package/dist/diff/getAssignedStyles.d.ts +9 -0
- package/dist/diff/getAssignedStyles.js +22 -0
- package/dist/diff/getAssignedStyles.min.js +1 -0
- package/dist/diff/index.d.ts +9 -0
- package/dist/diff/index.js +27 -0
- package/dist/diff/index.min.js +1 -0
- package/dist/diff/types.d.ts +17 -0
- package/dist/diff/types.js +8 -0
- package/dist/diff/types.min.js +1 -0
- package/dist/domItem/index.d.ts +34 -0
- package/dist/domItem/index.js +81 -0
- package/dist/domItem/index.min.js +1 -0
- package/dist/domItem/objects/addDomItemProperties.d.ts +7 -0
- package/dist/domItem/objects/addDomItemProperties.js +27 -0
- package/dist/domItem/objects/addDomItemProperties.min.js +1 -0
- package/dist/domItem/objects/createCoreItem.d.ts +9 -0
- package/dist/domItem/objects/createCoreItem.js +53 -0
- package/dist/domItem/objects/createCoreItem.min.js +1 -0
- package/dist/domItem/objects/createDomItem.d.ts +10 -0
- package/dist/domItem/objects/createDomItem.js +40 -0
- package/dist/domItem/objects/createDomItem.min.js +1 -0
- package/dist/domItem/objects/documentDomItem.d.ts +12 -0
- package/dist/domItem/objects/documentDomItem.js +36 -0
- package/dist/domItem/objects/documentDomItem.min.js +1 -0
- package/dist/domItem/objects/documentItem.d.ts +18 -0
- package/dist/domItem/objects/documentItem.js +40 -0
- package/dist/domItem/objects/documentItem.min.js +1 -0
- package/dist/domItem/objects/initChildren.d.ts +6 -0
- package/dist/domItem/objects/initChildren.js +44 -0
- package/dist/domItem/objects/initChildren.min.js +1 -0
- package/dist/domItem/objects/initRoot.d.ts +9 -0
- package/dist/domItem/objects/initRoot.js +32 -0
- package/dist/domItem/objects/initRoot.min.js +1 -0
- package/dist/domItem/query/gatherChildItems.d.ts +12 -0
- package/dist/domItem/query/gatherChildItems.js +19 -0
- package/dist/domItem/query/gatherChildItems.min.js +1 -0
- package/dist/domItem/query/getChildTest.d.ts +8 -0
- package/dist/domItem/query/getChildTest.js +15 -0
- package/dist/domItem/query/getChildTest.min.js +1 -0
- package/dist/domItem/query/getChildrenByClass.d.ts +11 -0
- package/dist/domItem/query/getChildrenByClass.js +26 -0
- package/dist/domItem/query/getChildrenByClass.min.js +1 -0
- package/dist/domItem/query/getChildrenByName.d.ts +9 -0
- package/dist/domItem/query/getChildrenByName.js +23 -0
- package/dist/domItem/query/getChildrenByName.min.js +1 -0
- package/dist/domItem/query/getChildrenFromAttribute.d.ts +13 -0
- package/dist/domItem/query/getChildrenFromAttribute.js +28 -0
- package/dist/domItem/query/getChildrenFromAttribute.min.js +1 -0
- package/dist/domItem/query/getItemByElement.d.ts +11 -0
- package/dist/domItem/query/getItemByElement.js +29 -0
- package/dist/domItem/query/getItemByElement.min.js +1 -0
- package/dist/domItem/query/getParentsByClass.d.ts +12 -0
- package/dist/domItem/query/getParentsByClass.js +40 -0
- package/dist/domItem/query/getParentsByClass.min.js +1 -0
- package/dist/domItem/query/getParentsByName.d.ts +9 -0
- package/dist/domItem/query/getParentsByName.js +23 -0
- package/dist/domItem/query/getParentsByName.min.js +1 -0
- package/dist/domItem/query/getParentsByTagName.d.ts +9 -0
- package/dist/domItem/query/getParentsByTagName.js +23 -0
- package/dist/domItem/query/getParentsByTagName.min.js +1 -0
- package/dist/domItem/query/getParentsFromAttribute.d.ts +13 -0
- package/dist/domItem/query/getParentsFromAttribute.js +39 -0
- package/dist/domItem/query/getParentsFromAttribute.min.js +1 -0
- package/dist/domItem/traits/defineTrait.d.ts +10 -0
- package/dist/domItem/traits/defineTrait.js +26 -0
- package/dist/domItem/traits/defineTrait.min.js +1 -0
- package/dist/domItem/traits/definitions.d.ts +7 -0
- package/dist/domItem/traits/definitions.js +20 -0
- package/dist/domItem/traits/definitions.min.js +1 -0
- package/dist/domItem/traits/getNonSerializableKeys.d.ts +9 -0
- package/dist/domItem/traits/getNonSerializableKeys.js +25 -0
- package/dist/domItem/traits/getNonSerializableKeys.min.js +1 -0
- package/dist/domItem/traits/getTraitDefinition.d.ts +7 -0
- package/dist/domItem/traits/getTraitDefinition.js +20 -0
- package/dist/domItem/traits/getTraitDefinition.min.js +1 -0
- package/dist/domItem/traits/hasTrait.d.ts +8 -0
- package/dist/domItem/traits/hasTrait.js +15 -0
- package/dist/domItem/traits/hasTrait.min.js +1 -0
- package/dist/domItem/traits/hasTraits.d.ts +9 -0
- package/dist/domItem/traits/hasTraits.js +16 -0
- package/dist/domItem/traits/hasTraits.min.js +1 -0
- package/dist/domItem/traits/isDomItem.d.ts +8 -0
- package/dist/domItem/traits/isDomItem.js +21 -0
- package/dist/domItem/traits/isDomItem.min.js +1 -0
- package/dist/domItem/traits/withTrait.d.ts +11 -0
- package/dist/domItem/traits/withTrait.js +30 -0
- package/dist/domItem/traits/withTrait.min.js +1 -0
- package/dist/domItem/tree/appendChild.d.ts +8 -0
- package/dist/domItem/tree/appendChild.js +19 -0
- package/dist/domItem/tree/appendChild.min.js +1 -0
- package/dist/domItem/tree/getItemByPath.d.ts +10 -0
- package/dist/domItem/tree/getItemByPath.js +23 -0
- package/dist/domItem/tree/getItemByPath.min.js +1 -0
- package/dist/domItem/tree/getItemPath.d.ts +9 -0
- package/dist/domItem/tree/getItemPath.js +31 -0
- package/dist/domItem/tree/getItemPath.min.js +1 -0
- package/dist/domItem/tree/getTopParentItem.d.ts +8 -0
- package/dist/domItem/tree/getTopParentItem.js +29 -0
- package/dist/domItem/tree/getTopParentItem.min.js +1 -0
- package/dist/domItem/tree/insertChild.d.ts +11 -0
- package/dist/domItem/tree/insertChild.js +22 -0
- package/dist/domItem/tree/insertChild.min.js +1 -0
- package/dist/domItem/tree/itemIdIndex.d.ts +43 -0
- package/dist/domItem/tree/itemIdIndex.js +118 -0
- package/dist/domItem/tree/itemIdIndex.min.js +1 -0
- package/dist/domItem/tree/removeChild.d.ts +8 -0
- package/dist/domItem/tree/removeChild.js +21 -0
- package/dist/domItem/tree/removeChild.min.js +1 -0
- package/dist/domItem/tree/setParentItemReferences.d.ts +7 -0
- package/dist/domItem/tree/setParentItemReferences.js +24 -0
- package/dist/domItem/tree/setParentItemReferences.min.js +1 -0
- package/dist/domItem/types.d.ts +131 -0
- package/dist/domItem/types.js +8 -0
- package/dist/domItem/types.min.js +1 -0
- package/dist/events/functions/activateListener.d.ts +10 -0
- package/dist/events/functions/activateListener.js +45 -0
- package/dist/events/functions/activateListener.min.js +1 -0
- package/dist/events/functions/addEventListener.d.ts +23 -0
- package/dist/events/functions/addEventListener.js +54 -0
- package/dist/events/functions/addEventListener.min.js +1 -0
- package/dist/events/functions/applyActiveListeners.d.ts +9 -0
- package/dist/events/functions/applyActiveListeners.js +52 -0
- package/dist/events/functions/applyActiveListeners.min.js +1 -0
- package/dist/events/functions/assignListener.d.ts +12 -0
- package/dist/events/functions/assignListener.js +39 -0
- package/dist/events/functions/assignListener.min.js +1 -0
- package/dist/events/functions/bindAllListeners.d.ts +10 -0
- package/dist/events/functions/bindAllListeners.js +28 -0
- package/dist/events/functions/bindAllListeners.min.js +1 -0
- package/dist/events/functions/bindElementListeners.d.ts +7 -0
- package/dist/events/functions/bindElementListeners.js +34 -0
- package/dist/events/functions/bindElementListeners.min.js +1 -0
- package/dist/events/functions/bindListeners.d.ts +9 -0
- package/dist/events/functions/bindListeners.js +23 -0
- package/dist/events/functions/bindListeners.min.js +1 -0
- package/dist/events/functions/deactivateListener.d.ts +13 -0
- package/dist/events/functions/deactivateListener.js +58 -0
- package/dist/events/functions/deactivateListener.min.js +1 -0
- package/dist/events/functions/deactivateListeners.d.ts +7 -0
- package/dist/events/functions/deactivateListeners.js +22 -0
- package/dist/events/functions/deactivateListeners.min.js +1 -0
- package/dist/events/functions/findEventListener.d.ts +22 -0
- package/dist/events/functions/findEventListener.js +61 -0
- package/dist/events/functions/findEventListener.min.js +1 -0
- package/dist/events/functions/fullAddEventListener.d.ts +20 -0
- package/dist/events/functions/fullAddEventListener.js +45 -0
- package/dist/events/functions/fullAddEventListener.min.js +1 -0
- package/dist/events/functions/fullRemoveEventListener.d.ts +22 -0
- package/dist/events/functions/fullRemoveEventListener.js +37 -0
- package/dist/events/functions/fullRemoveEventListener.min.js +1 -0
- package/dist/events/functions/listenerOptions.d.ts +12 -0
- package/dist/events/functions/listenerOptions.js +31 -0
- package/dist/events/functions/listenerOptions.min.js +1 -0
- package/dist/events/functions/makeEventHandler.d.ts +10 -0
- package/dist/events/functions/makeEventHandler.js +23 -0
- package/dist/events/functions/makeEventHandler.min.js +1 -0
- package/dist/events/functions/makeForwardingListener.d.ts +11 -0
- package/dist/events/functions/makeForwardingListener.js +46 -0
- package/dist/events/functions/makeForwardingListener.min.js +1 -0
- package/dist/events/functions/receiveForwardedEvent.d.ts +23 -0
- package/dist/events/functions/receiveForwardedEvent.js +40 -0
- package/dist/events/functions/receiveForwardedEvent.min.js +1 -0
- package/dist/events/functions/registerListener.d.ts +11 -0
- package/dist/events/functions/registerListener.js +25 -0
- package/dist/events/functions/registerListener.min.js +1 -0
- package/dist/events/functions/registerListeners.d.ts +10 -0
- package/dist/events/functions/registerListeners.js +26 -0
- package/dist/events/functions/registerListeners.min.js +1 -0
- package/dist/events/functions/removeEventListener.d.ts +18 -0
- package/dist/events/functions/removeEventListener.js +42 -0
- package/dist/events/functions/removeEventListener.min.js +1 -0
- package/dist/events/functions/retrieveListener.d.ts +14 -0
- package/dist/events/functions/retrieveListener.js +39 -0
- package/dist/events/functions/retrieveListener.min.js +1 -0
- package/dist/events/functions/revokeActiveListeners.d.ts +12 -0
- package/dist/events/functions/revokeActiveListeners.js +54 -0
- package/dist/events/functions/revokeActiveListeners.min.js +1 -0
- package/dist/events/functions/setForwardEvents.d.ts +11 -0
- package/dist/events/functions/setForwardEvents.js +26 -0
- package/dist/events/functions/setForwardEvents.min.js +1 -0
- package/dist/events/functions/unassignListener.d.ts +12 -0
- package/dist/events/functions/unassignListener.js +32 -0
- package/dist/events/functions/unassignListener.min.js +1 -0
- package/dist/events/index.d.ts +37 -0
- package/dist/events/index.js +72 -0
- package/dist/events/index.min.js +1 -0
- package/dist/events/objects/createEventListener.d.ts +13 -0
- package/dist/events/objects/createEventListener.js +30 -0
- package/dist/events/objects/createEventListener.min.js +1 -0
- package/dist/events/objects/createEventProxy.d.ts +10 -0
- package/dist/events/objects/createEventProxy.js +48 -0
- package/dist/events/objects/createEventProxy.min.js +1 -0
- package/dist/events/objects/createEventResponder.d.ts +8 -0
- package/dist/events/objects/createEventResponder.js +27 -0
- package/dist/events/objects/createEventResponder.min.js +1 -0
- package/dist/events/objects/options/getListenerOptions.d.ts +6 -0
- package/dist/events/objects/options/getListenerOptions.js +22 -0
- package/dist/events/objects/options/getListenerOptions.min.js +1 -0
- package/dist/events/objects/options/numberToOptions.d.ts +8 -0
- package/dist/events/objects/options/numberToOptions.js +21 -0
- package/dist/events/objects/options/numberToOptions.min.js +1 -0
- package/dist/events/objects/options/optionsToNumber.d.ts +9 -0
- package/dist/events/objects/options/optionsToNumber.js +27 -0
- package/dist/events/objects/options/optionsToNumber.min.js +1 -0
- package/dist/events/objects/options.d.ts +6 -0
- package/dist/events/objects/options.js +24 -0
- package/dist/events/objects/options.min.js +1 -0
- package/dist/events/types.d.ts +87 -0
- package/dist/events/types.js +8 -0
- package/dist/events/types.min.js +1 -0
- package/dist/inflate/index.d.ts +4 -0
- package/dist/inflate/index.js +17 -0
- package/dist/inflate/index.min.js +1 -0
- package/dist/inflate/jsonToDomItem.d.ts +7 -0
- package/dist/inflate/jsonToDomItem.js +30 -0
- package/dist/inflate/jsonToDomItem.min.js +1 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.js +24 -0
- package/dist/main.min.js +1 -0
- package/dist/render/generateElement.d.ts +7 -0
- package/dist/render/generateElement.js +41 -0
- package/dist/render/generateElement.min.js +1 -0
- package/dist/render/index.d.ts +9 -0
- package/dist/render/index.js +27 -0
- package/dist/render/index.min.js +1 -0
- package/dist/render/reconcile.d.ts +16 -0
- package/dist/render/reconcile.js +169 -0
- package/dist/render/reconcile.min.js +1 -0
- package/dist/render/renderHtml.d.ts +16 -0
- package/dist/render/renderHtml.js +57 -0
- package/dist/render/renderHtml.min.js +1 -0
- package/dist/render/updateChildNodes.d.ts +7 -0
- package/dist/render/updateChildNodes.js +53 -0
- package/dist/render/updateChildNodes.min.js +1 -0
- package/dist/render/updateElement.d.ts +14 -0
- package/dist/render/updateElement.js +113 -0
- package/dist/render/updateElement.min.js +1 -0
- package/dist/render/updateElements.d.ts +9 -0
- package/dist/render/updateElements.js +33 -0
- package/dist/render/updateElements.min.js +1 -0
- package/dist/renderOnly.d.ts +2 -0
- package/dist/renderOnly.js +27 -0
- package/dist/renderOnly.min.js +1 -0
- package/dist/sync/index.d.ts +6 -0
- package/dist/sync/index.js +21 -0
- package/dist/sync/index.min.js +1 -0
- package/dist/sync/updateChildren.d.ts +7 -0
- package/dist/sync/updateChildren.js +38 -0
- package/dist/sync/updateChildren.min.js +1 -0
- package/dist/sync/updateDomItem.d.ts +8 -0
- package/dist/sync/updateDomItem.js +53 -0
- package/dist/sync/updateDomItem.min.js +1 -0
- package/dist/sync/updateDomItems.d.ts +9 -0
- package/dist/sync/updateDomItems.js +33 -0
- package/dist/sync/updateDomItems.min.js +1 -0
- 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;
|