@bpmn-io/properties-panel 0.9.0 → 0.10.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/CHANGELOG.md +11 -0
- package/dist/index.esm.js +1607 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +1648 -0
- package/dist/index.js.map +1 -0
- package/package.json +16 -7
- package/preact/LICENSE +21 -0
- package/preact/README.md +185 -0
- package/preact/compat/dist/compat.js +2 -0
- package/preact/compat/dist/compat.js.map +1 -0
- package/preact/compat/dist/compat.mjs +2 -0
- package/preact/compat/dist/compat.module.js +2 -0
- package/preact/compat/dist/compat.module.js.map +1 -0
- package/preact/compat/dist/compat.umd.js +2 -0
- package/preact/compat/dist/compat.umd.js.map +1 -0
- package/preact/compat/jsx-dev-runtime.js +1 -0
- package/preact/compat/jsx-dev-runtime.mjs +1 -0
- package/preact/compat/jsx-runtime.js +1 -0
- package/preact/compat/jsx-runtime.mjs +1 -0
- package/preact/compat/package.json +19 -0
- package/preact/compat/server.js +15 -0
- package/preact/compat/server.mjs +4 -0
- package/preact/compat/src/Children.js +21 -0
- package/preact/compat/src/PureComponent.js +15 -0
- package/preact/compat/src/forwardRef.js +51 -0
- package/preact/compat/src/index.d.ts +140 -0
- package/preact/compat/src/index.js +175 -0
- package/preact/compat/src/internal.d.ts +47 -0
- package/preact/compat/src/memo.js +34 -0
- package/preact/compat/src/portals.js +80 -0
- package/preact/compat/src/render.js +219 -0
- package/preact/compat/src/scheduler.js +24 -0
- package/preact/compat/src/suspense-list.d.ts +14 -0
- package/preact/compat/src/suspense-list.js +126 -0
- package/preact/compat/src/suspense.d.ts +15 -0
- package/preact/compat/src/suspense.js +270 -0
- package/preact/compat/src/util.js +28 -0
- package/preact/compat/test-utils.js +1 -0
- package/preact/debug/dist/debug.js +2 -0
- package/preact/debug/dist/debug.js.map +1 -0
- package/preact/debug/dist/debug.mjs +2 -0
- package/preact/debug/dist/debug.module.js +2 -0
- package/preact/debug/dist/debug.module.js.map +1 -0
- package/preact/debug/dist/debug.umd.js +2 -0
- package/preact/debug/dist/debug.umd.js.map +1 -0
- package/preact/debug/package.json +18 -0
- package/preact/debug/src/check-props.js +54 -0
- package/preact/debug/src/component-stack.js +146 -0
- package/preact/debug/src/constants.js +3 -0
- package/preact/debug/src/debug.js +442 -0
- package/preact/debug/src/index.js +6 -0
- package/preact/debug/src/internal.d.ts +82 -0
- package/preact/debug/src/util.js +11 -0
- package/preact/devtools/dist/devtools.js +2 -0
- package/preact/devtools/dist/devtools.js.map +1 -0
- package/preact/devtools/dist/devtools.mjs +2 -0
- package/preact/devtools/dist/devtools.module.js +2 -0
- package/preact/devtools/dist/devtools.module.js.map +1 -0
- package/preact/devtools/dist/devtools.umd.js +2 -0
- package/preact/devtools/dist/devtools.umd.js.map +1 -0
- package/preact/devtools/package.json +16 -0
- package/preact/devtools/src/devtools.js +10 -0
- package/preact/devtools/src/index.d.ts +8 -0
- package/preact/devtools/src/index.js +15 -0
- package/preact/dist/preact.js +2 -0
- package/preact/dist/preact.js.map +1 -0
- package/preact/dist/preact.min.js +2 -0
- package/preact/dist/preact.min.js.map +1 -0
- package/preact/dist/preact.mjs +2 -0
- package/preact/dist/preact.module.js +2 -0
- package/preact/dist/preact.module.js.map +1 -0
- package/preact/dist/preact.umd.js +2 -0
- package/preact/dist/preact.umd.js.map +1 -0
- package/preact/hooks/dist/hooks.js +2 -0
- package/preact/hooks/dist/hooks.js.map +1 -0
- package/preact/hooks/dist/hooks.mjs +2 -0
- package/preact/hooks/dist/hooks.module.js +2 -0
- package/preact/hooks/dist/hooks.module.js.map +1 -0
- package/preact/hooks/dist/hooks.umd.js +2 -0
- package/preact/hooks/dist/hooks.umd.js.map +1 -0
- package/preact/hooks/package.json +26 -0
- package/preact/hooks/src/index.d.ts +130 -0
- package/preact/hooks/src/index.js +386 -0
- package/preact/hooks/src/internal.d.ts +75 -0
- package/preact/jsx-runtime/dist/jsxRuntime.js +2 -0
- package/preact/jsx-runtime/dist/jsxRuntime.js.map +1 -0
- package/preact/jsx-runtime/dist/jsxRuntime.mjs +2 -0
- package/preact/jsx-runtime/dist/jsxRuntime.module.js +2 -0
- package/preact/jsx-runtime/dist/jsxRuntime.module.js.map +1 -0
- package/preact/jsx-runtime/dist/jsxRuntime.umd.js +2 -0
- package/preact/jsx-runtime/dist/jsxRuntime.umd.js.map +1 -0
- package/preact/jsx-runtime/package.json +19 -0
- package/preact/jsx-runtime/src/index.d.ts +50 -0
- package/preact/jsx-runtime/src/index.js +72 -0
- package/preact/package.json +268 -0
- package/preact/src/cjs.js +3 -0
- package/preact/src/clone-element.js +39 -0
- package/preact/src/component.js +225 -0
- package/preact/src/constants.js +3 -0
- package/preact/src/create-context.js +68 -0
- package/preact/src/create-element.js +100 -0
- package/preact/src/diff/catch-error.js +38 -0
- package/preact/src/diff/children.js +347 -0
- package/preact/src/diff/index.js +516 -0
- package/preact/src/diff/props.js +158 -0
- package/preact/src/index.d.ts +310 -0
- package/preact/src/index.js +13 -0
- package/preact/src/internal.d.ts +147 -0
- package/preact/src/jsx.d.ts +955 -0
- package/preact/src/options.js +17 -0
- package/preact/src/render.js +74 -0
- package/preact/src/util.js +23 -0
- package/preact/test-utils/dist/testUtils.js +2 -0
- package/preact/test-utils/dist/testUtils.js.map +1 -0
- package/preact/test-utils/dist/testUtils.mjs +2 -0
- package/preact/test-utils/dist/testUtils.module.js +2 -0
- package/preact/test-utils/dist/testUtils.module.js.map +1 -0
- package/preact/test-utils/dist/testUtils.umd.js +2 -0
- package/preact/test-utils/dist/testUtils.umd.js.map +1 -0
- package/preact/test-utils/package.json +19 -0
- package/preact/test-utils/src/index.d.ts +3 -0
- package/preact/test-utils/src/index.js +117 -0
- package/lib/PropertiesPanel.js +0 -166
- package/lib/PropertiesPanel.js.map +0 -1
- package/lib/components/DropdownButton.js +0 -109
- package/lib/components/DropdownButton.js.map +0 -1
- package/lib/components/Group.js +0 -75
- package/lib/components/Group.js.map +0 -1
- package/lib/components/Header.js +0 -49
- package/lib/components/Header.js.map +0 -1
- package/lib/components/HeaderButton.js +0 -16
- package/lib/components/HeaderButton.js.map +0 -1
- package/lib/components/ListGroup.js +0 -167
- package/lib/components/ListGroup.js.map +0 -1
- package/lib/components/ListItem.js +0 -37
- package/lib/components/ListItem.js.map +0 -1
- package/lib/components/entries/Checkbox.js +0 -83
- package/lib/components/entries/Checkbox.js.map +0 -1
- package/lib/components/entries/Collapsible.js +0 -48
- package/lib/components/entries/Collapsible.js.map +0 -1
- package/lib/components/entries/Description.js +0 -26
- package/lib/components/entries/Description.js.map +0 -1
- package/lib/components/entries/List.js +0 -204
- package/lib/components/entries/List.js.map +0 -1
- package/lib/components/entries/NumberField.js +0 -110
- package/lib/components/entries/NumberField.js.map +0 -1
- package/lib/components/entries/Select.js +0 -110
- package/lib/components/entries/Select.js.map +0 -1
- package/lib/components/entries/Simple.js +0 -56
- package/lib/components/entries/Simple.js.map +0 -1
- package/lib/components/entries/TextArea.js +0 -98
- package/lib/components/entries/TextArea.js.map +0 -1
- package/lib/components/entries/TextField.js +0 -123
- package/lib/components/entries/TextField.js.map +0 -1
- package/lib/components/entries/ToggleSwitch.js +0 -91
- package/lib/components/entries/ToggleSwitch.js.map +0 -1
- package/lib/components/icons/index.js +0 -51
- package/lib/components/icons/index.js.map +0 -1
- package/lib/context/DescriptionContext.js +0 -7
- package/lib/context/DescriptionContext.js.map +0 -1
- package/lib/context/LayoutContext.js +0 -9
- package/lib/context/LayoutContext.js.map +0 -1
- package/lib/context/index.js +0 -3
- package/lib/context/index.js.map +0 -1
- package/lib/features/debounce-input/debounceInput.js +0 -14
- package/lib/features/debounce-input/debounceInput.js.map +0 -1
- package/lib/features/debounce-input/index.js +0 -5
- package/lib/features/debounce-input/index.js.map +0 -1
- package/lib/hooks/index.js +0 -5
- package/lib/hooks/index.js.map +0 -1
- package/lib/hooks/useDescriptionContext.js +0 -25
- package/lib/hooks/useDescriptionContext.js.map +0 -1
- package/lib/hooks/useKeyFactory.js +0 -39
- package/lib/hooks/useKeyFactory.js.map +0 -1
- package/lib/hooks/useLayoutState.js +0 -36
- package/lib/hooks/useLayoutState.js.map +0 -1
- package/lib/hooks/usePrevious.js +0 -16
- package/lib/hooks/usePrevious.js.map +0 -1
- package/lib/index.js +0 -2
- package/lib/index.js.map +0 -1
|
@@ -0,0 +1,516 @@
|
|
|
1
|
+
import { EMPTY_OBJ, EMPTY_ARR } from '../constants';
|
|
2
|
+
import { Component } from '../component';
|
|
3
|
+
import { Fragment } from '../create-element';
|
|
4
|
+
import { diffChildren } from './children';
|
|
5
|
+
import { diffProps, setProperty } from './props';
|
|
6
|
+
import { assign, removeNode } from '../util';
|
|
7
|
+
import options from '../options';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Diff two virtual nodes and apply proper changes to the DOM
|
|
11
|
+
* @param {import('../internal').PreactElement} parentDom The parent of the DOM element
|
|
12
|
+
* @param {import('../internal').VNode} newVNode The new virtual node
|
|
13
|
+
* @param {import('../internal').VNode} oldVNode The old virtual node
|
|
14
|
+
* @param {object} globalContext The current context object. Modified by getChildContext
|
|
15
|
+
* @param {boolean} isSvg Whether or not this element is an SVG node
|
|
16
|
+
* @param {Array<import('../internal').PreactElement>} excessDomChildren
|
|
17
|
+
* @param {Array<import('../internal').Component>} commitQueue List of components
|
|
18
|
+
* which have callbacks to invoke in commitRoot
|
|
19
|
+
* @param {import('../internal').PreactElement} oldDom The current attached DOM
|
|
20
|
+
* element any new dom elements should be placed around. Likely `null` on first
|
|
21
|
+
* render (except when hydrating). Can be a sibling DOM element when diffing
|
|
22
|
+
* Fragments that have siblings. In most cases, it starts out as `oldChildren[0]._dom`.
|
|
23
|
+
* @param {boolean} [isHydrating] Whether or not we are in hydration
|
|
24
|
+
*/
|
|
25
|
+
export function diff(
|
|
26
|
+
parentDom,
|
|
27
|
+
newVNode,
|
|
28
|
+
oldVNode,
|
|
29
|
+
globalContext,
|
|
30
|
+
isSvg,
|
|
31
|
+
excessDomChildren,
|
|
32
|
+
commitQueue,
|
|
33
|
+
oldDom,
|
|
34
|
+
isHydrating
|
|
35
|
+
) {
|
|
36
|
+
let tmp,
|
|
37
|
+
newType = newVNode.type;
|
|
38
|
+
|
|
39
|
+
// When passing through createElement it assigns the object
|
|
40
|
+
// constructor as undefined. This to prevent JSON-injection.
|
|
41
|
+
if (newVNode.constructor !== undefined) return null;
|
|
42
|
+
|
|
43
|
+
// If the previous diff bailed out, resume creating/hydrating.
|
|
44
|
+
if (oldVNode._hydrating != null) {
|
|
45
|
+
isHydrating = oldVNode._hydrating;
|
|
46
|
+
oldDom = newVNode._dom = oldVNode._dom;
|
|
47
|
+
// if we resume, we want the tree to be "unlocked"
|
|
48
|
+
newVNode._hydrating = null;
|
|
49
|
+
excessDomChildren = [oldDom];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if ((tmp = options._diff)) tmp(newVNode);
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
outer: if (typeof newType == 'function') {
|
|
56
|
+
let c, isNew, oldProps, oldState, snapshot, clearProcessingException;
|
|
57
|
+
let newProps = newVNode.props;
|
|
58
|
+
|
|
59
|
+
// Necessary for createContext api. Setting this property will pass
|
|
60
|
+
// the context value as `this.context` just for this component.
|
|
61
|
+
tmp = newType.contextType;
|
|
62
|
+
let provider = tmp && globalContext[tmp._id];
|
|
63
|
+
let componentContext = tmp
|
|
64
|
+
? provider
|
|
65
|
+
? provider.props.value
|
|
66
|
+
: tmp._defaultValue
|
|
67
|
+
: globalContext;
|
|
68
|
+
|
|
69
|
+
// Get component and set it to `c`
|
|
70
|
+
if (oldVNode._component) {
|
|
71
|
+
c = newVNode._component = oldVNode._component;
|
|
72
|
+
clearProcessingException = c._processingException = c._pendingError;
|
|
73
|
+
} else {
|
|
74
|
+
// Instantiate the new component
|
|
75
|
+
if ('prototype' in newType && newType.prototype.render) {
|
|
76
|
+
// @ts-ignore The check above verifies that newType is suppose to be constructed
|
|
77
|
+
newVNode._component = c = new newType(newProps, componentContext); // eslint-disable-line new-cap
|
|
78
|
+
} else {
|
|
79
|
+
// @ts-ignore Trust me, Component implements the interface we want
|
|
80
|
+
newVNode._component = c = new Component(newProps, componentContext);
|
|
81
|
+
c.constructor = newType;
|
|
82
|
+
c.render = doRender;
|
|
83
|
+
}
|
|
84
|
+
if (provider) provider.sub(c);
|
|
85
|
+
|
|
86
|
+
c.props = newProps;
|
|
87
|
+
if (!c.state) c.state = {};
|
|
88
|
+
c.context = componentContext;
|
|
89
|
+
c._globalContext = globalContext;
|
|
90
|
+
isNew = c._dirty = true;
|
|
91
|
+
c._renderCallbacks = [];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Invoke getDerivedStateFromProps
|
|
95
|
+
if (c._nextState == null) {
|
|
96
|
+
c._nextState = c.state;
|
|
97
|
+
}
|
|
98
|
+
if (newType.getDerivedStateFromProps != null) {
|
|
99
|
+
if (c._nextState == c.state) {
|
|
100
|
+
c._nextState = assign({}, c._nextState);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
assign(
|
|
104
|
+
c._nextState,
|
|
105
|
+
newType.getDerivedStateFromProps(newProps, c._nextState)
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
oldProps = c.props;
|
|
110
|
+
oldState = c.state;
|
|
111
|
+
|
|
112
|
+
// Invoke pre-render lifecycle methods
|
|
113
|
+
if (isNew) {
|
|
114
|
+
if (
|
|
115
|
+
newType.getDerivedStateFromProps == null &&
|
|
116
|
+
c.componentWillMount != null
|
|
117
|
+
) {
|
|
118
|
+
c.componentWillMount();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (c.componentDidMount != null) {
|
|
122
|
+
c._renderCallbacks.push(c.componentDidMount);
|
|
123
|
+
}
|
|
124
|
+
} else {
|
|
125
|
+
if (
|
|
126
|
+
newType.getDerivedStateFromProps == null &&
|
|
127
|
+
newProps !== oldProps &&
|
|
128
|
+
c.componentWillReceiveProps != null
|
|
129
|
+
) {
|
|
130
|
+
c.componentWillReceiveProps(newProps, componentContext);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (
|
|
134
|
+
(!c._force &&
|
|
135
|
+
c.shouldComponentUpdate != null &&
|
|
136
|
+
c.shouldComponentUpdate(
|
|
137
|
+
newProps,
|
|
138
|
+
c._nextState,
|
|
139
|
+
componentContext
|
|
140
|
+
) === false) ||
|
|
141
|
+
newVNode._original === oldVNode._original
|
|
142
|
+
) {
|
|
143
|
+
c.props = newProps;
|
|
144
|
+
c.state = c._nextState;
|
|
145
|
+
// More info about this here: https://gist.github.com/JoviDeCroock/bec5f2ce93544d2e6070ef8e0036e4e8
|
|
146
|
+
if (newVNode._original !== oldVNode._original) c._dirty = false;
|
|
147
|
+
c._vnode = newVNode;
|
|
148
|
+
newVNode._dom = oldVNode._dom;
|
|
149
|
+
newVNode._children = oldVNode._children;
|
|
150
|
+
newVNode._children.forEach(vnode => {
|
|
151
|
+
if (vnode) vnode._parent = newVNode;
|
|
152
|
+
});
|
|
153
|
+
if (c._renderCallbacks.length) {
|
|
154
|
+
commitQueue.push(c);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
break outer;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (c.componentWillUpdate != null) {
|
|
161
|
+
c.componentWillUpdate(newProps, c._nextState, componentContext);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (c.componentDidUpdate != null) {
|
|
165
|
+
c._renderCallbacks.push(() => {
|
|
166
|
+
c.componentDidUpdate(oldProps, oldState, snapshot);
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
c.context = componentContext;
|
|
172
|
+
c.props = newProps;
|
|
173
|
+
c.state = c._nextState;
|
|
174
|
+
|
|
175
|
+
if ((tmp = options._render)) tmp(newVNode);
|
|
176
|
+
|
|
177
|
+
c._dirty = false;
|
|
178
|
+
c._vnode = newVNode;
|
|
179
|
+
c._parentDom = parentDom;
|
|
180
|
+
|
|
181
|
+
tmp = c.render(c.props, c.state, c.context);
|
|
182
|
+
|
|
183
|
+
// Handle setState called in render, see #2553
|
|
184
|
+
c.state = c._nextState;
|
|
185
|
+
|
|
186
|
+
if (c.getChildContext != null) {
|
|
187
|
+
globalContext = assign(assign({}, globalContext), c.getChildContext());
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (!isNew && c.getSnapshotBeforeUpdate != null) {
|
|
191
|
+
snapshot = c.getSnapshotBeforeUpdate(oldProps, oldState);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
let isTopLevelFragment =
|
|
195
|
+
tmp != null && tmp.type === Fragment && tmp.key == null;
|
|
196
|
+
let renderResult = isTopLevelFragment ? tmp.props.children : tmp;
|
|
197
|
+
|
|
198
|
+
diffChildren(
|
|
199
|
+
parentDom,
|
|
200
|
+
Array.isArray(renderResult) ? renderResult : [renderResult],
|
|
201
|
+
newVNode,
|
|
202
|
+
oldVNode,
|
|
203
|
+
globalContext,
|
|
204
|
+
isSvg,
|
|
205
|
+
excessDomChildren,
|
|
206
|
+
commitQueue,
|
|
207
|
+
oldDom,
|
|
208
|
+
isHydrating
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
c.base = newVNode._dom;
|
|
212
|
+
|
|
213
|
+
// We successfully rendered this VNode, unset any stored hydration/bailout state:
|
|
214
|
+
newVNode._hydrating = null;
|
|
215
|
+
|
|
216
|
+
if (c._renderCallbacks.length) {
|
|
217
|
+
commitQueue.push(c);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (clearProcessingException) {
|
|
221
|
+
c._pendingError = c._processingException = null;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
c._force = false;
|
|
225
|
+
} else if (
|
|
226
|
+
excessDomChildren == null &&
|
|
227
|
+
newVNode._original === oldVNode._original
|
|
228
|
+
) {
|
|
229
|
+
newVNode._children = oldVNode._children;
|
|
230
|
+
newVNode._dom = oldVNode._dom;
|
|
231
|
+
} else {
|
|
232
|
+
newVNode._dom = diffElementNodes(
|
|
233
|
+
oldVNode._dom,
|
|
234
|
+
newVNode,
|
|
235
|
+
oldVNode,
|
|
236
|
+
globalContext,
|
|
237
|
+
isSvg,
|
|
238
|
+
excessDomChildren,
|
|
239
|
+
commitQueue,
|
|
240
|
+
isHydrating
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if ((tmp = options.diffed)) tmp(newVNode);
|
|
245
|
+
} catch (e) {
|
|
246
|
+
newVNode._original = null;
|
|
247
|
+
// if hydrating or creating initial tree, bailout preserves DOM:
|
|
248
|
+
if (isHydrating || excessDomChildren != null) {
|
|
249
|
+
newVNode._dom = oldDom;
|
|
250
|
+
newVNode._hydrating = !!isHydrating;
|
|
251
|
+
excessDomChildren[excessDomChildren.indexOf(oldDom)] = null;
|
|
252
|
+
// ^ could possibly be simplified to:
|
|
253
|
+
// excessDomChildren.length = 0;
|
|
254
|
+
}
|
|
255
|
+
options._catchError(e, newVNode, oldVNode);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* @param {Array<import('../internal').Component>} commitQueue List of components
|
|
261
|
+
* which have callbacks to invoke in commitRoot
|
|
262
|
+
* @param {import('../internal').VNode} root
|
|
263
|
+
*/
|
|
264
|
+
export function commitRoot(commitQueue, root) {
|
|
265
|
+
if (options._commit) options._commit(root, commitQueue);
|
|
266
|
+
|
|
267
|
+
commitQueue.some(c => {
|
|
268
|
+
try {
|
|
269
|
+
// @ts-ignore Reuse the commitQueue variable here so the type changes
|
|
270
|
+
commitQueue = c._renderCallbacks;
|
|
271
|
+
c._renderCallbacks = [];
|
|
272
|
+
commitQueue.some(cb => {
|
|
273
|
+
// @ts-ignore See above ts-ignore on commitQueue
|
|
274
|
+
cb.call(c);
|
|
275
|
+
});
|
|
276
|
+
} catch (e) {
|
|
277
|
+
options._catchError(e, c._vnode);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Diff two virtual nodes representing DOM element
|
|
284
|
+
* @param {import('../internal').PreactElement} dom The DOM element representing
|
|
285
|
+
* the virtual nodes being diffed
|
|
286
|
+
* @param {import('../internal').VNode} newVNode The new virtual node
|
|
287
|
+
* @param {import('../internal').VNode} oldVNode The old virtual node
|
|
288
|
+
* @param {object} globalContext The current context object
|
|
289
|
+
* @param {boolean} isSvg Whether or not this DOM node is an SVG node
|
|
290
|
+
* @param {*} excessDomChildren
|
|
291
|
+
* @param {Array<import('../internal').Component>} commitQueue List of components
|
|
292
|
+
* which have callbacks to invoke in commitRoot
|
|
293
|
+
* @param {boolean} isHydrating Whether or not we are in hydration
|
|
294
|
+
* @returns {import('../internal').PreactElement}
|
|
295
|
+
*/
|
|
296
|
+
function diffElementNodes(
|
|
297
|
+
dom,
|
|
298
|
+
newVNode,
|
|
299
|
+
oldVNode,
|
|
300
|
+
globalContext,
|
|
301
|
+
isSvg,
|
|
302
|
+
excessDomChildren,
|
|
303
|
+
commitQueue,
|
|
304
|
+
isHydrating
|
|
305
|
+
) {
|
|
306
|
+
let oldProps = oldVNode.props;
|
|
307
|
+
let newProps = newVNode.props;
|
|
308
|
+
let nodeType = newVNode.type;
|
|
309
|
+
let i = 0;
|
|
310
|
+
|
|
311
|
+
// Tracks entering and exiting SVG namespace when descending through the tree.
|
|
312
|
+
if (nodeType === 'svg') isSvg = true;
|
|
313
|
+
|
|
314
|
+
if (excessDomChildren != null) {
|
|
315
|
+
for (; i < excessDomChildren.length; i++) {
|
|
316
|
+
const child = excessDomChildren[i];
|
|
317
|
+
|
|
318
|
+
// if newVNode matches an element in excessDomChildren or the `dom`
|
|
319
|
+
// argument matches an element in excessDomChildren, remove it from
|
|
320
|
+
// excessDomChildren so it isn't later removed in diffChildren
|
|
321
|
+
if (
|
|
322
|
+
child &&
|
|
323
|
+
(child === dom ||
|
|
324
|
+
(nodeType ? child.localName == nodeType : child.nodeType == 3))
|
|
325
|
+
) {
|
|
326
|
+
dom = child;
|
|
327
|
+
excessDomChildren[i] = null;
|
|
328
|
+
break;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
if (dom == null) {
|
|
334
|
+
if (nodeType === null) {
|
|
335
|
+
// @ts-ignore createTextNode returns Text, we expect PreactElement
|
|
336
|
+
return document.createTextNode(newProps);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
if (isSvg) {
|
|
340
|
+
dom = document.createElementNS(
|
|
341
|
+
'http://www.w3.org/2000/svg',
|
|
342
|
+
// @ts-ignore We know `newVNode.type` is a string
|
|
343
|
+
nodeType
|
|
344
|
+
);
|
|
345
|
+
} else {
|
|
346
|
+
dom = document.createElement(
|
|
347
|
+
// @ts-ignore We know `newVNode.type` is a string
|
|
348
|
+
nodeType,
|
|
349
|
+
newProps.is && newProps
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// we created a new parent, so none of the previously attached children can be reused:
|
|
354
|
+
excessDomChildren = null;
|
|
355
|
+
// we are creating a new node, so we can assume this is a new subtree (in case we are hydrating), this deopts the hydrate
|
|
356
|
+
isHydrating = false;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
if (nodeType === null) {
|
|
360
|
+
// During hydration, we still have to split merged text from SSR'd HTML.
|
|
361
|
+
if (oldProps !== newProps && (!isHydrating || dom.data !== newProps)) {
|
|
362
|
+
dom.data = newProps;
|
|
363
|
+
}
|
|
364
|
+
} else {
|
|
365
|
+
// If excessDomChildren was not null, repopulate it with the current element's children:
|
|
366
|
+
excessDomChildren =
|
|
367
|
+
excessDomChildren && EMPTY_ARR.slice.call(dom.childNodes);
|
|
368
|
+
|
|
369
|
+
oldProps = oldVNode.props || EMPTY_OBJ;
|
|
370
|
+
|
|
371
|
+
let oldHtml = oldProps.dangerouslySetInnerHTML;
|
|
372
|
+
let newHtml = newProps.dangerouslySetInnerHTML;
|
|
373
|
+
|
|
374
|
+
// During hydration, props are not diffed at all (including dangerouslySetInnerHTML)
|
|
375
|
+
// @TODO we should warn in debug mode when props don't match here.
|
|
376
|
+
if (!isHydrating) {
|
|
377
|
+
// But, if we are in a situation where we are using existing DOM (e.g. replaceNode)
|
|
378
|
+
// we should read the existing DOM attributes to diff them
|
|
379
|
+
if (excessDomChildren != null) {
|
|
380
|
+
oldProps = {};
|
|
381
|
+
for (let i = 0; i < dom.attributes.length; i++) {
|
|
382
|
+
oldProps[dom.attributes[i].name] = dom.attributes[i].value;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
if (newHtml || oldHtml) {
|
|
387
|
+
// Avoid re-applying the same '__html' if it did not changed between re-render
|
|
388
|
+
if (
|
|
389
|
+
!newHtml ||
|
|
390
|
+
((!oldHtml || newHtml.__html != oldHtml.__html) &&
|
|
391
|
+
newHtml.__html !== dom.innerHTML)
|
|
392
|
+
) {
|
|
393
|
+
dom.innerHTML = (newHtml && newHtml.__html) || '';
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
diffProps(dom, newProps, oldProps, isSvg, isHydrating);
|
|
399
|
+
|
|
400
|
+
// If the new vnode didn't have dangerouslySetInnerHTML, diff its children
|
|
401
|
+
if (newHtml) {
|
|
402
|
+
newVNode._children = [];
|
|
403
|
+
} else {
|
|
404
|
+
i = newVNode.props.children;
|
|
405
|
+
diffChildren(
|
|
406
|
+
dom,
|
|
407
|
+
Array.isArray(i) ? i : [i],
|
|
408
|
+
newVNode,
|
|
409
|
+
oldVNode,
|
|
410
|
+
globalContext,
|
|
411
|
+
isSvg && nodeType !== 'foreignObject',
|
|
412
|
+
excessDomChildren,
|
|
413
|
+
commitQueue,
|
|
414
|
+
dom.firstChild,
|
|
415
|
+
isHydrating
|
|
416
|
+
);
|
|
417
|
+
|
|
418
|
+
// Remove children that are not part of any vnode.
|
|
419
|
+
if (excessDomChildren != null) {
|
|
420
|
+
for (i = excessDomChildren.length; i--; ) {
|
|
421
|
+
if (excessDomChildren[i] != null) removeNode(excessDomChildren[i]);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// (as above, don't diff props during hydration)
|
|
427
|
+
if (!isHydrating) {
|
|
428
|
+
if (
|
|
429
|
+
'value' in newProps &&
|
|
430
|
+
(i = newProps.value) !== undefined &&
|
|
431
|
+
// #2756 For the <progress>-element the initial value is 0,
|
|
432
|
+
// despite the attribute not being present. When the attribute
|
|
433
|
+
// is missing the progress bar is treated as indeterminate.
|
|
434
|
+
// To fix that we'll always update it when it is 0 for progress elements
|
|
435
|
+
(i !== dom.value || (nodeType === 'progress' && !i))
|
|
436
|
+
) {
|
|
437
|
+
setProperty(dom, 'value', i, oldProps.value, false);
|
|
438
|
+
}
|
|
439
|
+
if (
|
|
440
|
+
'checked' in newProps &&
|
|
441
|
+
(i = newProps.checked) !== undefined &&
|
|
442
|
+
i !== dom.checked
|
|
443
|
+
) {
|
|
444
|
+
setProperty(dom, 'checked', i, oldProps.checked, false);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
return dom;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Invoke or update a ref, depending on whether it is a function or object ref.
|
|
454
|
+
* @param {object|function} ref
|
|
455
|
+
* @param {any} value
|
|
456
|
+
* @param {import('../internal').VNode} vnode
|
|
457
|
+
*/
|
|
458
|
+
export function applyRef(ref, value, vnode) {
|
|
459
|
+
try {
|
|
460
|
+
if (typeof ref == 'function') ref(value);
|
|
461
|
+
else ref.current = value;
|
|
462
|
+
} catch (e) {
|
|
463
|
+
options._catchError(e, vnode);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Unmount a virtual node from the tree and apply DOM changes
|
|
469
|
+
* @param {import('../internal').VNode} vnode The virtual node to unmount
|
|
470
|
+
* @param {import('../internal').VNode} parentVNode The parent of the VNode that
|
|
471
|
+
* initiated the unmount
|
|
472
|
+
* @param {boolean} [skipRemove] Flag that indicates that a parent node of the
|
|
473
|
+
* current element is already detached from the DOM.
|
|
474
|
+
*/
|
|
475
|
+
export function unmount(vnode, parentVNode, skipRemove) {
|
|
476
|
+
let r;
|
|
477
|
+
if (options.unmount) options.unmount(vnode);
|
|
478
|
+
|
|
479
|
+
if ((r = vnode.ref)) {
|
|
480
|
+
if (!r.current || r.current === vnode._dom) applyRef(r, null, parentVNode);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
let dom;
|
|
484
|
+
if (!skipRemove && typeof vnode.type != 'function') {
|
|
485
|
+
skipRemove = (dom = vnode._dom) != null;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// Must be set to `undefined` to properly clean up `_nextDom`
|
|
489
|
+
// for which `null` is a valid value. See comment in `create-element.js`
|
|
490
|
+
vnode._dom = vnode._nextDom = undefined;
|
|
491
|
+
|
|
492
|
+
if ((r = vnode._component) != null) {
|
|
493
|
+
if (r.componentWillUnmount) {
|
|
494
|
+
try {
|
|
495
|
+
r.componentWillUnmount();
|
|
496
|
+
} catch (e) {
|
|
497
|
+
options._catchError(e, parentVNode);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
r.base = r._parentDom = null;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
if ((r = vnode._children)) {
|
|
505
|
+
for (let i = 0; i < r.length; i++) {
|
|
506
|
+
if (r[i]) unmount(r[i], parentVNode, skipRemove);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
if (dom != null) removeNode(dom);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/** The `.render()` method for a PFC backing instance. */
|
|
514
|
+
function doRender(props, state, context) {
|
|
515
|
+
return this.constructor(props, context);
|
|
516
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { IS_NON_DIMENSIONAL } from '../constants';
|
|
2
|
+
import options from '../options';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Diff the old and new properties of a VNode and apply changes to the DOM node
|
|
6
|
+
* @param {import('../internal').PreactElement} dom The DOM node to apply
|
|
7
|
+
* changes to
|
|
8
|
+
* @param {object} newProps The new props
|
|
9
|
+
* @param {object} oldProps The old props
|
|
10
|
+
* @param {boolean} isSvg Whether or not this node is an SVG node
|
|
11
|
+
* @param {boolean} hydrate Whether or not we are in hydration mode
|
|
12
|
+
*/
|
|
13
|
+
export function diffProps(dom, newProps, oldProps, isSvg, hydrate) {
|
|
14
|
+
let i;
|
|
15
|
+
|
|
16
|
+
for (i in oldProps) {
|
|
17
|
+
if (i !== 'children' && i !== 'key' && !(i in newProps)) {
|
|
18
|
+
setProperty(dom, i, null, oldProps[i], isSvg);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
for (i in newProps) {
|
|
23
|
+
if (
|
|
24
|
+
(!hydrate || typeof newProps[i] == 'function') &&
|
|
25
|
+
i !== 'children' &&
|
|
26
|
+
i !== 'key' &&
|
|
27
|
+
i !== 'value' &&
|
|
28
|
+
i !== 'checked' &&
|
|
29
|
+
oldProps[i] !== newProps[i]
|
|
30
|
+
) {
|
|
31
|
+
setProperty(dom, i, newProps[i], oldProps[i], isSvg);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function setStyle(style, key, value) {
|
|
37
|
+
if (key[0] === '-') {
|
|
38
|
+
style.setProperty(key, value);
|
|
39
|
+
} else if (value == null) {
|
|
40
|
+
style[key] = '';
|
|
41
|
+
} else if (typeof value != 'number' || IS_NON_DIMENSIONAL.test(key)) {
|
|
42
|
+
style[key] = value;
|
|
43
|
+
} else {
|
|
44
|
+
style[key] = value + 'px';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Set a property value on a DOM node
|
|
50
|
+
* @param {import('../internal').PreactElement} dom The DOM node to modify
|
|
51
|
+
* @param {string} name The name of the property to set
|
|
52
|
+
* @param {*} value The value to set the property to
|
|
53
|
+
* @param {*} oldValue The old value the property had
|
|
54
|
+
* @param {boolean} isSvg Whether or not this DOM node is an SVG node or not
|
|
55
|
+
*/
|
|
56
|
+
export function setProperty(dom, name, value, oldValue, isSvg) {
|
|
57
|
+
let useCapture;
|
|
58
|
+
|
|
59
|
+
o: if (name === 'style') {
|
|
60
|
+
if (typeof value == 'string') {
|
|
61
|
+
dom.style.cssText = value;
|
|
62
|
+
} else {
|
|
63
|
+
if (typeof oldValue == 'string') {
|
|
64
|
+
dom.style.cssText = oldValue = '';
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (oldValue) {
|
|
68
|
+
for (name in oldValue) {
|
|
69
|
+
if (!(value && name in value)) {
|
|
70
|
+
setStyle(dom.style, name, '');
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (value) {
|
|
76
|
+
for (name in value) {
|
|
77
|
+
if (!oldValue || value[name] !== oldValue[name]) {
|
|
78
|
+
setStyle(dom.style, name, value[name]);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// Benchmark for comparison: https://esbench.com/bench/574c954bdb965b9a00965ac6
|
|
85
|
+
else if (name[0] === 'o' && name[1] === 'n') {
|
|
86
|
+
useCapture = name !== (name = name.replace(/Capture$/, ''));
|
|
87
|
+
|
|
88
|
+
// Infer correct casing for DOM built-in events:
|
|
89
|
+
if (name.toLowerCase() in dom) name = name.toLowerCase().slice(2);
|
|
90
|
+
else name = name.slice(2);
|
|
91
|
+
|
|
92
|
+
if (!dom._listeners) dom._listeners = {};
|
|
93
|
+
dom._listeners[name + useCapture] = value;
|
|
94
|
+
|
|
95
|
+
if (value) {
|
|
96
|
+
if (!oldValue) {
|
|
97
|
+
const handler = useCapture ? eventProxyCapture : eventProxy;
|
|
98
|
+
dom.addEventListener(name, handler, useCapture);
|
|
99
|
+
}
|
|
100
|
+
} else {
|
|
101
|
+
const handler = useCapture ? eventProxyCapture : eventProxy;
|
|
102
|
+
dom.removeEventListener(name, handler, useCapture);
|
|
103
|
+
}
|
|
104
|
+
} else if (name !== 'dangerouslySetInnerHTML') {
|
|
105
|
+
if (isSvg) {
|
|
106
|
+
// Normalize incorrect prop usage for SVG:
|
|
107
|
+
// - xlink:href / xlinkHref --> href (xlink:href was removed from SVG and isn't needed)
|
|
108
|
+
// - className --> class
|
|
109
|
+
name = name.replace(/xlink[H:h]/, 'h').replace(/sName$/, 's');
|
|
110
|
+
} else if (
|
|
111
|
+
name !== 'href' &&
|
|
112
|
+
name !== 'list' &&
|
|
113
|
+
name !== 'form' &&
|
|
114
|
+
// Default value in browsers is `-1` and an empty string is
|
|
115
|
+
// cast to `0` instead
|
|
116
|
+
name !== 'tabIndex' &&
|
|
117
|
+
name !== 'download' &&
|
|
118
|
+
name in dom
|
|
119
|
+
) {
|
|
120
|
+
try {
|
|
121
|
+
dom[name] = value == null ? '' : value;
|
|
122
|
+
// labelled break is 1b smaller here than a return statement (sorry)
|
|
123
|
+
break o;
|
|
124
|
+
} catch (e) {}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// ARIA-attributes have a different notion of boolean values.
|
|
128
|
+
// The value `false` is different from the attribute not
|
|
129
|
+
// existing on the DOM, so we can't remove it. For non-boolean
|
|
130
|
+
// ARIA-attributes we could treat false as a removal, but the
|
|
131
|
+
// amount of exceptions would cost us too many bytes. On top of
|
|
132
|
+
// that other VDOM frameworks also always stringify `false`.
|
|
133
|
+
|
|
134
|
+
if (typeof value === 'function') {
|
|
135
|
+
// never serialize functions as attribute values
|
|
136
|
+
} else if (
|
|
137
|
+
value != null &&
|
|
138
|
+
(value !== false || (name[0] === 'a' && name[1] === 'r'))
|
|
139
|
+
) {
|
|
140
|
+
dom.setAttribute(name, value);
|
|
141
|
+
} else {
|
|
142
|
+
dom.removeAttribute(name);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Proxy an event to hooked event handlers
|
|
149
|
+
* @param {Event} e The event object from the browser
|
|
150
|
+
* @private
|
|
151
|
+
*/
|
|
152
|
+
function eventProxy(e) {
|
|
153
|
+
this._listeners[e.type + false](options.event ? options.event(e) : e);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function eventProxyCapture(e) {
|
|
157
|
+
this._listeners[e.type + true](options.event ? options.event(e) : e);
|
|
158
|
+
}
|