mirror of
https://github.com/bendtherules/react-fiber-traverse.git
synced 2026-08-18 13:52:36 +00:00
Compare commits
34
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c019a5fd2 | ||
|
|
be7ec5d869 | ||
|
|
6bb43e34e2 | ||
|
|
d630d21b23 | ||
|
|
693dd69d32 | ||
|
|
f01ae4fb2a | ||
|
|
1ef5941a9e | ||
|
|
e7e969cf65 | ||
|
|
8326ec5bf7 | ||
|
|
0bc8c1af99 | ||
|
|
aced1be6e8 | ||
|
|
492e69f4dd | ||
|
|
94ab7112f7 | ||
|
|
808ed790f3 | ||
|
|
817242dd25 | ||
|
|
827b282064 | ||
|
|
c71b9ad531 | ||
|
|
01e6932cd5 | ||
|
|
215153c516 | ||
|
|
fd6dad21ad | ||
|
|
30b1bfefea | ||
|
|
e870a92e4b | ||
|
|
6cffc96d60 | ||
|
|
4824828b51 | ||
|
|
5a2e7f1375 | ||
|
|
977a376cad | ||
|
|
21231fcb11 | ||
|
|
b09af700c9 | ||
|
|
55152a1be7 | ||
|
|
8a69d1f1ca | ||
|
|
c40fc9b2c4 | ||
|
|
18ea2e7d2a | ||
|
|
e01fc3ab0b | ||
|
|
ba2e842338 |
Vendored
+2
-1
@@ -13,5 +13,6 @@
|
||||
"javascriptreact",
|
||||
"typescript",
|
||||
"typescriptreact"
|
||||
]
|
||||
],
|
||||
"typescript.tsdk": "node_modules\\typescript\\lib"
|
||||
}
|
||||
@@ -10,28 +10,39 @@
|
||||
## Basic Usage
|
||||
|
||||
```ts
|
||||
import { render } from 'react-dom'
|
||||
import React from "react";
|
||||
import { render } from "react-dom";
|
||||
|
||||
import { findNodeByComponentName, Utils } from 'react-fiber-traverse'
|
||||
import { findNodeByComponentName, Utils } from "react-fiber-traverse";
|
||||
|
||||
const rootElement = document.getElementById('root');
|
||||
render(<App>, 'root');
|
||||
// Sample component
|
||||
// Say, if SomeComponentName looks like this -
|
||||
function SomeComponentName() {
|
||||
return <div>Some text</div>;
|
||||
}
|
||||
|
||||
// Render component
|
||||
const rootElement = document.getElementById("root");
|
||||
render(<SomeComponentName />, rootElement);
|
||||
|
||||
// Get root node
|
||||
const rootFiberNode = Utils.getRootFiberNodeFromDOM(rootElement);
|
||||
|
||||
const someFiberNode = findNodeByComponentName(rootFiberNode, 'SomeComponentName'); // <- returns FiberNode for first usage of 'SomeComponentName'
|
||||
// Say, if SomeComponentName renders (<div>Some text</div>)
|
||||
someFiberNode.stateNode // <- returns reference to the div
|
||||
someFiberNode.stateNode.innerText // <- returns 'Some text'
|
||||
// Get component node
|
||||
const someFiberNode = findNodeByComponentName(
|
||||
rootFiberNode,
|
||||
"SomeComponentName"
|
||||
); // <- returns FiberNode for first usage of 'SomeComponentName'
|
||||
|
||||
console.log(someFiberNode.child.stateNode); // <- returns reference to the div
|
||||
console.log(someFiberNode.child.stateNode.innerText); // <- returns 'Some text'
|
||||
|
||||
```
|
||||
|
||||
## Live Examples
|
||||
|
||||
- [Basic Usage](https://codesandbox.io/)
|
||||
- [API Example](https://codesandbox.io/)
|
||||
- [UMD Build (Development)](https://codesandbox.io/)
|
||||
- [UMD Build (Production)](https://codesandbox.io/)
|
||||
|
||||
- [Basic Usage](https://codesandbox.io/s/react-example-x82zk?expanddevtools=1&fontsize=14)
|
||||
<!--
|
||||
## API
|
||||
|
||||
**Props**
|
||||
@@ -42,7 +53,7 @@ someFiberNode.stateNode.innerText // <- returns 'Some text'
|
||||
**Example**
|
||||
|
||||
```jsx
|
||||
```
|
||||
``` -->
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -65,6 +76,38 @@ For the minified production version, make sure you have already included:
|
||||
- [`React`](https://unpkg.com/react/umd/react.production.min.js)
|
||||
- [`ReactDOM`](https://unpkg.com/react-dom/umd/react-dom.production.min.js)
|
||||
|
||||
## Overview
|
||||
|
||||
This package contains few utility functions which operate over react-fiber tree.
|
||||
|
||||
Overall characteristics are:
|
||||
1. Only read-only operations
|
||||
2. Support inversion of control
|
||||
|
||||
There are few categories of helpers, each with their variations:
|
||||
1. Find node(s)
|
||||
2. Traverse node
|
||||
3. Others - Check node type, find root node, etc.
|
||||
|
||||
Little more info is present in docs section.
|
||||
|
||||
## Concerns and improvements
|
||||
|
||||
Currently, it assumes that nodes are created by `react 16.3+` with appropriate `react-dom`.
|
||||
|
||||
Because fiber nodes are internal to react and are supported by multiple renderers, this is an incorrect assumption to make. It should:
|
||||
1. support diff versions of react (which have fiber node, but slight variations of it)
|
||||
2. be renderer-agnostic (say, support react-fs-renderer) but with extra helpers for react-dom.
|
||||
3. heavily tested with all these variations (to know when internals have changed).
|
||||
|
||||
## Docs
|
||||
|
||||
Docs are sparse at the moment. I plan on adding them soon.
|
||||
|
||||
Till then, the auto-generated (typedoc) docs available in [docs folder](./docs/globals.md) might be of some help.
|
||||
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
4. Build some demo
|
||||
|
||||
5. Add `findAllNodes` helpers which searches all usages of the components - by name or class
|
||||
6. Allow using all methods without explicit root node. Find automatically, if not provided.
|
||||
|
||||
6. Fix getRootFiberNodeFromDOM and related helpers -
|
||||
- .\_internalRoot is not present is 16.0.0 but present in 16.9.0
|
||||
@@ -14,3 +15,10 @@
|
||||
|
||||
7. Make it work with older React versions
|
||||
8. Make it work with non React-DOM renderers
|
||||
|
||||
9. Add test - traverseGenerator - siblings were traversed earlier, not now. Check input config.
|
||||
|
||||
10. Find node by CSS (query language) - Make it work for Class/Function reference also
|
||||
11. Allow easy way to continue FiberNode select with CSS selector for dom node (handling Fragments)
|
||||
|
||||
12. Helper and filter by props and state
|
||||
+60
-11
@@ -13,20 +13,40 @@
|
||||
|
||||
## Basic Usage
|
||||
|
||||
```jsx
|
||||
import React from 'react'
|
||||
import { render } from 'react-dom'
|
||||
```ts
|
||||
import React from "react";
|
||||
import { render } from "react-dom";
|
||||
|
||||
import { findNodeByComponentName, Utils } from "react-fiber-traverse";
|
||||
|
||||
// Sample component
|
||||
// Say, if SomeComponentName looks like this -
|
||||
function SomeComponentName() {
|
||||
return <div>Some text</div>;
|
||||
}
|
||||
|
||||
// Render component
|
||||
const rootElement = document.getElementById("root");
|
||||
render(<SomeComponentName />, rootElement);
|
||||
|
||||
// Get root node
|
||||
const rootFiberNode = Utils.getRootFiberNodeFromDOM(rootElement);
|
||||
|
||||
// Get component node
|
||||
const someFiberNode = findNodeByComponentName(
|
||||
rootFiberNode,
|
||||
"SomeComponentName"
|
||||
); // <- returns FiberNode for first usage of 'SomeComponentName'
|
||||
|
||||
console.log(someFiberNode.child.stateNode); // <- returns reference to the div
|
||||
console.log(someFiberNode.child.stateNode.innerText); // <- returns 'Some text'
|
||||
|
||||
render(, document.getElementById('root'))
|
||||
```
|
||||
|
||||
## Live Examples
|
||||
|
||||
- [Basic Usage](https://codesandbox.io/)
|
||||
- [API Example](https://codesandbox.io/)
|
||||
- [UMD Build (Development)](https://codesandbox.io/)
|
||||
- [UMD Build (Production)](https://codesandbox.io/)
|
||||
|
||||
- [Basic Usage](https://codesandbox.io/s/react-example-x82zk?expanddevtools=1&fontsize=14)
|
||||
<!--
|
||||
## API
|
||||
|
||||
**Props**
|
||||
@@ -37,7 +57,7 @@ render(, document.getElementById('root'))
|
||||
**Example**
|
||||
|
||||
```jsx
|
||||
```
|
||||
``` -->
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -54,13 +74,42 @@ For the non-minified development version, make sure you have already included:
|
||||
|
||||
- [`React`](https://unpkg.com/react/umd/react.development.js)
|
||||
- [`ReactDOM`](https://unpkg.com/react-dom/umd/react-dom.development.js)
|
||||
- [`PropTypes`](https://unpkg.com/prop-types/prop-types.js)
|
||||
|
||||
For the minified production version, make sure you have already included:
|
||||
|
||||
- [`React`](https://unpkg.com/react/umd/react.production.min.js)
|
||||
- [`ReactDOM`](https://unpkg.com/react-dom/umd/react-dom.production.min.js)
|
||||
|
||||
## Overview
|
||||
|
||||
This package contains few utility functions which operate over react-fiber tree.
|
||||
|
||||
Overall characteristics are:
|
||||
1. Only read-only operations
|
||||
2. Support inversion of control
|
||||
|
||||
There are few categories of helpers, each with their variations:
|
||||
1. Find node(s)
|
||||
2. Traverse node
|
||||
3. Others - Check node type, find root node, etc.
|
||||
|
||||
Little more info is present in docs section.
|
||||
|
||||
## Concerns and improvements
|
||||
|
||||
Currently, it assumes that nodes are created by `react 16.3+` with appropriate `react-dom`.
|
||||
|
||||
Because fiber nodes are internal to react and are supported by multiple renderers, this is an incorrect assumption to make. It should:
|
||||
1. support diff versions of react (which have fiber node, but slight variations of it)
|
||||
2. be renderer-agnostic (say, support react-fs-renderer) but with extra helpers for react-dom.
|
||||
3. heavily tested with all these variations (to know when internals have changed).
|
||||
|
||||
## Docs
|
||||
|
||||
Docs are sparse at the moment. I plan on adding them soon.
|
||||
|
||||
Till then, the auto-generated (typedoc) docs available in [docs folder](./docs/globals.md) might be of some help.
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -24,7 +24,7 @@
|
||||
|
||||
• **child**: *[FiberNode](../modules/_mocked_types_index_.md#fibernode) | null*
|
||||
|
||||
*Defined in [mocked-types/index.ts:20](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L20)*
|
||||
*Defined in [mocked-types/index.ts:28](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L28)*
|
||||
|
||||
___
|
||||
|
||||
@@ -32,7 +32,7 @@ ___
|
||||
|
||||
• **elementType**: *`ComponentClass`*
|
||||
|
||||
*Defined in [mocked-types/index.ts:23](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L23)*
|
||||
*Defined in [mocked-types/index.ts:31](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L31)*
|
||||
|
||||
___
|
||||
|
||||
@@ -40,7 +40,7 @@ ___
|
||||
|
||||
• **sibling**: *[FiberNode](../modules/_mocked_types_index_.md#fibernode) | null*
|
||||
|
||||
*Defined in [mocked-types/index.ts:21](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L21)*
|
||||
*Defined in [mocked-types/index.ts:29](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L29)*
|
||||
|
||||
___
|
||||
|
||||
@@ -48,7 +48,7 @@ ___
|
||||
|
||||
• **stateNode**: *`Component`*
|
||||
|
||||
*Defined in [mocked-types/index.ts:26](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L26)*
|
||||
*Defined in [mocked-types/index.ts:34](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L34)*
|
||||
|
||||
___
|
||||
|
||||
@@ -56,4 +56,4 @@ ___
|
||||
|
||||
• **type**: *`ComponentClass`*
|
||||
|
||||
*Defined in [mocked-types/index.ts:24](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L24)*
|
||||
*Defined in [mocked-types/index.ts:32](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L32)*
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
• **child**: *[FiberNode](../modules/_mocked_types_index_.md#fibernode) | null*
|
||||
|
||||
*Defined in [mocked-types/index.ts:10](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L10)*
|
||||
*Defined in [mocked-types/index.ts:18](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L18)*
|
||||
|
||||
___
|
||||
|
||||
@@ -32,7 +32,7 @@ ___
|
||||
|
||||
• **elementType**: *`FunctionComponent`*
|
||||
|
||||
*Defined in [mocked-types/index.ts:13](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L13)*
|
||||
*Defined in [mocked-types/index.ts:21](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L21)*
|
||||
|
||||
___
|
||||
|
||||
@@ -40,7 +40,7 @@ ___
|
||||
|
||||
• **sibling**: *[FiberNode](../modules/_mocked_types_index_.md#fibernode) | null*
|
||||
|
||||
*Defined in [mocked-types/index.ts:11](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L11)*
|
||||
*Defined in [mocked-types/index.ts:19](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L19)*
|
||||
|
||||
___
|
||||
|
||||
@@ -48,7 +48,7 @@ ___
|
||||
|
||||
• **stateNode**: *null*
|
||||
|
||||
*Defined in [mocked-types/index.ts:16](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L16)*
|
||||
*Defined in [mocked-types/index.ts:24](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L24)*
|
||||
|
||||
___
|
||||
|
||||
@@ -56,4 +56,4 @@ ___
|
||||
|
||||
• **type**: *`FunctionComponent`*
|
||||
|
||||
*Defined in [mocked-types/index.ts:14](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L14)*
|
||||
*Defined in [mocked-types/index.ts:22](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L22)*
|
||||
@@ -24,9 +24,9 @@
|
||||
|
||||
• **child**: *[FiberNode](../modules/_mocked_types_index_.md#fibernode) | null*
|
||||
|
||||
*Defined in [mocked-types/index.ts:30](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L30)*
|
||||
*Defined in [mocked-types/index.ts:38](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L38)*
|
||||
|
||||
*Defined in [mocked-types/index.ts:40](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L40)*
|
||||
*Defined in [mocked-types/index.ts:48](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L48)*
|
||||
|
||||
___
|
||||
|
||||
@@ -34,9 +34,9 @@ ___
|
||||
|
||||
• **elementType**: *keyof IntrinsicElements*
|
||||
|
||||
*Defined in [mocked-types/index.ts:33](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L33)*
|
||||
*Defined in [mocked-types/index.ts:41](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L41)*
|
||||
|
||||
*Defined in [mocked-types/index.ts:43](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L43)*
|
||||
*Defined in [mocked-types/index.ts:51](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L51)*
|
||||
|
||||
___
|
||||
|
||||
@@ -44,9 +44,9 @@ ___
|
||||
|
||||
• **sibling**: *[FiberNode](../modules/_mocked_types_index_.md#fibernode) | null*
|
||||
|
||||
*Defined in [mocked-types/index.ts:31](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L31)*
|
||||
*Defined in [mocked-types/index.ts:39](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L39)*
|
||||
|
||||
*Defined in [mocked-types/index.ts:41](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L41)*
|
||||
*Defined in [mocked-types/index.ts:49](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L49)*
|
||||
|
||||
___
|
||||
|
||||
@@ -54,9 +54,9 @@ ___
|
||||
|
||||
• **stateNode**: *`HTMLElement`*
|
||||
|
||||
*Defined in [mocked-types/index.ts:36](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L36)*
|
||||
*Defined in [mocked-types/index.ts:44](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L44)*
|
||||
|
||||
*Defined in [mocked-types/index.ts:46](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L46)*
|
||||
*Defined in [mocked-types/index.ts:54](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L54)*
|
||||
|
||||
___
|
||||
|
||||
@@ -64,6 +64,6 @@ ___
|
||||
|
||||
• **type**: *keyof IntrinsicElements*
|
||||
|
||||
*Defined in [mocked-types/index.ts:34](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L34)*
|
||||
*Defined in [mocked-types/index.ts:42](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L42)*
|
||||
|
||||
*Defined in [mocked-types/index.ts:44](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L44)*
|
||||
*Defined in [mocked-types/index.ts:52](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L52)*
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
• **child**: *null*
|
||||
|
||||
*Defined in [mocked-types/index.ts:50](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L50)*
|
||||
*Defined in [mocked-types/index.ts:58](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L58)*
|
||||
|
||||
___
|
||||
|
||||
@@ -32,7 +32,7 @@ ___
|
||||
|
||||
• **elementType**: *null*
|
||||
|
||||
*Defined in [mocked-types/index.ts:53](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L53)*
|
||||
*Defined in [mocked-types/index.ts:61](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L61)*
|
||||
|
||||
___
|
||||
|
||||
@@ -40,7 +40,7 @@ ___
|
||||
|
||||
• **sibling**: *[FiberNode](../modules/_mocked_types_index_.md#fibernode) | null*
|
||||
|
||||
*Defined in [mocked-types/index.ts:51](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L51)*
|
||||
*Defined in [mocked-types/index.ts:59](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L59)*
|
||||
|
||||
___
|
||||
|
||||
@@ -48,7 +48,7 @@ ___
|
||||
|
||||
• **stateNode**: *`Text`*
|
||||
|
||||
*Defined in [mocked-types/index.ts:56](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L56)*
|
||||
*Defined in [mocked-types/index.ts:64](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L64)*
|
||||
|
||||
___
|
||||
|
||||
@@ -56,4 +56,4 @@ ___
|
||||
|
||||
• **type**: *null*
|
||||
|
||||
*Defined in [mocked-types/index.ts:54](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L54)*
|
||||
*Defined in [mocked-types/index.ts:62](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L62)*
|
||||
@@ -18,7 +18,23 @@
|
||||
|
||||
▸ **findNodeByComponent**(`node`: [FiberNode](_mocked_types_index_.md#fibernode) | null, `expectedClassOrFunction`: `React.ComponentType`): *[FiberNode](_mocked_types_index_.md#fibernode) | null*
|
||||
|
||||
*Defined in [findNode.ts:32](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/findNode.ts#L32)*
|
||||
*Defined in [findNode.ts:67](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/findNode.ts#L67)*
|
||||
|
||||
Find node by component (i.e. class or function by reference), till first match.
|
||||
|
||||
Matches against class and function by reference.
|
||||
Returns null if no match is found.
|
||||
|
||||
**`example`**
|
||||
```js
|
||||
// returns FiberNode for first usage of AccordionMenu
|
||||
findNodeByComponent(startNode, AccordionMenu);
|
||||
```
|
||||
|
||||
**`note`** Medium chance of collision, medium data access needed.
|
||||
This is safer than findNodeByComponentName, as different components with the same name won't collide.
|
||||
But, two instances of the same component will still collide.
|
||||
Needs access to component class or function.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
@@ -35,7 +51,22 @@ ___
|
||||
|
||||
▸ **findNodeByComponentName**(`node`: [FiberNode](_mocked_types_index_.md#fibernode) | null, `expectedName`: string): *[FiberNode](_mocked_types_index_.md#fibernode) | null*
|
||||
|
||||
*Defined in [findNode.ts:4](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/findNode.ts#L4)*
|
||||
*Defined in [findNode.ts:21](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/findNode.ts#L21)*
|
||||
|
||||
Find node by component name, till first match.
|
||||
|
||||
Matches against class and function name, doesn't match html-like nodes.
|
||||
Returns null if no match is found.
|
||||
|
||||
**`example`**
|
||||
```js
|
||||
// returns FiberNode for first usage of 'AccordionMenu'
|
||||
findNodeByComponentName(startNode, "AccordionMenu");
|
||||
```
|
||||
|
||||
**`note`** Highest chance of collision, least data access needed.
|
||||
Different components with same name will collide.
|
||||
Needs access to component name.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
@@ -52,7 +83,21 @@ ___
|
||||
|
||||
▸ **findNodeByComponentRef**(`node`: [FiberNode](_mocked_types_index_.md#fibernode) | null, `expectedClassInstance`: `Component`): *[FiberNode](_mocked_types_index_.md#fibernode) | null*
|
||||
|
||||
*Defined in [findNode.ts:63](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/findNode.ts#L63)*
|
||||
*Defined in [findNode.ts:114](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/findNode.ts#L114)*
|
||||
|
||||
Find node by component instance ref, till first match.
|
||||
|
||||
Matches against class instances by reference.
|
||||
Returns null if no match is found.
|
||||
|
||||
**`example`**
|
||||
```js
|
||||
// menuRef=createRef(); <AccordionMenu ref={menuRef}>
|
||||
findNodeByComponentRef(startNode, menuRef.current);
|
||||
```
|
||||
|
||||
**`note`** Least chance of collision, maximum data access needed.
|
||||
Needs access to component instance (through React ref usually).
|
||||
|
||||
**Parameters:**
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
### Interfaces
|
||||
|
||||
* [FiberNodeDOMContainer](../interfaces/_mocked_types_index_.fibernodedomcontainer.md)
|
||||
* [FiberNodeForComponentClass](../interfaces/_mocked_types_index_.fibernodeforcomponentclass.md)
|
||||
* [FiberNodeForFunctionComponent](../interfaces/_mocked_types_index_.fibernodeforfunctioncomponent.md)
|
||||
* [FiberNodeForInstrinsicElement](../interfaces/_mocked_types_index_.fibernodeforinstrinsicelement.md)
|
||||
@@ -24,7 +25,7 @@
|
||||
|
||||
Ƭ **FiberNode**: *[FiberNodeForComponentClass](../interfaces/_mocked_types_index_.fibernodeforcomponentclass.md) | [FiberNodeForFunctionComponent](../interfaces/_mocked_types_index_.fibernodeforfunctioncomponent.md) | [FiberNodeForInstrinsicElement](../interfaces/_mocked_types_index_.fibernodeforinstrinsicelement.md) | [FiberNodeForTextNode](../interfaces/_mocked_types_index_.fibernodefortextnode.md)*
|
||||
|
||||
*Defined in [mocked-types/index.ts:3](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L3)*
|
||||
*Defined in [mocked-types/index.ts:11](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L11)*
|
||||
|
||||
___
|
||||
|
||||
@@ -32,4 +33,4 @@ ___
|
||||
|
||||
Ƭ **FiberNodeisHTMLLike**: *[FiberNodeForInstrinsicElement](../interfaces/_mocked_types_index_.fibernodeforinstrinsicelement.md) | [FiberNodeForTextNode](../interfaces/_mocked_types_index_.fibernodefortextnode.md)*
|
||||
|
||||
*Defined in [mocked-types/index.ts:59](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/mocked-types/index.ts#L59)*
|
||||
*Defined in [mocked-types/index.ts:67](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/mocked-types/index.ts#L67)*
|
||||
@@ -17,7 +17,19 @@
|
||||
|
||||
▸ **traverse**(`node`: [FiberNode](_mocked_types_index_.md#fibernode), `fn`: function): *void*
|
||||
|
||||
*Defined in [traverse.ts:4](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/traverse.ts#L4)*
|
||||
*Defined in [traverse.ts:19](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/traverse.ts#L19)*
|
||||
|
||||
Traverse nodes recursively in depth-first manner, starting from a start node.
|
||||
|
||||
This is the default and basic traversal method, which covers basic use cases.
|
||||
You can't do advanced things like change the order of traversal, skip or cancel traversal after any node, etc.
|
||||
For more advanced usecases, see [traverseGenerator](_traverse_.md#traversegenerator)
|
||||
|
||||
**`example`**
|
||||
```js
|
||||
// calls fn for each node inside startNode
|
||||
traverse(startNode, fn);
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
|
||||
@@ -41,7 +53,7 @@ ___
|
||||
|
||||
▸ **traverseGenerator**(`node`: [FiberNode](_mocked_types_index_.md#fibernode), `__namedParameters`: object): *`IterableIterator<FiberNode>`*
|
||||
|
||||
*Defined in [traverse.ts:15](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/traverse.ts#L15)*
|
||||
*Defined in [traverse.ts:30](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/traverse.ts#L30)*
|
||||
|
||||
**Parameters:**
|
||||
|
||||
|
||||
+51
-14
@@ -8,6 +8,8 @@
|
||||
|
||||
### Functions
|
||||
|
||||
* [doesElementContainRootFiberNode](_utils_.md#doeselementcontainrootfibernode)
|
||||
* [getRootFiberNodeFromDOM](_utils_.md#getrootfibernodefromdom)
|
||||
* [isConstructorComponentClass](_utils_.md#isconstructorcomponentclass)
|
||||
* [isConstructorFunctionComponent](_utils_.md#isconstructorfunctioncomponent)
|
||||
* [isConstructorHtmlLike](_utils_.md#isconstructorhtmllike)
|
||||
@@ -18,17 +20,52 @@
|
||||
|
||||
## Functions
|
||||
|
||||
### isConstructorComponentClass
|
||||
### doesElementContainRootFiberNode
|
||||
|
||||
▸ **isConstructorComponentClass**(`ctr`: `React.ElementType`): *boolean*
|
||||
▸ **doesElementContainRootFiberNode**(`element`: `Element`): *boolean*
|
||||
|
||||
*Defined in [utils.ts:40](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/utils.ts#L40)*
|
||||
*Defined in [utils.ts:65](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/utils.ts#L65)*
|
||||
|
||||
**Parameters:**
|
||||
|
||||
Name | Type |
|
||||
------ | ------ |
|
||||
`ctr` | `React.ElementType` |
|
||||
`element` | `Element` |
|
||||
|
||||
**Returns:** *boolean*
|
||||
|
||||
___
|
||||
|
||||
### getRootFiberNodeFromDOM
|
||||
|
||||
▸ **getRootFiberNodeFromDOM**(`startElement?`: [Element](../interfaces/_mocked_types_index_.fibernodedomcontainer.md#element)): *[FiberNode](_mocked_types_index_.md#fibernode) | null*
|
||||
|
||||
*Defined in [utils.ts:82](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/utils.ts#L82)*
|
||||
|
||||
Util to find root React Fiber node from html DOM tree.
|
||||
Returns null, if not found.SHould be called after ReactDOM.render is finished.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
Name | Type | Description |
|
||||
------ | ------ | ------ |
|
||||
`startElement?` | [Element](../interfaces/_mocked_types_index_.fibernodedomcontainer.md#element) | Starting DOM element to seach from. If not found, it checks inside its child nodes. Defaults to document.body |
|
||||
|
||||
**Returns:** *[FiberNode](_mocked_types_index_.md#fibernode) | null*
|
||||
|
||||
___
|
||||
|
||||
### isConstructorComponentClass
|
||||
|
||||
▸ **isConstructorComponentClass**(`ctr`: `React.ElementType` | null): *boolean*
|
||||
|
||||
*Defined in [utils.ts:42](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/utils.ts#L42)*
|
||||
|
||||
**Parameters:**
|
||||
|
||||
Name | Type |
|
||||
------ | ------ |
|
||||
`ctr` | `React.ElementType` \| null |
|
||||
|
||||
**Returns:** *boolean*
|
||||
|
||||
@@ -36,15 +73,15 @@ ___
|
||||
|
||||
### isConstructorFunctionComponent
|
||||
|
||||
▸ **isConstructorFunctionComponent**(`ctr`: `React.ElementType`): *boolean*
|
||||
▸ **isConstructorFunctionComponent**(`ctr`: `React.ElementType` | null): *boolean*
|
||||
|
||||
*Defined in [utils.ts:57](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/utils.ts#L57)*
|
||||
*Defined in [utils.ts:59](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/utils.ts#L59)*
|
||||
|
||||
**Parameters:**
|
||||
|
||||
Name | Type |
|
||||
------ | ------ |
|
||||
`ctr` | `React.ElementType` |
|
||||
`ctr` | `React.ElementType` \| null |
|
||||
|
||||
**Returns:** *boolean*
|
||||
|
||||
@@ -52,15 +89,15 @@ ___
|
||||
|
||||
### isConstructorHtmlLike
|
||||
|
||||
▸ **isConstructorHtmlLike**(`ctr`: `React.ElementType`): *boolean*
|
||||
▸ **isConstructorHtmlLike**(`ctr`: `React.ElementType` | null): *boolean*
|
||||
|
||||
*Defined in [utils.ts:31](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/utils.ts#L31)*
|
||||
*Defined in [utils.ts:33](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/utils.ts#L33)*
|
||||
|
||||
**Parameters:**
|
||||
|
||||
Name | Type |
|
||||
------ | ------ |
|
||||
`ctr` | `React.ElementType` |
|
||||
`ctr` | `React.ElementType` \| null |
|
||||
|
||||
**Returns:** *boolean*
|
||||
|
||||
@@ -70,7 +107,7 @@ ___
|
||||
|
||||
▸ **isNodeComponentClass**(`node`: [FiberNode](_mocked_types_index_.md#fibernode)): *boolean*
|
||||
|
||||
*Defined in [utils.ts:25](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/utils.ts#L25)*
|
||||
*Defined in [utils.ts:27](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/utils.ts#L27)*
|
||||
|
||||
**Parameters:**
|
||||
|
||||
@@ -86,7 +123,7 @@ ___
|
||||
|
||||
▸ **isNodeFunctionComponent**(`node`: [FiberNode](_mocked_types_index_.md#fibernode)): *boolean*
|
||||
|
||||
*Defined in [utils.ts:19](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/utils.ts#L19)*
|
||||
*Defined in [utils.ts:21](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/utils.ts#L21)*
|
||||
|
||||
**Parameters:**
|
||||
|
||||
@@ -102,7 +139,7 @@ ___
|
||||
|
||||
▸ **isNodeHtmlLike**(`node`: [FiberNode](_mocked_types_index_.md#fibernode)): *boolean*
|
||||
|
||||
*Defined in [utils.ts:9](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/utils.ts#L9)*
|
||||
*Defined in [utils.ts:11](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/utils.ts#L11)*
|
||||
|
||||
**Parameters:**
|
||||
|
||||
@@ -118,7 +155,7 @@ ___
|
||||
|
||||
▸ **isNodeNotHtmlLike**(`node`: [FiberNode](_mocked_types_index_.md#fibernode)): *boolean*
|
||||
|
||||
*Defined in [utils.ts:13](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/utils.ts#L13)*
|
||||
*Defined in [utils.ts:15](https://github.com/bendtherules/react-fiber-traverse/blob/fd6dad2/src/utils.ts#L15)*
|
||||
|
||||
**Parameters:**
|
||||
|
||||
|
||||
Generated
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-fiber-traverse",
|
||||
"version": "0.0.5",
|
||||
"version": "0.0.7",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-fiber-traverse",
|
||||
"version": "0.0.5",
|
||||
"version": "0.0.7",
|
||||
"description": "Traverse and other utils on top of React fiber tree",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/react-fiber-traverse.esm.js",
|
||||
@@ -38,7 +38,7 @@
|
||||
"test:umd": "jest --config ./scripts/jest/config.umd.js",
|
||||
"test:umdprod": "jest --config ./scripts/jest/config.umdprod.js",
|
||||
"test:src:debug": "node --inspect ./node_modules/jest/bin/jest.js --config ./scripts/jest/config.src.js",
|
||||
"version": "run-s test authors && git add ."
|
||||
"version": "run-s test authors docs && git add ."
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
|
||||
+108
-52
@@ -1,94 +1,150 @@
|
||||
import { FiberNode } from "./mocked-types";
|
||||
import { traverseGenerator, TTraverseConfig } from "./traverse";
|
||||
import { isNodeNotHtmlLike } from "./utils";
|
||||
|
||||
/**
|
||||
* Find node by component name, till first match.
|
||||
*
|
||||
* Matches against class and function name, doesn't match html-like nodes.
|
||||
* Returns null if no match is found.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* // returns FiberNode for first usage of 'AccordionMenu'
|
||||
* findNodeByComponentName(startNode, "AccordionMenu");
|
||||
* ```
|
||||
*
|
||||
* @note Highest chance of collision, least data access needed.
|
||||
* Different components with same name will collide.
|
||||
* Needs access to component name.
|
||||
*
|
||||
*/
|
||||
function findNodeByComponentName(
|
||||
node: FiberNode | null,
|
||||
expectedName: string
|
||||
expectedName: string,
|
||||
traverseConfig?: TTraverseConfig
|
||||
): FiberNode | null {
|
||||
if (node === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isNodeNotHtmlLike(node) && node.type.name === expectedName) {
|
||||
return node;
|
||||
}
|
||||
|
||||
{
|
||||
const returnVal = findNodeByComponentName(node.child, expectedName);
|
||||
if (returnVal !== null) {
|
||||
return returnVal;
|
||||
}
|
||||
}
|
||||
{
|
||||
const returnVal = findNodeByComponentName(node.sibling, expectedName);
|
||||
if (returnVal !== null) {
|
||||
return returnVal;
|
||||
const nodeIterator = traverseGenerator(node, traverseConfig);
|
||||
for (const tmpNode of nodeIterator) {
|
||||
if (isNodeNotHtmlLike(tmpNode) && tmpNode.type.name === expectedName) {
|
||||
return tmpNode;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function* findNodesByComponentName(
|
||||
node: FiberNode | null,
|
||||
expectedName: string,
|
||||
traverseConfig?: TTraverseConfig
|
||||
): IterableIterator<FiberNode> {
|
||||
if (node === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const nodeIterator = traverseGenerator(node, traverseConfig);
|
||||
for (const tmpNode of nodeIterator) {
|
||||
if (isNodeNotHtmlLike(tmpNode) && tmpNode.type.name === expectedName) {
|
||||
yield tmpNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function findAllNodesByComponentName(
|
||||
node: FiberNode | null,
|
||||
expectedName: string,
|
||||
traverseConfig?: TTraverseConfig
|
||||
): Array<FiberNode> {
|
||||
return [...findNodesByComponentName(node, expectedName, traverseConfig)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Find node by component (i.e. class or function by reference), till first match.
|
||||
*
|
||||
* Matches against class and function by reference.
|
||||
* Returns null if no match is found.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* // returns FiberNode for first usage of AccordionMenu
|
||||
* findNodeByComponent(startNode, AccordionMenu);
|
||||
* ```
|
||||
*
|
||||
* @note Medium chance of collision, medium data access needed.
|
||||
* This is safer than findNodeByComponentName, as different components with the same name won't collide.
|
||||
* But, two instances of the same component will still collide.
|
||||
* Needs access to component class or function.
|
||||
*
|
||||
*/
|
||||
function findNodeByComponent(
|
||||
node: FiberNode | null,
|
||||
expectedClassOrFunction: React.ComponentType
|
||||
expectedClassOrFunction: React.ComponentType,
|
||||
traverseConfig?: TTraverseConfig
|
||||
): FiberNode | null {
|
||||
if (node === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isNodeNotHtmlLike(node) && node.type === expectedClassOrFunction) {
|
||||
return node;
|
||||
}
|
||||
|
||||
{
|
||||
const returnVal = findNodeByComponent(node.child, expectedClassOrFunction);
|
||||
if (returnVal !== null) {
|
||||
return returnVal;
|
||||
}
|
||||
}
|
||||
{
|
||||
const returnVal = findNodeByComponent(
|
||||
node.sibling,
|
||||
expectedClassOrFunction
|
||||
);
|
||||
if (returnVal !== null) {
|
||||
return returnVal;
|
||||
const nodeIterator = traverseGenerator(node, traverseConfig);
|
||||
for (const tmpNode of nodeIterator) {
|
||||
if (
|
||||
isNodeNotHtmlLike(tmpNode) &&
|
||||
tmpNode.type === expectedClassOrFunction
|
||||
) {
|
||||
return tmpNode;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find node by component instance ref, till first match.
|
||||
*
|
||||
* Matches against class instances by reference.
|
||||
* Returns null if no match is found.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* // menuRef=createRef(); <AccordionMenu ref={menuRef}>
|
||||
* findNodeByComponentRef(startNode, menuRef.current);
|
||||
* ```
|
||||
*
|
||||
* @note Least chance of collision, maximum data access needed.
|
||||
* Needs access to component instance (through React ref usually).
|
||||
*
|
||||
*/
|
||||
function findNodeByComponentRef(
|
||||
node: FiberNode | null,
|
||||
expectedClassInstance: React.Component
|
||||
expectedClassInstance: React.Component,
|
||||
traverseConfig?: TTraverseConfig
|
||||
): FiberNode | null {
|
||||
if (node === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isNodeNotHtmlLike(node) && node.stateNode === expectedClassInstance) {
|
||||
return node;
|
||||
}
|
||||
|
||||
{
|
||||
const returnVal = findNodeByComponentRef(node.child, expectedClassInstance);
|
||||
if (returnVal !== null) {
|
||||
return returnVal;
|
||||
}
|
||||
}
|
||||
{
|
||||
const returnVal = findNodeByComponentRef(
|
||||
node.sibling,
|
||||
expectedClassInstance
|
||||
);
|
||||
if (returnVal !== null) {
|
||||
return returnVal;
|
||||
const nodeIterator = traverseGenerator(node, traverseConfig);
|
||||
for (const tmpNode of nodeIterator) {
|
||||
if (
|
||||
isNodeNotHtmlLike(tmpNode) &&
|
||||
tmpNode.stateNode === expectedClassInstance
|
||||
) {
|
||||
return tmpNode;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export { findNodeByComponentName, findNodeByComponent, findNodeByComponentRef };
|
||||
export {
|
||||
findNodeByComponentName,
|
||||
findNodesByComponentName,
|
||||
findAllNodesByComponentName,
|
||||
findNodeByComponent,
|
||||
findNodeByComponentRef
|
||||
};
|
||||
|
||||
+101
-16
@@ -1,29 +1,83 @@
|
||||
// import { isNodeSimple } from './utils';
|
||||
import { FiberNode } from "./mocked-types";
|
||||
|
||||
function traverse(node: FiberNode, fn: (node: FiberNode) => any) {
|
||||
fn.call(null, node);
|
||||
|
||||
if (node.child !== null) {
|
||||
traverse(node.child, fn);
|
||||
}
|
||||
if (node.sibling !== null) {
|
||||
traverse(node.sibling, fn);
|
||||
}
|
||||
interface TTraverseConfig {
|
||||
order?: Array<"self" | "child" | "sibling">;
|
||||
skipSiblingForStartNode?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverse nodes recursively using generators.
|
||||
*
|
||||
* This is the advanced traverse function, which can be used used
|
||||
* to write other variants of traversal and find.
|
||||
*
|
||||
* Type signature for generator.next first argument is `{ skipChild?: boolean; skipSibling?: boolean } | void `
|
||||
* Throw any error into the generator to finish the generator and let it cleanup its internals.
|
||||
*
|
||||
* It allows inversion of control -
|
||||
* so, application code can decide to
|
||||
* 1. change order of traversal,
|
||||
* 2. skip some elements,
|
||||
* 3. cancel traversal mid-way.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* // Basic use (for-of)
|
||||
*
|
||||
* const nodeIterator = traverseGenerator(rootNode);
|
||||
* for (const node of nodeIterator) {
|
||||
* // do something with each node here
|
||||
* }
|
||||
* ```
|
||||
* ------
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* // Breadth-first
|
||||
*
|
||||
* // note the order below
|
||||
* const nodeIterator = traverseGenerator(rootNode, ["self", "sibling", "child"]);
|
||||
* // rest - same as above
|
||||
* ```
|
||||
* -----
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* // Get first 3 nodes and then stop the generator
|
||||
*
|
||||
* const nodeIterator = traverseGenerator(rootNode);
|
||||
*
|
||||
* var count = 0;
|
||||
* var next;
|
||||
* while (
|
||||
* count < 3 &&
|
||||
* !(next = nodeIterator.next()).done
|
||||
* ) {
|
||||
* count++;
|
||||
* const node = next.value;
|
||||
* // do something with each node here
|
||||
* }
|
||||
*
|
||||
* // Finish generator, to prevent memory leak
|
||||
* nodeIterator.throw(new Error());
|
||||
* ```
|
||||
* -----
|
||||
*
|
||||
*/
|
||||
function* traverseGenerator(
|
||||
node: FiberNode,
|
||||
{
|
||||
order = ["self", "child", "sibling"]
|
||||
}: { order?: Array<"self" | "child" | "sibling"> } = {}
|
||||
order = ["self", "child", "sibling"],
|
||||
skipSiblingForStartNode = true
|
||||
}: TTraverseConfig = {}
|
||||
): IterableIterator<FiberNode> {
|
||||
let skipChild = false,
|
||||
skipSibling = false;
|
||||
skipSibling = skipSiblingForStartNode;
|
||||
|
||||
function* traverseSelf() {
|
||||
const controlInput:
|
||||
| { skipChild: boolean; skipSibling: boolean }
|
||||
| { skipChild?: boolean; skipSibling?: boolean }
|
||||
| undefined = yield node;
|
||||
|
||||
if (controlInput !== undefined) {
|
||||
@@ -34,14 +88,20 @@ function* traverseGenerator(
|
||||
function* traverseChild() {
|
||||
if (!skipChild && node.child !== null) {
|
||||
const nextNode = node.child;
|
||||
yield* traverseGenerator(nextNode, { order });
|
||||
yield* traverseGenerator(nextNode, {
|
||||
order,
|
||||
skipSiblingForStartNode: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function* traverseSibling() {
|
||||
if (!skipSibling && node.sibling !== null) {
|
||||
const nextNode = node.sibling;
|
||||
yield* traverseGenerator(nextNode, { order });
|
||||
yield* traverseGenerator(nextNode, {
|
||||
order,
|
||||
skipSiblingForStartNode: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,4 +122,29 @@ function* traverseGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
export { traverse, traverseGenerator };
|
||||
/**
|
||||
* Traverse nodes recursively in depth-first manner, starting from a start node.
|
||||
*
|
||||
* This is the default and basic traversal function, which covers basic use cases.
|
||||
* You can't do advanced things like change the order of traversal, skip or cancel traversal after any node, etc.
|
||||
* For more advanced usecases, see {@link traverseGenerator}
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* // calls fn for each node inside startNode
|
||||
* traverse(startNode, fn);
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
function traverse(
|
||||
node: FiberNode,
|
||||
fn: (node: FiberNode) => any,
|
||||
traverseConfig?: TTraverseConfig
|
||||
) {
|
||||
const nodeIterator = traverseGenerator(node, traverseConfig);
|
||||
for (const tmpNode of nodeIterator) {
|
||||
fn.call(null, tmpNode);
|
||||
}
|
||||
}
|
||||
|
||||
export { traverse, traverseGenerator, TTraverseConfig };
|
||||
|
||||
Reference in New Issue
Block a user