@faiwer/react 0.8.3 → 0.9.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/README.md +20 -14
- package/dist/core/Children.d.ts +11 -0
- package/dist/core/Children.d.ts.map +1 -0
- package/dist/core/Children.js +35 -0
- package/dist/core/Children.js.map +1 -0
- package/dist/core/actions/applyAction.d.ts.map +1 -1
- package/dist/core/actions/applyAction.js +2 -0
- package/dist/core/actions/applyAction.js.map +1 -1
- package/dist/core/actions/createComment.action.d.ts +2 -2
- package/dist/core/actions/createComment.action.d.ts.map +1 -1
- package/dist/core/actions/createComment.action.js +1 -8
- package/dist/core/actions/createComment.action.js.map +1 -1
- package/dist/core/actions/createContainer.action.d.ts +7 -0
- package/dist/core/actions/createContainer.action.d.ts.map +1 -0
- package/dist/core/actions/createContainer.action.js +28 -0
- package/dist/core/actions/createContainer.action.js.map +1 -0
- package/dist/core/actions/createTag.action.d.ts +2 -1
- package/dist/core/actions/createTag.action.d.ts.map +1 -1
- package/dist/core/actions/createTag.action.js +107 -5
- package/dist/core/actions/createTag.action.js.map +1 -1
- package/dist/core/actions/createText.action.d.ts.map +1 -1
- package/dist/core/actions/createText.action.js +2 -5
- package/dist/core/actions/createText.action.js.map +1 -1
- package/dist/core/actions/dom/attributes.d.ts +4 -0
- package/dist/core/actions/dom/attributes.d.ts.map +1 -0
- package/dist/core/actions/dom/attributes.js +56 -0
- package/dist/core/actions/dom/attributes.js.map +1 -0
- package/dist/core/actions/dom/css.d.ts +6 -0
- package/dist/core/actions/dom/css.d.ts.map +1 -0
- package/dist/core/actions/dom/css.js +54 -0
- package/dist/core/actions/dom/css.js.map +1 -0
- package/dist/core/actions/dom/events.d.ts +3 -0
- package/dist/core/actions/dom/events.d.ts.map +1 -0
- package/dist/core/actions/dom/events.js +45 -0
- package/dist/core/actions/dom/events.js.map +1 -0
- package/dist/core/actions/dom/svg.d.ts +7 -0
- package/dist/core/actions/dom/svg.d.ts.map +1 -0
- package/dist/core/actions/dom/svg.js +76 -0
- package/dist/core/actions/dom/svg.js.map +1 -0
- package/dist/core/actions/dom/value.d.ts +17 -0
- package/dist/core/actions/dom/value.d.ts.map +1 -0
- package/dist/core/actions/dom/value.js +204 -0
- package/dist/core/actions/dom/value.js.map +1 -0
- package/dist/core/actions/helpers.d.ts +18 -11
- package/dist/core/actions/helpers.d.ts.map +1 -1
- package/dist/core/actions/helpers.js +78 -68
- package/dist/core/actions/helpers.js.map +1 -1
- package/dist/core/actions/relayout.action.d.ts +2 -1
- package/dist/core/actions/relayout.action.d.ts.map +1 -1
- package/dist/core/actions/relayout.action.js +119 -30
- package/dist/core/actions/relayout.action.js.map +1 -1
- package/dist/core/actions/remove.action.d.ts +3 -2
- package/dist/core/actions/remove.action.d.ts.map +1 -1
- package/dist/core/actions/remove.action.js +22 -18
- package/dist/core/actions/remove.action.js.map +1 -1
- package/dist/core/actions/replace.action.d.ts +1 -1
- package/dist/core/actions/replace.action.d.ts.map +1 -1
- package/dist/core/actions/replace.action.js +36 -11
- package/dist/core/actions/replace.action.js.map +1 -1
- package/dist/core/actions/setAttr.action.d.ts +1 -1
- package/dist/core/actions/setAttr.action.d.ts.map +1 -1
- package/dist/core/actions/setAttr.action.js +55 -87
- package/dist/core/actions/setAttr.action.js.map +1 -1
- package/dist/core/actions/setProps.action.d.ts.map +1 -1
- package/dist/core/actions/setProps.action.js +2 -1
- package/dist/core/actions/setProps.action.js.map +1 -1
- package/dist/core/actions/setRef.action.d.ts +1 -1
- package/dist/core/actions/setRef.action.d.ts.map +1 -1
- package/dist/core/actions/setRef.action.js +5 -6
- package/dist/core/actions/setRef.action.js.map +1 -1
- package/dist/core/actions/setText.action.d.ts.map +1 -1
- package/dist/core/actions/setText.action.js +3 -3
- package/dist/core/actions/setText.action.js.map +1 -1
- package/dist/core/classComponent.d.ts +33 -0
- package/dist/core/classComponent.d.ts.map +1 -0
- package/dist/core/classComponent.js +127 -0
- package/dist/core/classComponent.js.map +1 -0
- package/dist/core/compact.d.ts +10 -29
- package/dist/core/compact.d.ts.map +1 -1
- package/dist/core/compact.js +12 -100
- package/dist/core/compact.js.map +1 -1
- package/dist/core/components.d.ts +2 -2
- package/dist/core/components.d.ts.map +1 -1
- package/dist/core/components.js +22 -5
- package/dist/core/components.js.map +1 -1
- package/dist/core/createElement.d.ts +9 -9
- package/dist/core/createElement.d.ts.map +1 -1
- package/dist/core/createElement.js +19 -3
- package/dist/core/createElement.js.map +1 -1
- package/dist/core/createRoot.js.map +1 -1
- package/dist/core/reactNodeToFiberNode.d.ts.map +1 -1
- package/dist/core/reactNodeToFiberNode.js +6 -1
- package/dist/core/reactNodeToFiberNode.js.map +1 -1
- package/dist/core/reconciliation/app.js +3 -3
- package/dist/core/reconciliation/app.js.map +1 -1
- package/dist/core/reconciliation/collect/fromApp.d.ts.map +1 -1
- package/dist/core/reconciliation/collect/fromApp.js +3 -27
- package/dist/core/reconciliation/collect/fromApp.js.map +1 -1
- package/dist/core/reconciliation/collect/fromChildrenPair.d.ts.map +1 -1
- package/dist/core/reconciliation/collect/fromChildrenPair.js +24 -15
- package/dist/core/reconciliation/collect/fromChildrenPair.js.map +1 -1
- package/dist/core/reconciliation/collect/fromComponent.d.ts +2 -2
- package/dist/core/reconciliation/collect/fromComponent.d.ts.map +1 -1
- package/dist/core/reconciliation/collect/fromComponent.js +4 -8
- package/dist/core/reconciliation/collect/fromComponent.js.map +1 -1
- package/dist/core/reconciliation/collect/fromFiberPair.d.ts.map +1 -1
- package/dist/core/reconciliation/collect/fromFiberPair.js +6 -4
- package/dist/core/reconciliation/collect/fromFiberPair.js.map +1 -1
- package/dist/core/reconciliation/collect/fromNewFiber.d.ts.map +1 -1
- package/dist/core/reconciliation/collect/fromNewFiber.js +7 -15
- package/dist/core/reconciliation/collect/fromNewFiber.js.map +1 -1
- package/dist/core/reconciliation/effects.d.ts.map +1 -1
- package/dist/core/reconciliation/effects.js +0 -5
- package/dist/core/reconciliation/effects.js.map +1 -1
- package/dist/core/reconciliation/errors/ReactError.d.ts +7 -0
- package/dist/core/reconciliation/errors/ReactError.d.ts.map +1 -0
- package/dist/core/reconciliation/errors/ReactError.js +26 -0
- package/dist/core/reconciliation/errors/ReactError.js.map +1 -0
- package/dist/core/reconciliation/errors/stack.d.ts +9 -0
- package/dist/core/reconciliation/errors/stack.d.ts.map +1 -0
- package/dist/core/reconciliation/errors/stack.js +80 -0
- package/dist/core/reconciliation/errors/stack.js.map +1 -0
- package/dist/core/reconciliation/fibers.d.ts +7 -0
- package/dist/core/reconciliation/fibers.d.ts.map +1 -1
- package/dist/core/reconciliation/fibers.js +9 -2
- package/dist/core/reconciliation/fibers.js.map +1 -1
- package/dist/core/reconciliation/heap.d.ts +18 -0
- package/dist/core/reconciliation/heap.d.ts.map +1 -0
- package/dist/core/reconciliation/heap.js +81 -0
- package/dist/core/reconciliation/heap.js.map +1 -0
- package/dist/core/reconciliation/invalidateFiber.d.ts.map +1 -1
- package/dist/core/reconciliation/invalidateFiber.js +10 -4
- package/dist/core/reconciliation/invalidateFiber.js.map +1 -1
- package/dist/core/reconciliation/mount.d.ts.map +1 -1
- package/dist/core/reconciliation/mount.js +17 -7
- package/dist/core/reconciliation/mount.js.map +1 -1
- package/dist/core/reconciliation/postCommit.d.ts +1 -1
- package/dist/core/reconciliation/postCommit.d.ts.map +1 -1
- package/dist/core/reconciliation/postCommit.js +19 -4
- package/dist/core/reconciliation/postCommit.js.map +1 -1
- package/dist/core/reconciliation/queue.d.ts +21 -0
- package/dist/core/reconciliation/queue.d.ts.map +1 -0
- package/dist/core/reconciliation/queue.js +55 -0
- package/dist/core/reconciliation/queue.js.map +1 -0
- package/dist/core/reconciliation/render.js +5 -5
- package/dist/core/reconciliation/render.js.map +1 -1
- package/dist/core/reconciliation/runFiberComponents.d.ts.map +1 -1
- package/dist/core/reconciliation/runFiberComponents.js +2 -1
- package/dist/core/reconciliation/runFiberComponents.js.map +1 -1
- package/dist/core/reconciliation/typeGuards.d.ts +9 -1
- package/dist/core/reconciliation/typeGuards.d.ts.map +1 -1
- package/dist/core/reconciliation/typeGuards.js +25 -0
- package/dist/core/reconciliation/typeGuards.js.map +1 -1
- package/dist/core/reconciliation/validateApp.d.ts +3 -0
- package/dist/core/reconciliation/validateApp.d.ts.map +1 -0
- package/dist/core/reconciliation/validateApp.js +74 -0
- package/dist/core/reconciliation/validateApp.js.map +1 -0
- package/dist/hooks/helpers.d.ts +2 -2
- package/dist/hooks/helpers.d.ts.map +1 -1
- package/dist/hooks/helpers.js +3 -2
- package/dist/hooks/helpers.js.map +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/useContext.d.ts.map +1 -1
- package/dist/hooks/useContext.js +16 -0
- package/dist/hooks/useContext.js.map +1 -1
- package/dist/hooks/useEffect.d.ts +2 -1
- package/dist/hooks/useEffect.d.ts.map +1 -1
- package/dist/hooks/useEffect.js +1 -1
- package/dist/hooks/useEffect.js.map +1 -1
- package/dist/hooks/useRef.d.ts +8 -3
- package/dist/hooks/useRef.d.ts.map +1 -1
- package/dist/hooks/useRef.js +27 -0
- package/dist/hooks/useRef.js.map +1 -1
- package/dist/hooks/useState.d.ts +1 -1
- package/dist/hooks/useState.d.ts.map +1 -1
- package/dist/hooks/useState.js +24 -1
- package/dist/hooks/useState.js.map +1 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/jsx-dev-runtime.d.ts +4 -4
- package/dist/jsx-dev-runtime.d.ts.map +1 -1
- package/dist/jsx-dev-runtime.js +4 -4
- package/dist/jsx-dev-runtime.js.map +1 -1
- package/dist/jsx-runtime.d.ts +3 -3
- package/dist/jsx-runtime.d.ts.map +1 -1
- package/dist/jsx-runtime.js +3 -3
- package/dist/jsx-runtime.js.map +1 -1
- package/dist/jsx.d.ts +176 -36
- package/dist/mocks.d.ts +21 -0
- package/dist/mocks.d.ts.map +1 -0
- package/dist/mocks.js +27 -0
- package/dist/mocks.js.map +1 -0
- package/dist/react.d.ts +46 -0
- package/dist/types/actions.d.ts +12 -4
- package/dist/types/actions.d.ts.map +1 -1
- package/dist/types/app.d.ts +17 -2
- package/dist/types/app.d.ts.map +1 -1
- package/dist/types/attributes.d.ts +42 -0
- package/dist/types/attributes.d.ts.map +1 -0
- package/dist/types/attributes.js +2 -0
- package/dist/types/attributes.js.map +1 -0
- package/dist/types/common.d.ts +13 -0
- package/dist/types/common.d.ts.map +1 -0
- package/dist/types/common.js +2 -0
- package/dist/types/common.js.map +1 -0
- package/dist/types/component.d.ts +5 -1
- package/dist/types/component.d.ts.map +1 -1
- package/dist/types/context.d.ts +3 -2
- package/dist/types/context.d.ts.map +1 -1
- package/dist/types/core.d.ts +17 -13
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/dom.d.ts +23 -27
- package/dist/types/dom.d.ts.map +1 -1
- package/dist/types/events.d.ts +31 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +2 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/fiber.d.ts +31 -11
- package/dist/types/fiber.d.ts.map +1 -1
- package/dist/types/fiber.js +5 -1
- package/dist/types/fiber.js.map +1 -1
- package/dist/types/hooks.d.ts +8 -5
- package/dist/types/hooks.d.ts.map +1 -1
- package/dist/types/react.d.ts +35 -0
- package/dist/types/react.d.ts.map +1 -0
- package/dist/types/react.js +2 -0
- package/dist/types/react.js.map +1 -0
- package/dist/types/refs.d.ts +5 -8
- package/dist/types/refs.d.ts.map +1 -1
- package/package.json +15 -3
- package/dist/core/reconciliation/validateTree.d.ts +0 -6
- package/dist/core/reconciliation/validateTree.d.ts.map +0 -1
- package/dist/core/reconciliation/validateTree.js +0 -48
- package/dist/core/reconciliation/validateTree.js.map +0 -1
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ReactError } from '../../../core/reconciliation/errors/ReactError';
|
|
2
|
+
export const setEventHandler = (fiber, element, name, value) => {
|
|
3
|
+
const { events } = fiber.data;
|
|
4
|
+
if (value == null || value === false) {
|
|
5
|
+
if (events[name]) {
|
|
6
|
+
// Event handler was added before but now it's removed.
|
|
7
|
+
events[name].handler = null;
|
|
8
|
+
}
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
if (typeof value !== 'function') {
|
|
12
|
+
throw new ReactError(fiber, `Unsupported format of event handler. It has to be "undefined" or a function`);
|
|
13
|
+
}
|
|
14
|
+
// Instead of adding and removing event handlers on every render, we can add a
|
|
15
|
+
// wrapper that calls `events[name]` and update only the internal
|
|
16
|
+
// function when it changes.
|
|
17
|
+
if (!events[name]) {
|
|
18
|
+
const capture = name.endsWith('Capture');
|
|
19
|
+
let eventName = name.slice(2).toLowerCase(); // onClick -> click.
|
|
20
|
+
if (capture) {
|
|
21
|
+
eventName = eventName.slice(0, eventName.length - 7);
|
|
22
|
+
}
|
|
23
|
+
if (eventName === 'change' &&
|
|
24
|
+
(fiber.tag === 'input' ||
|
|
25
|
+
fiber.tag === 'textarea' ||
|
|
26
|
+
fiber.tag === 'select')) {
|
|
27
|
+
eventName = 'input'; // Custom behavior. @see `./value.ts`.
|
|
28
|
+
}
|
|
29
|
+
events[name] = {
|
|
30
|
+
name: eventName,
|
|
31
|
+
handler: value,
|
|
32
|
+
capture,
|
|
33
|
+
wrapper: (event) => {
|
|
34
|
+
// Original React doesn't support stopping propagation on `false` return.
|
|
35
|
+
events[name].handler?.(event);
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
element.addEventListener(eventName, events[name].wrapper, { capture });
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
// The tag is already listening to this event. Just update the internal ref.
|
|
42
|
+
events[name].handler = value;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../../../src/core/actions/dom/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oDAAoD,CAAC;AAGhF,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,KAAmB,EACnB,OAAgB,EAChB,IAAY,EACZ,KAAmB,EACb,EAAE,CAAC;IACT,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC;IAE9B,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;QACrC,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YACjB,uDAAuD;YACvD,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC;QAC9B,CAAC;QACD,OAAO;IACT,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;QAChC,MAAM,IAAI,UAAU,CAClB,KAAK,EACL,6EAA6E,CAC9E,CAAC;IACJ,CAAC;IAED,8EAA8E;IAC9E,iEAAiE;IACjE,4BAA4B;IAC5B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAClB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,oBAAoB;QACjE,IAAI,OAAO,EAAE,CAAC;YACZ,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACvD,CAAC;QAED,IACE,SAAS,KAAK,QAAQ;YACtB,CAAC,KAAK,CAAC,GAAG,KAAK,OAAO;gBACpB,KAAK,CAAC,GAAG,KAAK,UAAU;gBACxB,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,EACzB,CAAC;YACD,SAAS,GAAG,OAAO,CAAC,CAAC,sCAAsC;QAC7D,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,GAAG;YACb,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,KAAK;YACd,OAAO;YACP,OAAO,EAAE,CAAC,KAAY,EAAE,EAAE,CAAC;gBACzB,yEAAyE;gBACzE,MAAM,CAAC,IAAI,CAAE,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;YAAA,CAChC;SACF,CAAC;QACF,OAAO,CAAC,gBAAgB,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IACzE,CAAC;SAAM,CAAC;QACN,4EAA4E;QAC5E,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC;IAC/B,CAAC;AAAA,CACF,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SVG is weird. Some of the attributes are in camelCase, and some are in
|
|
3
|
+
* kebab-case. This methods takes into account SVG-based nuances and sets the
|
|
4
|
+
* given attribute in the right way.
|
|
5
|
+
*/
|
|
6
|
+
export declare const setSvgAttribute: (element: SVGElement, name: string, value: string) => void;
|
|
7
|
+
//# sourceMappingURL=svg.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svg.d.ts","sourceRoot":"","sources":["../../../../src/core/actions/dom/svg.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,eAAe,4DAW3B,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SVG is weird. Some of the attributes are in camelCase, and some are in
|
|
3
|
+
* kebab-case. This methods takes into account SVG-based nuances and sets the
|
|
4
|
+
* given attribute in the right way.
|
|
5
|
+
*/
|
|
6
|
+
export const setSvgAttribute = (element, name, value) => {
|
|
7
|
+
if (name === 'className') {
|
|
8
|
+
name = 'class';
|
|
9
|
+
}
|
|
10
|
+
else if (!SVG_CAMEL_ATTRS.has(name)) {
|
|
11
|
+
name = name.replace(/[A-Z]/g, (m) => '-' + m.toLowerCase());
|
|
12
|
+
}
|
|
13
|
+
element.setAttribute(name, value);
|
|
14
|
+
};
|
|
15
|
+
// Most of SVG attributes are in kebab-cases. Here is the list of exclusions.
|
|
16
|
+
const SVG_CAMEL_ATTRS = new Set([
|
|
17
|
+
'attributeName',
|
|
18
|
+
'repeatCount',
|
|
19
|
+
'attributeType',
|
|
20
|
+
'baseFrequency',
|
|
21
|
+
'baseProfile',
|
|
22
|
+
'calcMode',
|
|
23
|
+
'clipPathUnits',
|
|
24
|
+
'diffuseConstant',
|
|
25
|
+
'edgeMode',
|
|
26
|
+
'Experimental',
|
|
27
|
+
'filterUnits',
|
|
28
|
+
'gradientTransform',
|
|
29
|
+
'gradientUnits',
|
|
30
|
+
'kernelMatrix',
|
|
31
|
+
'kernelUnitLength',
|
|
32
|
+
'keyPoints',
|
|
33
|
+
'keySplines',
|
|
34
|
+
'keyTimes',
|
|
35
|
+
'lengthAdjust',
|
|
36
|
+
'limitingConeAngle',
|
|
37
|
+
'markerHeight',
|
|
38
|
+
'markerUnits',
|
|
39
|
+
'markerWidth',
|
|
40
|
+
'maskContentUnits',
|
|
41
|
+
'maskUnits',
|
|
42
|
+
'numOctaves',
|
|
43
|
+
'pathLength',
|
|
44
|
+
'patternContentUnits',
|
|
45
|
+
'patternTransform',
|
|
46
|
+
'patternUnits',
|
|
47
|
+
'pointsAtX',
|
|
48
|
+
'pointsAtY',
|
|
49
|
+
'pointsAtZ',
|
|
50
|
+
'preserveAlpha',
|
|
51
|
+
'preserveAspectRatio',
|
|
52
|
+
'primitiveUnits',
|
|
53
|
+
'refX',
|
|
54
|
+
'refY',
|
|
55
|
+
'repeatDur',
|
|
56
|
+
'requiredExtensions',
|
|
57
|
+
'requiredFeatures',
|
|
58
|
+
'Experimental',
|
|
59
|
+
'specularConstant',
|
|
60
|
+
'specularExponent',
|
|
61
|
+
'spreadMethod',
|
|
62
|
+
'startOffset',
|
|
63
|
+
'stdDeviation',
|
|
64
|
+
'stitchTiles',
|
|
65
|
+
'surfaceScale',
|
|
66
|
+
'systemLanguage',
|
|
67
|
+
'tableValues',
|
|
68
|
+
'targetX',
|
|
69
|
+
'targetY',
|
|
70
|
+
'textLength',
|
|
71
|
+
'viewBox',
|
|
72
|
+
'xChannelSelector',
|
|
73
|
+
'yChannelSelector',
|
|
74
|
+
'zoomAndPan',
|
|
75
|
+
]);
|
|
76
|
+
//# sourceMappingURL=svg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svg.js","sourceRoot":"","sources":["../../../../src/core/actions/dom/svg.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,OAAmB,EACnB,IAAY,EACZ,KAAa,EACP,EAAE,CAAC;IACT,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;QACzB,IAAI,GAAG,OAAO,CAAC;IACjB,CAAC;SAAM,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAAA,CACnC,CAAC;AAEF,6EAA6E;AAC7E,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;IAC9B,eAAe;IACf,aAAa;IACb,eAAe;IACf,eAAe;IACf,aAAa;IACb,UAAU;IACV,eAAe;IACf,iBAAiB;IACjB,UAAU;IACV,cAAc;IACd,aAAa;IACb,mBAAmB;IACnB,eAAe;IACf,cAAc;IACd,kBAAkB;IAClB,WAAW;IACX,YAAY;IACZ,UAAU;IACV,cAAc;IACd,mBAAmB;IACnB,cAAc;IACd,aAAa;IACb,aAAa;IACb,kBAAkB;IAClB,WAAW;IACX,YAAY;IACZ,YAAY;IACZ,qBAAqB;IACrB,kBAAkB;IAClB,cAAc;IACd,WAAW;IACX,WAAW;IACX,WAAW;IACX,eAAe;IACf,qBAAqB;IACrB,gBAAgB;IAChB,MAAM;IACN,MAAM;IACN,WAAW;IACX,oBAAoB;IACpB,kBAAkB;IAClB,cAAc;IACd,kBAAkB;IAClB,kBAAkB;IAClB,cAAc;IACd,aAAa;IACb,cAAc;IACd,aAAa;IACb,cAAc;IACd,gBAAgB;IAChB,aAAa;IACb,SAAS;IACT,SAAS;IACT,YAAY;IACZ,SAAS;IACT,kBAAkB;IAClB,kBAAkB;IAClB,YAAY;CACb,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { App, TagAttrValue, TagFiberNode } from '../../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Original React has a very special behavior for the "onChange" event:
|
|
4
|
+
* - It treats "onChange" as an "onInput" event for form controls
|
|
5
|
+
* - If the "value" prop is provided and is not `null` or `undefined`, React
|
|
6
|
+
* treats the input as "controlled" and ignores user changes by restoring the
|
|
7
|
+
* original value after each input event
|
|
8
|
+
* - Even for controlled inputs, React still calls the "onChange" handler with
|
|
9
|
+
* the updated event.target.value before restoring the previous value
|
|
10
|
+
* - React overrides the property descriptor of the "value" property on the DOM
|
|
11
|
+
* element to intercept and track all value changes
|
|
12
|
+
*/
|
|
13
|
+
export declare const setValueAttr: (fiber: TagFiberNode, attrName: "checked" | "value", attrValue: TagAttrValue) => void;
|
|
14
|
+
export declare const changeControlValue: (app: App, element: FormControl, attrName: "checked" | "value", valueRaw: unknown, restoreCursor?: boolean) => void;
|
|
15
|
+
type FormControl = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=value.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"value.d.ts","sourceRoot":"","sources":["../../../../src/core/actions/dom/value.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,GAAG,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAI1E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,uFAsCxB,CAAC;AAmBF,eAAO,MAAM,kBAAkB,qHAiC9B,CAAC;AA2KF,KAAK,WAAW,GAAG,gBAAgB,GAAG,mBAAmB,GAAG,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { getAppByFiber } from '../../../core/reconciliation/app';
|
|
2
|
+
import { scheduleEffect } from '../../../core/reconciliation/effects';
|
|
3
|
+
import { nullthrowsForFiber } from '../../../core/reconciliation/errors/ReactError';
|
|
4
|
+
const stores = new WeakMap();
|
|
5
|
+
/**
|
|
6
|
+
* Original React has a very special behavior for the "onChange" event:
|
|
7
|
+
* - It treats "onChange" as an "onInput" event for form controls
|
|
8
|
+
* - If the "value" prop is provided and is not `null` or `undefined`, React
|
|
9
|
+
* treats the input as "controlled" and ignores user changes by restoring the
|
|
10
|
+
* original value after each input event
|
|
11
|
+
* - Even for controlled inputs, React still calls the "onChange" handler with
|
|
12
|
+
* the updated event.target.value before restoring the previous value
|
|
13
|
+
* - React overrides the property descriptor of the "value" property on the DOM
|
|
14
|
+
* element to intercept and track all value changes
|
|
15
|
+
*/
|
|
16
|
+
export const setValueAttr = (fiber, attrName, attrValue) => {
|
|
17
|
+
const element = fiber.element;
|
|
18
|
+
const app = getAppByFiber(fiber);
|
|
19
|
+
// We continue to reference the same `events` object even after calling
|
|
20
|
+
// `displaceFiber`, so this assumption should hold
|
|
21
|
+
const { events } = fiber.data;
|
|
22
|
+
if (!events[VALUE_EVENT]) {
|
|
23
|
+
const store = setUpStore(app, element, attrName);
|
|
24
|
+
const onInput = createOnInputHandler(app, element, attrName, store);
|
|
25
|
+
events[VALUE_EVENT] = {
|
|
26
|
+
name: 'input',
|
|
27
|
+
handler: null,
|
|
28
|
+
capture: false,
|
|
29
|
+
wrapper: onInput,
|
|
30
|
+
};
|
|
31
|
+
element.addEventListener('input', onInput, {
|
|
32
|
+
capture: events[VALUE_EVENT].capture,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
const store = nullthrowsForFiber(fiber, stores.get(element));
|
|
36
|
+
store.prev = attrValue;
|
|
37
|
+
if (attrValue != null) {
|
|
38
|
+
store.set(attrValue, true);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const VALUE_EVENT = 'x:input';
|
|
42
|
+
const setUpStore = (app, element, attrName) => {
|
|
43
|
+
const store = {
|
|
44
|
+
prev: null,
|
|
45
|
+
cursor: null,
|
|
46
|
+
set: changeControlValue.bind(null, app, element, attrName),
|
|
47
|
+
};
|
|
48
|
+
stores.set(element, store);
|
|
49
|
+
return store;
|
|
50
|
+
};
|
|
51
|
+
export const changeControlValue = (app, element, attrName, valueRaw, restoreCursor = false) => {
|
|
52
|
+
const value = toNativeValue(attrName, valueRaw);
|
|
53
|
+
if (element instanceof HTMLSelectElement) {
|
|
54
|
+
setSelectValue(app, element, value);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (element[attrName] === value) {
|
|
58
|
+
// Don't touch the value to avoid moving the cursor.
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
// Non-reactively update the native value.
|
|
62
|
+
element[attrName] = value;
|
|
63
|
+
if ((element instanceof HTMLInputElement ||
|
|
64
|
+
element instanceof HTMLTextAreaElement) &&
|
|
65
|
+
attrName === 'value' &&
|
|
66
|
+
restoreCursor) {
|
|
67
|
+
const store = stores.get(element);
|
|
68
|
+
if (store.cursor != null) {
|
|
69
|
+
element.selectionStart = element.selectionEnd = store.cursor;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
const createOnInputHandler = (app, element, attrName, store) => {
|
|
74
|
+
return function onInput() {
|
|
75
|
+
if (element instanceof HTMLInputElement &&
|
|
76
|
+
element.type === 'radio' &&
|
|
77
|
+
element.name) {
|
|
78
|
+
// Radio buttons require special group-based handling
|
|
79
|
+
onRadioClick(app, element);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const newValue = element[attrName];
|
|
83
|
+
if (store.prev == null)
|
|
84
|
+
return; // Uncontrolled component - allow changes
|
|
85
|
+
if (store.prev === newValue)
|
|
86
|
+
return; // No actual change occurred
|
|
87
|
+
scheduleResetValueEffect(app, () => {
|
|
88
|
+
// The following render could make the control uncontrolled. In such a
|
|
89
|
+
// case we shouldn't restore the value. Now it's in free flight.
|
|
90
|
+
if (store.prev == null)
|
|
91
|
+
return;
|
|
92
|
+
if ((element instanceof HTMLInputElement ||
|
|
93
|
+
element instanceof HTMLTextAreaElement) &&
|
|
94
|
+
attrName === 'value') {
|
|
95
|
+
store.cursor = element.selectionStart;
|
|
96
|
+
}
|
|
97
|
+
// Restore the previous value since this is a controlled element
|
|
98
|
+
store.set(store.prev);
|
|
99
|
+
});
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Radio button group handling:
|
|
104
|
+
*
|
|
105
|
+
* - Browsers don't emit "change" or "input" events for radio buttons that lose
|
|
106
|
+
* their "checked" state when another radio in the group is selected. The
|
|
107
|
+
* state change happens silently.
|
|
108
|
+
* - When a user selects a different radio button, the browser only emits an
|
|
109
|
+
* "input" event for the newly selected button. The event provides no
|
|
110
|
+
* information about which radio button was previously active.
|
|
111
|
+
* - Radio buttons form a group when they share the same "name" attribute within
|
|
112
|
+
* their containing <form> (or document if no form exists).
|
|
113
|
+
*
|
|
114
|
+
* This function enforces React's "controlled component" behavior for radio
|
|
115
|
+
* button groups. If any radio button in the group has "checked=true", all other
|
|
116
|
+
* radio buttons in the group must have "checked=false", even if they don't
|
|
117
|
+
* explicitly define a "checked" attribute (React assumes they do).
|
|
118
|
+
*/
|
|
119
|
+
const onRadioClick = (app, element) => {
|
|
120
|
+
scheduleResetValueEffect(app, () => {
|
|
121
|
+
// Find all radio buttons in the same group (same name within the form)
|
|
122
|
+
const form = element.closest('form') ?? app.root.element;
|
|
123
|
+
const radios = form.querySelectorAll(`input[type="radio"]`);
|
|
124
|
+
// Look for a radio button that was previously controlled with checked=true
|
|
125
|
+
for (let i = 0; i < radios.length; ++i) {
|
|
126
|
+
const radio = radios[i];
|
|
127
|
+
if (radio.name === element.name && stores.get(radio)?.prev === true) {
|
|
128
|
+
// Restore the previously checked radio button's state, which will
|
|
129
|
+
// automatically uncheck the currently selected one. The correct state
|
|
130
|
+
// will be updated in the next render if setState was called from the
|
|
131
|
+
// user's onChange handler
|
|
132
|
+
stores.get(radio).set(true);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const store = stores.get(element);
|
|
137
|
+
if (typeof store?.prev === 'boolean') {
|
|
138
|
+
// A single uncontrolled radio button with checked="false".
|
|
139
|
+
store.set(store.prev);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Converts React prop values to native DOM values:
|
|
145
|
+
* - value: null | undefined → '' (empty string, not "null")
|
|
146
|
+
* - checked: any value → boolean conversion
|
|
147
|
+
*/
|
|
148
|
+
const toNativeValue = (attrName, newValue) => attrName === 'checked'
|
|
149
|
+
? !!newValue
|
|
150
|
+
: newValue == null
|
|
151
|
+
? '' // not "null"
|
|
152
|
+
: Array.isArray(newValue)
|
|
153
|
+
? newValue.map((v) => String(v))
|
|
154
|
+
: String(newValue);
|
|
155
|
+
/**
|
|
156
|
+
* Schedules value restoration for controlled form elements.
|
|
157
|
+
*
|
|
158
|
+
* React maintains the value attribute for "controlled" HTML form controls,
|
|
159
|
+
* where only setState and subsequent renders can update their value. However,
|
|
160
|
+
* there's a brief window between the "onInput" event and the DOM/React render
|
|
161
|
+
* where the new value hasn't been reset yet. This function ensures the callback
|
|
162
|
+
* runs at the appropriate time to restore the controlled value.
|
|
163
|
+
*/
|
|
164
|
+
const scheduleResetValueEffect = (app, fn) => {
|
|
165
|
+
let executed = false;
|
|
166
|
+
requestAnimationFrame(() => {
|
|
167
|
+
if (!executed) {
|
|
168
|
+
executed = true;
|
|
169
|
+
fn();
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
scheduleEffect(app, () => {
|
|
173
|
+
if (!executed) {
|
|
174
|
+
executed = true;
|
|
175
|
+
fn();
|
|
176
|
+
}
|
|
177
|
+
}, 'afterActions');
|
|
178
|
+
};
|
|
179
|
+
/**
|
|
180
|
+
* <select/> & <select multiple/> are very special cases.
|
|
181
|
+
* - When it has only one item selected its behavior is similar to single-mode
|
|
182
|
+
* selects. `value` reflects the only selected option's value.
|
|
183
|
+
* - When there is a multiple selection `value` reflects only the name of the
|
|
184
|
+
* 1st selected option, completely ignoring the rest of them.
|
|
185
|
+
*
|
|
186
|
+
* So, how do we handle it without `value`? We just need to update `selected`
|
|
187
|
+
* for each of the <option/>s.
|
|
188
|
+
*/
|
|
189
|
+
const setSelectValue = (app, element, value) => {
|
|
190
|
+
// Unfortunately, we can't do it right away, because:
|
|
191
|
+
// 1. on the 1st render we have no inner options here yet
|
|
192
|
+
// 2. on subsequent render the inner options may not be fully updated yet.
|
|
193
|
+
scheduleResetValueEffect(app, () => {
|
|
194
|
+
const arr = Array.isArray(value) ? value : [value];
|
|
195
|
+
const set = new Set(arr.map((v) => String(v)));
|
|
196
|
+
for (const option of element.options) {
|
|
197
|
+
const selected = set.has(option.value);
|
|
198
|
+
if (option.selected !== selected) {
|
|
199
|
+
option.selected = selected;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
};
|
|
204
|
+
//# sourceMappingURL=value.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"value.js","sourceRoot":"","sources":["../../../../src/core/actions/dom/value.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type DomNode, type FiberNode, type TagFiberNode } from '../../types';
|
|
2
2
|
/**
|
|
3
3
|
* Determines if a prop name represents an event handler by checking if it
|
|
4
4
|
* starts with "on". This follows React's convention where any prop beginning
|
|
@@ -13,31 +13,38 @@ import type { DomNode, FiberNode, Ref, RefSetter } from '../../types';
|
|
|
13
13
|
export declare const isEventName: (name: string) => boolean;
|
|
14
14
|
/**
|
|
15
15
|
* Returns the DOM container for the given fiber node. This isn't always the
|
|
16
|
-
* direct parent's element since the parent might be a
|
|
17
|
-
*
|
|
16
|
+
* direct parent's element since the parent might be a component, a fragment, or
|
|
17
|
+
* a portal node.
|
|
18
18
|
*/
|
|
19
19
|
export declare const getParentElement: (fiber: FiberNode) => Element;
|
|
20
|
+
export declare const asElement: (node: Node | null) => Element;
|
|
20
21
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* element;
|
|
24
|
-
* 2) [element, child] - the new node should be added right after `child`.
|
|
22
|
+
* Returns the 1st DOM-node of the given auto-container fiber. Pass custom
|
|
23
|
+
* `children` if `fiber`'s children are incorrect.
|
|
25
24
|
*/
|
|
26
|
-
export declare const
|
|
25
|
+
export declare const getFirstContainerElement: (fiber: FiberNode, children?: FiberNode[]) => DomNode;
|
|
26
|
+
/** Returns the last DOM-node of the given auto-container fiber */
|
|
27
|
+
export declare const getLastContainerElement: (fiber: FiberNode) => DomNode;
|
|
27
28
|
/**
|
|
28
29
|
* Returns all direct DOM nodes associated with the given fiber. This isn't
|
|
29
|
-
* always a single node since components and fragments may be in
|
|
30
|
-
*
|
|
30
|
+
* always a single node since components and fragments may be in the
|
|
31
|
+
* auto-container mode. That means they contain more then one direct DOM-nodes
|
|
32
|
+
* that are inlined into the `fiber`'s DOM container.
|
|
31
33
|
*/
|
|
32
34
|
export declare const getFiberDomNodes: (fiber: FiberNode) => DomNode[];
|
|
33
35
|
/**
|
|
34
36
|
* When a node leaves the DOM tree, we need to update all associated ref
|
|
35
37
|
* objects and ref handlers.
|
|
36
38
|
*/
|
|
37
|
-
export declare const unsetRef:
|
|
39
|
+
export declare const unsetRef: (fiber: TagFiberNode, immediate: boolean) => void;
|
|
38
40
|
/**
|
|
39
41
|
* To help avoid memory leaks, this method removes fiber properties that
|
|
40
42
|
* can hold references to other objects.
|
|
41
43
|
*/
|
|
42
44
|
export declare const emptyFiberNode: (fiber: FiberNode) => void;
|
|
45
|
+
/**
|
|
46
|
+
* Calls the given fn against every single child in the fiben fiber tree.
|
|
47
|
+
* Return `false` to stop traversing right away.
|
|
48
|
+
*/
|
|
49
|
+
export declare const traverseFiberTree: (fiber: FiberNode, fn: (fiber: FiberNode) => void | boolean) => boolean;
|
|
43
50
|
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/core/actions/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/core/actions/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,YAAY,EAClB,MAAM,oBAAoB,CAAC;AAc5B;;;;;;;;;;GAUG;AACH,eAAO,MAAM,WAAW,2BAAmD,CAAC;AAE5E;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,+BAa5B,CAAC;AAEF,eAAO,MAAM,SAAS,gCAMrB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,uDAUpC,CAAC;AAEF,kEAAkE;AAClE,eAAO,MAAM,uBAAuB,+BAOnC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,iCAuC5B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,QAAQ,mDAsBpB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,4BAW1B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,yEAe7B,CAAC"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { isEmptyContainer, isSingleChildContainer, isAutoContainer, } from '../compact';
|
|
2
|
+
import { isFiberDead, NULL_FIBER } from '../reconciliation/fibers';
|
|
3
|
+
import { scheduleEffect } from '../reconciliation/effects';
|
|
4
|
+
import { getAppByFiber } from '../reconciliation/app';
|
|
5
|
+
import { nullthrowsForFiber, ReactError, } from '../reconciliation/errors/ReactError';
|
|
5
6
|
/**
|
|
6
7
|
* Determines if a prop name represents an event handler by checking if it
|
|
7
8
|
* starts with "on". This follows React's convention where any prop beginning
|
|
@@ -16,8 +17,8 @@ import { buildCommentText } from '../reconciliation/comments';
|
|
|
16
17
|
export const isEventName = (name) => name.startsWith('on');
|
|
17
18
|
/**
|
|
18
19
|
* Returns the DOM container for the given fiber node. This isn't always the
|
|
19
|
-
* direct parent's element since the parent might be a
|
|
20
|
-
*
|
|
20
|
+
* direct parent's element since the parent might be a component, a fragment, or
|
|
21
|
+
* a portal node.
|
|
21
22
|
*/
|
|
22
23
|
export const getParentElement = (fiber) => {
|
|
23
24
|
while (fiber.parent.type === 'component' ||
|
|
@@ -27,99 +28,91 @@ export const getParentElement = (fiber) => {
|
|
|
27
28
|
if (fiber.parent.data instanceof HTMLElement) {
|
|
28
29
|
return fiber.parent.data; // Portal.
|
|
29
30
|
}
|
|
30
|
-
return
|
|
31
|
+
return nullthrowsForFiber(fiber, fiber.parent?.element);
|
|
31
32
|
};
|
|
32
|
-
|
|
33
|
-
* Finds the !--begin comment for the given !--end comment.
|
|
34
|
-
*/
|
|
35
|
-
const getBeginComment = (fiber) => {
|
|
36
|
-
let node = asComment(fiber.element).previousSibling;
|
|
37
|
-
const text = buildCommentText('begin', fiber.id);
|
|
38
|
-
while (!(node instanceof Comment) || node.textContent !== text)
|
|
39
|
-
node = nullthrows(node.previousSibling);
|
|
40
|
-
return node;
|
|
41
|
-
};
|
|
42
|
-
const asElement = (node) => {
|
|
33
|
+
export const asElement = (node) => {
|
|
43
34
|
if (!(node instanceof Element)) {
|
|
44
35
|
throw new Error(`node is not element`);
|
|
45
36
|
}
|
|
46
37
|
return node;
|
|
47
38
|
};
|
|
48
|
-
const asComment = (node) => {
|
|
49
|
-
if (!(node instanceof Comment)) {
|
|
50
|
-
throw new Error(`node is not comment`);
|
|
51
|
-
}
|
|
52
|
-
return node;
|
|
53
|
-
};
|
|
54
39
|
/**
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* element;
|
|
58
|
-
* 2) [element, child] - the new node should be added right after `child`.
|
|
40
|
+
* Returns the 1st DOM-node of the given auto-container fiber. Pass custom
|
|
41
|
+
* `children` if `fiber`'s children are incorrect.
|
|
59
42
|
*/
|
|
60
|
-
export const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
? fiber.data // Portal's `element` is !--r:portal
|
|
65
|
-
: fiber.element),
|
|
66
|
-
null,
|
|
67
|
-
];
|
|
43
|
+
export const getFirstContainerElement = (fiber, children = fiber.children) => {
|
|
44
|
+
let [firstNode] = children;
|
|
45
|
+
while (!(firstNode.element instanceof Node)) {
|
|
46
|
+
[firstNode] = firstNode.children;
|
|
68
47
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
// E.g.
|
|
77
|
-
// <div>
|
|
78
|
-
// <something/>
|
|
79
|
-
// <!--r:begin:1--> // a component or a fragment
|
|
80
|
-
// … // the content of the `fiber`
|
|
81
|
-
// <!--r:end:1-->
|
|
82
|
-
// <something/>
|
|
83
|
-
return [getParentElement(fiber), getBeginComment(fiber)];
|
|
48
|
+
return firstNode.element;
|
|
49
|
+
};
|
|
50
|
+
/** Returns the last DOM-node of the given auto-container fiber */
|
|
51
|
+
export const getLastContainerElement = (fiber) => {
|
|
52
|
+
let lastNode = fiber.children.at(-1);
|
|
53
|
+
while (!(lastNode.element instanceof Node)) {
|
|
54
|
+
lastNode = lastNode.children.at(-1);
|
|
84
55
|
}
|
|
85
|
-
|
|
86
|
-
throw new Error(`Unsupported anchor type: ${fiber.type}`);
|
|
56
|
+
return lastNode.element;
|
|
87
57
|
};
|
|
88
58
|
/**
|
|
89
59
|
* Returns all direct DOM nodes associated with the given fiber. This isn't
|
|
90
|
-
* always a single node since components and fragments may be in
|
|
91
|
-
*
|
|
60
|
+
* always a single node since components and fragments may be in the
|
|
61
|
+
* auto-container mode. That means they contain more then one direct DOM-nodes
|
|
62
|
+
* that are inlined into the `fiber`'s DOM container.
|
|
92
63
|
*/
|
|
93
64
|
export const getFiberDomNodes = (fiber) => {
|
|
65
|
+
if (isFiberDead(fiber)) {
|
|
66
|
+
throw new ReactError(fiber, `Can't get fiber children for a dead fiber`);
|
|
67
|
+
}
|
|
94
68
|
switch (fiber.type) {
|
|
95
69
|
case 'component':
|
|
96
70
|
case 'fragment': {
|
|
97
|
-
if (
|
|
98
|
-
|
|
71
|
+
if (isAutoContainer(fiber)) {
|
|
72
|
+
const first = getFirstContainerElement(fiber);
|
|
73
|
+
const last = getLastContainerElement(fiber);
|
|
74
|
+
const result = [first];
|
|
75
|
+
let domNode = first.nextSibling;
|
|
76
|
+
while (domNode !== last) {
|
|
77
|
+
result.push(domNode);
|
|
78
|
+
domNode = domNode.nextSibling;
|
|
79
|
+
}
|
|
80
|
+
result.push(last);
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
if (isSingleChildContainer(fiber)) {
|
|
84
|
+
return getFiberDomNodes(fiber.children[0]);
|
|
99
85
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
let prev = nullthrows(list[0].previousSibling);
|
|
103
|
-
while (prev && !isBeginOf(prev, fiber)) {
|
|
104
|
-
list.push(prev);
|
|
105
|
-
prev = nullthrows(prev.previousSibling);
|
|
86
|
+
if (isEmptyContainer(fiber)) {
|
|
87
|
+
return [fiber.element];
|
|
106
88
|
}
|
|
107
|
-
|
|
108
|
-
return list.reverse();
|
|
89
|
+
throw new ReactError(fiber, `Unknown kind of fiber`);
|
|
109
90
|
}
|
|
110
91
|
case 'null':
|
|
111
92
|
case 'tag':
|
|
112
93
|
case 'text':
|
|
113
|
-
return [
|
|
94
|
+
return [nullthrowsForFiber(fiber, fiber.element)];
|
|
114
95
|
}
|
|
115
96
|
};
|
|
116
97
|
/**
|
|
117
98
|
* When a node leaves the DOM tree, we need to update all associated ref
|
|
118
99
|
* objects and ref handlers.
|
|
119
100
|
*/
|
|
120
|
-
export const unsetRef = (
|
|
101
|
+
export const unsetRef = (fiber, immediate) => {
|
|
102
|
+
const { ref } = fiber;
|
|
121
103
|
if (typeof ref === 'function') {
|
|
122
|
-
|
|
104
|
+
if (immediate) {
|
|
105
|
+
ref(null);
|
|
106
|
+
// TODO: add a test ^.
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
// It can be a setter (e.g., <div onRef={setContainer}/>). Since we
|
|
110
|
+
// shouldn't allow invalidating components during commit phase we need
|
|
111
|
+
// to schedule an async update.
|
|
112
|
+
scheduleEffect(getAppByFiber(fiber), () => {
|
|
113
|
+
ref(null);
|
|
114
|
+
}, 'refsUnmount');
|
|
115
|
+
}
|
|
123
116
|
}
|
|
124
117
|
else {
|
|
125
118
|
ref.current = null;
|
|
@@ -130,6 +123,8 @@ export const unsetRef = (ref) => {
|
|
|
130
123
|
* can hold references to other objects.
|
|
131
124
|
*/
|
|
132
125
|
export const emptyFiberNode = (fiber) => {
|
|
126
|
+
// For debug purposes mark dead nodes with a negative number.
|
|
127
|
+
fiber.id = -fiber.id;
|
|
133
128
|
fiber.data = null;
|
|
134
129
|
fiber.element = null;
|
|
135
130
|
fiber.component = null;
|
|
@@ -138,4 +133,19 @@ export const emptyFiberNode = (fiber) => {
|
|
|
138
133
|
fiber.ref = null;
|
|
139
134
|
fiber.parent = NULL_FIBER;
|
|
140
135
|
};
|
|
136
|
+
/**
|
|
137
|
+
* Calls the given fn against every single child in the fiben fiber tree.
|
|
138
|
+
* Return `false` to stop traversing right away.
|
|
139
|
+
*/
|
|
140
|
+
export const traverseFiberTree = (fiber, fn) => {
|
|
141
|
+
if (fn(fiber) === false) {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
for (const child of fiber.children) {
|
|
145
|
+
if (traverseFiberTree(child, fn) === false) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return true;
|
|
150
|
+
};
|
|
141
151
|
//# sourceMappingURL=helpers.js.map
|