mirror of
https://github.com/bendtherules/react-fiber-traverse.git
synced 2026-08-18 22:01:49 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0f65cad28f | ||
|
|
fdfd267d95 | ||
|
|
c2a6000887 | ||
|
|
473d7cc38e | ||
|
|
1efcb67c56 | ||
|
|
f10c17bd53 | ||
|
|
e12438fd4f | ||
|
|
c92c64baa1 | ||
|
|
986f2c0aac | ||
|
|
ef593615ad | ||
|
|
2f28cd5eb0 | ||
|
|
c47a4dddbd | ||
|
|
051bb1f543 | ||
|
|
7b27f9c5b7 | ||
|
|
f5c37dc251 | ||
|
|
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 | ||
|
|
b16012f81e | ||
|
|
113674df2f | ||
|
|
88eb62298e | ||
|
|
8e484fc074 | ||
|
|
a88e0e0f07 | ||
|
|
a1204cfc1b | ||
|
|
ceaa1eee32 | ||
|
|
3c5ea67992 | ||
|
|
395dc281ce | ||
|
|
3e062ef911 | ||
|
|
e3750e9b50 | ||
|
|
e1dec601e7 | ||
|
|
d6d32fd847 | ||
|
|
7aff88ecb8 | ||
|
|
400757182f | ||
|
|
6cd41bc4bd | ||
|
|
5a33b3272e | ||
|
|
e7e1415039 | ||
|
|
7e676b0edc | ||
|
|
9ebc534cc3 | ||
|
|
d7276eff9e | ||
|
|
c5adcb3152 | ||
|
|
e64d51a3e6 | ||
|
|
887f4b95d1 | ||
|
|
39080755ef | ||
|
|
69c1d2db86 | ||
|
|
86216d3b05 | ||
|
|
933639e0ba | ||
|
|
91ab867f19 | ||
|
|
8f29fd8eea | ||
|
|
c3ca45928a | ||
|
|
2aa7a9bbf3 | ||
|
|
fb23260efe | ||
|
|
6f5826d398 |
+18
-18
@@ -1,36 +1,36 @@
|
|||||||
{
|
{
|
||||||
"dist/react-fiber-traverse.cjs.development.js": {
|
"dist/react-fiber-traverse.cjs.development.js": {
|
||||||
"bundled": 7398,
|
"bundled": 19424,
|
||||||
"minified": 3036,
|
"minified": 8388,
|
||||||
"gzipped": 967
|
"gzipped": 2612
|
||||||
},
|
},
|
||||||
"dist/react-fiber-traverse.cjs.production.js": {
|
"dist/react-fiber-traverse.cjs.production.js": {
|
||||||
"bundled": 7398,
|
"bundled": 19424,
|
||||||
"minified": 3036,
|
"minified": 8388,
|
||||||
"gzipped": 967
|
"gzipped": 2612
|
||||||
},
|
},
|
||||||
"dist/react-fiber-traverse.esm.js": {
|
"dist/react-fiber-traverse.esm.js": {
|
||||||
"bundled": 7048,
|
"bundled": 19124,
|
||||||
"minified": 2736,
|
"minified": 8112,
|
||||||
"gzipped": 869,
|
"gzipped": 2537,
|
||||||
"treeshaked": {
|
"treeshaked": {
|
||||||
"rollup": {
|
"rollup": {
|
||||||
"code": 49,
|
"code": 31,
|
||||||
"import_statements": 49
|
"import_statements": 31
|
||||||
},
|
},
|
||||||
"webpack": {
|
"webpack": {
|
||||||
"code": 1066
|
"code": 1048
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dist/react-fiber-traverse.umd.development.js": {
|
"dist/react-fiber-traverse.umd.development.js": {
|
||||||
"bundled": 32560,
|
"bundled": 34569,
|
||||||
"minified": 8698,
|
"minified": 11581,
|
||||||
"gzipped": 3085
|
"gzipped": 4230
|
||||||
},
|
},
|
||||||
"dist/react-fiber-traverse.umd.production.js": {
|
"dist/react-fiber-traverse.umd.production.js": {
|
||||||
"bundled": 32560,
|
"bundled": 34569,
|
||||||
"minified": 8698,
|
"minified": 11581,
|
||||||
"gzipped": 3085
|
"gzipped": 4230
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+2
-1
@@ -13,5 +13,6 @@
|
|||||||
"javascriptreact",
|
"javascriptreact",
|
||||||
"typescript",
|
"typescript",
|
||||||
"typescriptreact"
|
"typescriptreact"
|
||||||
]
|
],
|
||||||
|
"typescript.tsdk": "node_modules\\typescript\\lib"
|
||||||
}
|
}
|
||||||
@@ -10,29 +10,39 @@
|
|||||||
## Basic Usage
|
## Basic Usage
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import { render } from 'react-dom'
|
import React from "react";
|
||||||
|
import { render } from "react-dom";
|
||||||
|
|
||||||
import { findNodeByComponentName } from 'react-fiber-traverse'
|
import { findNodeByComponentName, Utils } from "react-fiber-traverse";
|
||||||
import { getRootFiberNodeFromDOM } from 'react-fiber-traverse/utils'
|
|
||||||
|
|
||||||
const rootElement = document.getElementById('root');
|
// Sample component
|
||||||
render(<App>, 'root');
|
// Say, if SomeComponentName looks like this -
|
||||||
|
function SomeComponentName() {
|
||||||
|
return <div>Some text</div>;
|
||||||
|
}
|
||||||
|
|
||||||
const rootFiberNode = getRootFiberNodeFromDOM(rootElement);
|
// 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'
|
||||||
|
|
||||||
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'
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Live Examples
|
## Live Examples
|
||||||
|
|
||||||
- [Basic Usage](https://codesandbox.io/)
|
- [Basic Usage](https://codesandbox.io/s/react-example-x82zk?expanddevtools=1&fontsize=14)
|
||||||
- [API Example](https://codesandbox.io/)
|
<!--
|
||||||
- [UMD Build (Development)](https://codesandbox.io/)
|
|
||||||
- [UMD Build (Production)](https://codesandbox.io/)
|
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
**Props**
|
**Props**
|
||||||
@@ -43,7 +53,7 @@ someFiberNode.stateNode.innerText // <- returns 'Some text'
|
|||||||
**Example**
|
**Example**
|
||||||
|
|
||||||
```jsx
|
```jsx
|
||||||
```
|
``` -->
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@@ -66,6 +76,38 @@ For the minified production version, make sure you have already included:
|
|||||||
- [`React`](https://unpkg.com/react/umd/react.production.min.js)
|
- [`React`](https://unpkg.com/react/umd/react.production.min.js)
|
||||||
- [`ReactDOM`](https://unpkg.com/react-dom/umd/react-dom.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
|
## License
|
||||||
|
|
||||||
MIT
|
MIT
|
||||||
|
|||||||
@@ -1,4 +1,28 @@
|
|||||||
|
# TODOs
|
||||||
|
|
||||||
1. Write docs and examples
|
1. Write docs and examples
|
||||||
2. Reduce testcase boilerplate code for similar tests
|
2. Reduce testcase boilerplate code for similar tests
|
||||||
3. Publish to npm
|
3. Publish to npm
|
||||||
4. Build some demo
|
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
|
||||||
|
- actual node is available 2 levels nested inside this root node
|
||||||
|
- add testcase to run across all versions of React 16.0.0 (dev+prod) and above (because internals change)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
13. Fix es5, downLevelIteration with generator iteration
|
||||||
|
14. Tests for match
|
||||||
|
15. **Catch throw in generator**
|
||||||
+60
-11
@@ -13,20 +13,40 @@
|
|||||||
|
|
||||||
## Basic Usage
|
## Basic Usage
|
||||||
|
|
||||||
```jsx
|
```ts
|
||||||
import React from 'react'
|
import React from "react";
|
||||||
import { render } from 'react-dom'
|
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
|
## Live Examples
|
||||||
|
|
||||||
- [Basic Usage](https://codesandbox.io/)
|
- [Basic Usage](https://codesandbox.io/s/react-example-x82zk?expanddevtools=1&fontsize=14)
|
||||||
- [API Example](https://codesandbox.io/)
|
<!--
|
||||||
- [UMD Build (Development)](https://codesandbox.io/)
|
|
||||||
- [UMD Build (Production)](https://codesandbox.io/)
|
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
**Props**
|
**Props**
|
||||||
@@ -37,7 +57,7 @@ render(, document.getElementById('root'))
|
|||||||
**Example**
|
**Example**
|
||||||
|
|
||||||
```jsx
|
```jsx
|
||||||
```
|
``` -->
|
||||||
|
|
||||||
## Installation
|
## 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)
|
- [`React`](https://unpkg.com/react/umd/react.development.js)
|
||||||
- [`ReactDOM`](https://unpkg.com/react-dom/umd/react-dom.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:
|
For the minified production version, make sure you have already included:
|
||||||
|
|
||||||
- [`React`](https://unpkg.com/react/umd/react.production.min.js)
|
- [`React`](https://unpkg.com/react/umd/react.production.min.js)
|
||||||
- [`ReactDOM`](https://unpkg.com/react-dom/umd/react-dom.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
|
## License
|
||||||
|
|
||||||
MIT
|
MIT
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
* ["findNode"](modules/_findnode_.md)
|
* ["findNode"](modules/_findnode_.md)
|
||||||
* ["index"](modules/_index_.md)
|
* ["index"](modules/_index_.md)
|
||||||
|
* ["match"](modules/_match_.md)
|
||||||
* ["mocked-types/index"](modules/_mocked_types_index_.md)
|
* ["mocked-types/index"](modules/_mocked_types_index_.md)
|
||||||
* ["traverse"](modules/_traverse_.md)
|
* ["traverse"](modules/_traverse_.md)
|
||||||
* ["utils"](modules/_utils_.md)
|
* ["utils"](modules/_utils_.md)
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
• **child**: *[FiberNode](../modules/_mocked_types_index_.md#fibernode) | null*
|
• **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/c92c64b/src/mocked-types/index.ts#L28)*
|
||||||
|
|
||||||
___
|
___
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ ___
|
|||||||
|
|
||||||
• **elementType**: *`ComponentClass`*
|
• **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/c92c64b/src/mocked-types/index.ts#L31)*
|
||||||
|
|
||||||
___
|
___
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ ___
|
|||||||
|
|
||||||
• **sibling**: *[FiberNode](../modules/_mocked_types_index_.md#fibernode) | null*
|
• **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/c92c64b/src/mocked-types/index.ts#L29)*
|
||||||
|
|
||||||
___
|
___
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ ___
|
|||||||
|
|
||||||
• **stateNode**: *`Component`*
|
• **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/c92c64b/src/mocked-types/index.ts#L34)*
|
||||||
|
|
||||||
___
|
___
|
||||||
|
|
||||||
@@ -56,4 +56,4 @@ ___
|
|||||||
|
|
||||||
• **type**: *`ComponentClass`*
|
• **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/c92c64b/src/mocked-types/index.ts#L32)*
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
• **child**: *[FiberNode](../modules/_mocked_types_index_.md#fibernode) | null*
|
• **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/c92c64b/src/mocked-types/index.ts#L18)*
|
||||||
|
|
||||||
___
|
___
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ ___
|
|||||||
|
|
||||||
• **elementType**: *`FunctionComponent`*
|
• **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/c92c64b/src/mocked-types/index.ts#L21)*
|
||||||
|
|
||||||
___
|
___
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ ___
|
|||||||
|
|
||||||
• **sibling**: *[FiberNode](../modules/_mocked_types_index_.md#fibernode) | null*
|
• **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/c92c64b/src/mocked-types/index.ts#L19)*
|
||||||
|
|
||||||
___
|
___
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ ___
|
|||||||
|
|
||||||
• **stateNode**: *null*
|
• **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/c92c64b/src/mocked-types/index.ts#L24)*
|
||||||
|
|
||||||
___
|
___
|
||||||
|
|
||||||
@@ -56,4 +56,4 @@ ___
|
|||||||
|
|
||||||
• **type**: *`FunctionComponent`*
|
• **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/c92c64b/src/mocked-types/index.ts#L22)*
|
||||||
@@ -24,9 +24,9 @@
|
|||||||
|
|
||||||
• **child**: *[FiberNode](../modules/_mocked_types_index_.md#fibernode) | null*
|
• **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/c92c64b/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/c92c64b/src/mocked-types/index.ts#L48)*
|
||||||
|
|
||||||
___
|
___
|
||||||
|
|
||||||
@@ -34,9 +34,9 @@ ___
|
|||||||
|
|
||||||
• **elementType**: *keyof IntrinsicElements*
|
• **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/c92c64b/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/c92c64b/src/mocked-types/index.ts#L51)*
|
||||||
|
|
||||||
___
|
___
|
||||||
|
|
||||||
@@ -44,9 +44,9 @@ ___
|
|||||||
|
|
||||||
• **sibling**: *[FiberNode](../modules/_mocked_types_index_.md#fibernode) | null*
|
• **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/c92c64b/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/c92c64b/src/mocked-types/index.ts#L49)*
|
||||||
|
|
||||||
___
|
___
|
||||||
|
|
||||||
@@ -54,9 +54,9 @@ ___
|
|||||||
|
|
||||||
• **stateNode**: *`HTMLElement`*
|
• **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/c92c64b/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/c92c64b/src/mocked-types/index.ts#L54)*
|
||||||
|
|
||||||
___
|
___
|
||||||
|
|
||||||
@@ -64,6 +64,6 @@ ___
|
|||||||
|
|
||||||
• **type**: *keyof IntrinsicElements*
|
• **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/c92c64b/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/c92c64b/src/mocked-types/index.ts#L52)*
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
• **child**: *null*
|
• **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/c92c64b/src/mocked-types/index.ts#L58)*
|
||||||
|
|
||||||
___
|
___
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ ___
|
|||||||
|
|
||||||
• **elementType**: *null*
|
• **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/c92c64b/src/mocked-types/index.ts#L61)*
|
||||||
|
|
||||||
___
|
___
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ ___
|
|||||||
|
|
||||||
• **sibling**: *[FiberNode](../modules/_mocked_types_index_.md#fibernode) | null*
|
• **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/c92c64b/src/mocked-types/index.ts#L59)*
|
||||||
|
|
||||||
___
|
___
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ ___
|
|||||||
|
|
||||||
• **stateNode**: *`Text`*
|
• **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/c92c64b/src/mocked-types/index.ts#L64)*
|
||||||
|
|
||||||
___
|
___
|
||||||
|
|
||||||
@@ -56,4 +56,4 @@ ___
|
|||||||
|
|
||||||
• **type**: *null*
|
• **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/c92c64b/src/mocked-types/index.ts#L62)*
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
> **[react-fiber-traverse](../README.md)**
|
||||||
|
|
||||||
|
[Globals](../globals.md) / ["traverse"](../modules/_traverse_.md) / [TTraverseConfig](_traverse_.ttraverseconfig.md) /
|
||||||
|
|
||||||
|
# Interface: TTraverseConfig
|
||||||
|
|
||||||
|
## Hierarchy
|
||||||
|
|
||||||
|
* **TTraverseConfig**
|
||||||
|
|
||||||
|
## Index
|
||||||
|
|
||||||
|
### Properties
|
||||||
|
|
||||||
|
* [order](_traverse_.ttraverseconfig.md#optional-order)
|
||||||
|
* [skipSelfForStartNode](_traverse_.ttraverseconfig.md#optional-skipselfforstartnode)
|
||||||
|
* [skipSiblingForStartNode](_traverse_.ttraverseconfig.md#optional-skipsiblingforstartnode)
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
### `Optional` order
|
||||||
|
|
||||||
|
• **order**? : *`Array<"self" | "child" | "sibling">`*
|
||||||
|
|
||||||
|
*Defined in [traverse.ts:5](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/traverse.ts#L5)*
|
||||||
|
|
||||||
|
___
|
||||||
|
|
||||||
|
### `Optional` skipSelfForStartNode
|
||||||
|
|
||||||
|
• **skipSelfForStartNode**? : *undefined | false | true*
|
||||||
|
|
||||||
|
*Defined in [traverse.ts:7](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/traverse.ts#L7)*
|
||||||
|
|
||||||
|
___
|
||||||
|
|
||||||
|
### `Optional` skipSiblingForStartNode
|
||||||
|
|
||||||
|
• **skipSiblingForStartNode**? : *undefined | false | true*
|
||||||
|
|
||||||
|
*Defined in [traverse.ts:6](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/traverse.ts#L6)*
|
||||||
+109
-23
@@ -8,34 +8,19 @@
|
|||||||
|
|
||||||
### Functions
|
### Functions
|
||||||
|
|
||||||
|
* [findAllNodesByComponentName](_findnode_.md#findallnodesbycomponentname)
|
||||||
* [findNodeByComponent](_findnode_.md#findnodebycomponent)
|
* [findNodeByComponent](_findnode_.md#findnodebycomponent)
|
||||||
* [findNodeByComponentName](_findnode_.md#findnodebycomponentname)
|
* [findNodeByComponentName](_findnode_.md#findnodebycomponentname)
|
||||||
* [findNodeByComponentRef](_findnode_.md#findnodebycomponentref)
|
* [findNodeByComponentRef](_findnode_.md#findnodebycomponentref)
|
||||||
|
* [findNodesByComponentName](_findnode_.md#findnodesbycomponentname)
|
||||||
|
|
||||||
## Functions
|
## Functions
|
||||||
|
|
||||||
### findNodeByComponent
|
### findAllNodesByComponentName
|
||||||
|
|
||||||
▸ **findNodeByComponent**(`node`: [FiberNode](_mocked_types_index_.md#fibernode) | null, `expectedClassOrFunction`: `React.ComponentType`): *[FiberNode](_mocked_types_index_.md#fibernode) | null*
|
▸ **findAllNodesByComponentName**(`node`: [FiberNode](_mocked_types_index_.md#fibernode) | null, `expectedName`: string, `traverseConfig?`: [TTraverseConfig](../interfaces/_traverse_.ttraverseconfig.md)): *`Array<FiberNode>`*
|
||||||
|
|
||||||
*Defined in [findNode.ts:32](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/findNode.ts#L32)*
|
*Defined in [findNode.ts:58](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/findNode.ts#L58)*
|
||||||
|
|
||||||
**Parameters:**
|
|
||||||
|
|
||||||
Name | Type |
|
|
||||||
------ | ------ |
|
|
||||||
`node` | [FiberNode](_mocked_types_index_.md#fibernode) \| null |
|
|
||||||
`expectedClassOrFunction` | `React.ComponentType` |
|
|
||||||
|
|
||||||
**Returns:** *[FiberNode](_mocked_types_index_.md#fibernode) | null*
|
|
||||||
|
|
||||||
___
|
|
||||||
|
|
||||||
### findNodeByComponentName
|
|
||||||
|
|
||||||
▸ **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)*
|
|
||||||
|
|
||||||
**Parameters:**
|
**Parameters:**
|
||||||
|
|
||||||
@@ -43,6 +28,74 @@ Name | Type |
|
|||||||
------ | ------ |
|
------ | ------ |
|
||||||
`node` | [FiberNode](_mocked_types_index_.md#fibernode) \| null |
|
`node` | [FiberNode](_mocked_types_index_.md#fibernode) \| null |
|
||||||
`expectedName` | string |
|
`expectedName` | string |
|
||||||
|
`traverseConfig?` | [TTraverseConfig](../interfaces/_traverse_.ttraverseconfig.md) |
|
||||||
|
|
||||||
|
**Returns:** *`Array<FiberNode>`*
|
||||||
|
|
||||||
|
___
|
||||||
|
|
||||||
|
### findNodeByComponent
|
||||||
|
|
||||||
|
▸ **findNodeByComponent**(`node`: [FiberNode](_mocked_types_index_.md#fibernode) | null, `expectedClassOrFunction`: `React.ComponentType`, `traverseConfig?`: [TTraverseConfig](../interfaces/_traverse_.ttraverseconfig.md)): *[FiberNode](_mocked_types_index_.md#fibernode) | null*
|
||||||
|
|
||||||
|
*Defined in [findNode.ts:84](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/findNode.ts#L84)*
|
||||||
|
|
||||||
|
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:**
|
||||||
|
|
||||||
|
Name | Type |
|
||||||
|
------ | ------ |
|
||||||
|
`node` | [FiberNode](_mocked_types_index_.md#fibernode) \| null |
|
||||||
|
`expectedClassOrFunction` | `React.ComponentType` |
|
||||||
|
`traverseConfig?` | [TTraverseConfig](../interfaces/_traverse_.ttraverseconfig.md) |
|
||||||
|
|
||||||
|
**Returns:** *[FiberNode](_mocked_types_index_.md#fibernode) | null*
|
||||||
|
|
||||||
|
___
|
||||||
|
|
||||||
|
### findNodeByComponentName
|
||||||
|
|
||||||
|
▸ **findNodeByComponentName**(`node`: [FiberNode](_mocked_types_index_.md#fibernode) | null, `expectedName`: string, `traverseConfig?`: [TTraverseConfig](../interfaces/_traverse_.ttraverseconfig.md)): *[FiberNode](_mocked_types_index_.md#fibernode) | null*
|
||||||
|
|
||||||
|
*Defined in [findNode.ts:22](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/findNode.ts#L22)*
|
||||||
|
|
||||||
|
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:**
|
||||||
|
|
||||||
|
Name | Type |
|
||||||
|
------ | ------ |
|
||||||
|
`node` | [FiberNode](_mocked_types_index_.md#fibernode) \| null |
|
||||||
|
`expectedName` | string |
|
||||||
|
`traverseConfig?` | [TTraverseConfig](../interfaces/_traverse_.ttraverseconfig.md) |
|
||||||
|
|
||||||
**Returns:** *[FiberNode](_mocked_types_index_.md#fibernode) | null*
|
**Returns:** *[FiberNode](_mocked_types_index_.md#fibernode) | null*
|
||||||
|
|
||||||
@@ -50,9 +103,23 @@ ___
|
|||||||
|
|
||||||
### findNodeByComponentRef
|
### findNodeByComponentRef
|
||||||
|
|
||||||
▸ **findNodeByComponentRef**(`node`: [FiberNode](_mocked_types_index_.md#fibernode) | null, `expectedClassInstance`: `Component`): *[FiberNode](_mocked_types_index_.md#fibernode) | null*
|
▸ **findNodeByComponentRef**(`node`: [FiberNode](_mocked_types_index_.md#fibernode) | null, `expectedClassInstance`: `Component`, `traverseConfig?`: [TTraverseConfig](../interfaces/_traverse_.ttraverseconfig.md)): *[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:122](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/findNode.ts#L122)*
|
||||||
|
|
||||||
|
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:**
|
**Parameters:**
|
||||||
|
|
||||||
@@ -60,5 +127,24 @@ Name | Type |
|
|||||||
------ | ------ |
|
------ | ------ |
|
||||||
`node` | [FiberNode](_mocked_types_index_.md#fibernode) \| null |
|
`node` | [FiberNode](_mocked_types_index_.md#fibernode) \| null |
|
||||||
`expectedClassInstance` | `Component` |
|
`expectedClassInstance` | `Component` |
|
||||||
|
`traverseConfig?` | [TTraverseConfig](../interfaces/_traverse_.ttraverseconfig.md) |
|
||||||
|
|
||||||
**Returns:** *[FiberNode](_mocked_types_index_.md#fibernode) | null*
|
**Returns:** *[FiberNode](_mocked_types_index_.md#fibernode) | null*
|
||||||
|
|
||||||
|
___
|
||||||
|
|
||||||
|
### findNodesByComponentName
|
||||||
|
|
||||||
|
▸ **findNodesByComponentName**(`node`: [FiberNode](_mocked_types_index_.md#fibernode) | null, `expectedName`: string, `traverseConfig?`: [TTraverseConfig](../interfaces/_traverse_.ttraverseconfig.md)): *`IterableIterator<FiberNode>`*
|
||||||
|
|
||||||
|
*Defined in [findNode.ts:41](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/findNode.ts#L41)*
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
Name | Type |
|
||||||
|
------ | ------ |
|
||||||
|
`node` | [FiberNode](_mocked_types_index_.md#fibernode) \| null |
|
||||||
|
`expectedName` | string |
|
||||||
|
`traverseConfig?` | [TTraverseConfig](../interfaces/_traverse_.ttraverseconfig.md) |
|
||||||
|
|
||||||
|
**Returns:** *`IterableIterator<FiberNode>`*
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
> **[react-fiber-traverse](../README.md)**
|
||||||
|
|
||||||
|
[Globals](../globals.md) / ["match"](_match_.md) /
|
||||||
|
|
||||||
|
# External module: "match"
|
||||||
|
|
||||||
|
## Index
|
||||||
|
|
||||||
|
### Functions
|
||||||
|
|
||||||
|
* [matchAll](_match_.md#matchall)
|
||||||
|
* [matchFirst](_match_.md#matchfirst)
|
||||||
|
* [matchGenerator](_match_.md#matchgenerator)
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
|
||||||
|
### matchAll
|
||||||
|
|
||||||
|
▸ **matchAll**(`node`: [FiberNode](_mocked_types_index_.md#fibernode), `match`: string | `CSSWhat.Selector`[][]): *`Array<FiberNode>`*
|
||||||
|
|
||||||
|
*Defined in [match.ts:115](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/match.ts#L115)*
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
Name | Type |
|
||||||
|
------ | ------ |
|
||||||
|
`node` | [FiberNode](_mocked_types_index_.md#fibernode) |
|
||||||
|
`match` | string \| `CSSWhat.Selector`[][] |
|
||||||
|
|
||||||
|
**Returns:** *`Array<FiberNode>`*
|
||||||
|
|
||||||
|
___
|
||||||
|
|
||||||
|
### matchFirst
|
||||||
|
|
||||||
|
▸ **matchFirst**(`node`: [FiberNode](_mocked_types_index_.md#fibernode), `match`: string | `CSSWhat.Selector`[][]): *[FiberNode](_mocked_types_index_.md#fibernode) | null*
|
||||||
|
|
||||||
|
*Defined in [match.ts:122](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/match.ts#L122)*
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
Name | Type |
|
||||||
|
------ | ------ |
|
||||||
|
`node` | [FiberNode](_mocked_types_index_.md#fibernode) |
|
||||||
|
`match` | string \| `CSSWhat.Selector`[][] |
|
||||||
|
|
||||||
|
**Returns:** *[FiberNode](_mocked_types_index_.md#fibernode) | null*
|
||||||
|
|
||||||
|
___
|
||||||
|
|
||||||
|
### matchGenerator
|
||||||
|
|
||||||
|
▸ **matchGenerator**(`node`: [FiberNode](_mocked_types_index_.md#fibernode), `match`: string | `CSSWhat.Selector`[][]): *`IterableIterator<FiberNode>`*
|
||||||
|
|
||||||
|
*Defined in [match.ts:6](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/match.ts#L6)*
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
Name | Type |
|
||||||
|
------ | ------ |
|
||||||
|
`node` | [FiberNode](_mocked_types_index_.md#fibernode) |
|
||||||
|
`match` | string \| `CSSWhat.Selector`[][] |
|
||||||
|
|
||||||
|
**Returns:** *`IterableIterator<FiberNode>`*
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
### Interfaces
|
### Interfaces
|
||||||
|
|
||||||
|
* [FiberNodeDOMContainer](../interfaces/_mocked_types_index_.fibernodedomcontainer.md)
|
||||||
* [FiberNodeForComponentClass](../interfaces/_mocked_types_index_.fibernodeforcomponentclass.md)
|
* [FiberNodeForComponentClass](../interfaces/_mocked_types_index_.fibernodeforcomponentclass.md)
|
||||||
* [FiberNodeForFunctionComponent](../interfaces/_mocked_types_index_.fibernodeforfunctioncomponent.md)
|
* [FiberNodeForFunctionComponent](../interfaces/_mocked_types_index_.fibernodeforfunctioncomponent.md)
|
||||||
* [FiberNodeForInstrinsicElement](../interfaces/_mocked_types_index_.fibernodeforinstrinsicelement.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)*
|
Ƭ **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/c92c64b/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)*
|
Ƭ **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/c92c64b/src/mocked-types/index.ts#L67)*
|
||||||
@@ -6,6 +6,10 @@
|
|||||||
|
|
||||||
## Index
|
## Index
|
||||||
|
|
||||||
|
### Interfaces
|
||||||
|
|
||||||
|
* [TTraverseConfig](../interfaces/_traverse_.ttraverseconfig.md)
|
||||||
|
|
||||||
### Functions
|
### Functions
|
||||||
|
|
||||||
* [traverse](_traverse_.md#traverse)
|
* [traverse](_traverse_.md#traverse)
|
||||||
@@ -15,9 +19,21 @@
|
|||||||
|
|
||||||
### traverse
|
### traverse
|
||||||
|
|
||||||
▸ **traverse**(`node`: [FiberNode](_mocked_types_index_.md#fibernode), `fn`: function): *void*
|
▸ **traverse**(`node`: [FiberNode](_mocked_types_index_.md#fibernode), `fn`: function, `traverseConfig?`: [TTraverseConfig](../interfaces/_traverse_.ttraverseconfig.md)): *void*
|
||||||
|
|
||||||
*Defined in [traverse.ts:4](https://github.com/bendtherules/react-fiber-traverse/blob/c9d7fd7/src/traverse.ts#L4)*
|
*Defined in [traverse.ts:146](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/traverse.ts#L146)*
|
||||||
|
|
||||||
|
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 [traverseGenerator](_traverse_.md#traversegenerator)
|
||||||
|
|
||||||
|
**`example`**
|
||||||
|
```js
|
||||||
|
// calls fn for each node inside startNode
|
||||||
|
traverse(startNode, fn);
|
||||||
|
```
|
||||||
|
|
||||||
**Parameters:**
|
**Parameters:**
|
||||||
|
|
||||||
@@ -33,6 +49,8 @@ Name | Type |
|
|||||||
------ | ------ |
|
------ | ------ |
|
||||||
`node` | [FiberNode](_mocked_types_index_.md#fibernode) |
|
`node` | [FiberNode](_mocked_types_index_.md#fibernode) |
|
||||||
|
|
||||||
|
▪`Optional` **traverseConfig**: *[TTraverseConfig](../interfaces/_traverse_.ttraverseconfig.md)*
|
||||||
|
|
||||||
**Returns:** *void*
|
**Returns:** *void*
|
||||||
|
|
||||||
___
|
___
|
||||||
@@ -41,7 +59,64 @@ ___
|
|||||||
|
|
||||||
▸ **traverseGenerator**(`node`: [FiberNode](_mocked_types_index_.md#fibernode), `__namedParameters`: object): *`IterableIterator<FiberNode>`*
|
▸ **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:69](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/traverse.ts#L69)*
|
||||||
|
|
||||||
|
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());
|
||||||
|
```
|
||||||
|
-----
|
||||||
|
|
||||||
**Parameters:**
|
**Parameters:**
|
||||||
|
|
||||||
@@ -52,5 +127,7 @@ ___
|
|||||||
Name | Type | Default |
|
Name | Type | Default |
|
||||||
------ | ------ | ------ |
|
------ | ------ | ------ |
|
||||||
`order` | "self" \| "child" \| "sibling"[] | ["self", "child", "sibling"] |
|
`order` | "self" \| "child" \| "sibling"[] | ["self", "child", "sibling"] |
|
||||||
|
`skipSelfForStartNode` | boolean | false |
|
||||||
|
`skipSiblingForStartNode` | boolean | true |
|
||||||
|
|
||||||
**Returns:** *`IterableIterator<FiberNode>`*
|
**Returns:** *`IterableIterator<FiberNode>`*
|
||||||
+51
-14
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
### Functions
|
### Functions
|
||||||
|
|
||||||
|
* [doesElementContainRootFiberNode](_utils_.md#doeselementcontainrootfibernode)
|
||||||
|
* [getRootFiberNodeFromDOM](_utils_.md#getrootfibernodefromdom)
|
||||||
* [isConstructorComponentClass](_utils_.md#isconstructorcomponentclass)
|
* [isConstructorComponentClass](_utils_.md#isconstructorcomponentclass)
|
||||||
* [isConstructorFunctionComponent](_utils_.md#isconstructorfunctioncomponent)
|
* [isConstructorFunctionComponent](_utils_.md#isconstructorfunctioncomponent)
|
||||||
* [isConstructorHtmlLike](_utils_.md#isconstructorhtmllike)
|
* [isConstructorHtmlLike](_utils_.md#isconstructorhtmllike)
|
||||||
@@ -18,17 +20,52 @@
|
|||||||
|
|
||||||
## Functions
|
## 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/c92c64b/src/utils.ts#L65)*
|
||||||
|
|
||||||
**Parameters:**
|
**Parameters:**
|
||||||
|
|
||||||
Name | Type |
|
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/c92c64b/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/c92c64b/src/utils.ts#L42)*
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
Name | Type |
|
||||||
|
------ | ------ |
|
||||||
|
`ctr` | `React.ElementType` \| null |
|
||||||
|
|
||||||
**Returns:** *boolean*
|
**Returns:** *boolean*
|
||||||
|
|
||||||
@@ -36,15 +73,15 @@ ___
|
|||||||
|
|
||||||
### isConstructorFunctionComponent
|
### 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/c92c64b/src/utils.ts#L59)*
|
||||||
|
|
||||||
**Parameters:**
|
**Parameters:**
|
||||||
|
|
||||||
Name | Type |
|
Name | Type |
|
||||||
------ | ------ |
|
------ | ------ |
|
||||||
`ctr` | `React.ElementType` |
|
`ctr` | `React.ElementType` \| null |
|
||||||
|
|
||||||
**Returns:** *boolean*
|
**Returns:** *boolean*
|
||||||
|
|
||||||
@@ -52,15 +89,15 @@ ___
|
|||||||
|
|
||||||
### isConstructorHtmlLike
|
### 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/c92c64b/src/utils.ts#L33)*
|
||||||
|
|
||||||
**Parameters:**
|
**Parameters:**
|
||||||
|
|
||||||
Name | Type |
|
Name | Type |
|
||||||
------ | ------ |
|
------ | ------ |
|
||||||
`ctr` | `React.ElementType` |
|
`ctr` | `React.ElementType` \| null |
|
||||||
|
|
||||||
**Returns:** *boolean*
|
**Returns:** *boolean*
|
||||||
|
|
||||||
@@ -70,7 +107,7 @@ ___
|
|||||||
|
|
||||||
▸ **isNodeComponentClass**(`node`: [FiberNode](_mocked_types_index_.md#fibernode)): *boolean*
|
▸ **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/c92c64b/src/utils.ts#L27)*
|
||||||
|
|
||||||
**Parameters:**
|
**Parameters:**
|
||||||
|
|
||||||
@@ -86,7 +123,7 @@ ___
|
|||||||
|
|
||||||
▸ **isNodeFunctionComponent**(`node`: [FiberNode](_mocked_types_index_.md#fibernode)): *boolean*
|
▸ **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/c92c64b/src/utils.ts#L21)*
|
||||||
|
|
||||||
**Parameters:**
|
**Parameters:**
|
||||||
|
|
||||||
@@ -102,7 +139,7 @@ ___
|
|||||||
|
|
||||||
▸ **isNodeHtmlLike**(`node`: [FiberNode](_mocked_types_index_.md#fibernode)): *boolean*
|
▸ **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/c92c64b/src/utils.ts#L11)*
|
||||||
|
|
||||||
**Parameters:**
|
**Parameters:**
|
||||||
|
|
||||||
@@ -118,7 +155,7 @@ ___
|
|||||||
|
|
||||||
▸ **isNodeNotHtmlLike**(`node`: [FiberNode](_mocked_types_index_.md#fibernode)): *boolean*
|
▸ **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/c92c64b/src/utils.ts#L15)*
|
||||||
|
|
||||||
**Parameters:**
|
**Parameters:**
|
||||||
|
|
||||||
|
|||||||
+10
-1
@@ -1,3 +1,12 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
"*.{js,jsx,ts,tsx}": () => "run-s check:* lint"
|
"*.{js,jsx,ts,tsx}": filenames => {
|
||||||
|
// Escape filenames and join by space
|
||||||
|
const joinedFilenames = filenames.map(str => `"${str}"`).join(" ");
|
||||||
|
return [
|
||||||
|
"run-s check:!(format)",
|
||||||
|
`npm run check:format -- ${joinedFilenames}`,
|
||||||
|
`npm run _lint -- ${joinedFilenames}`
|
||||||
|
];
|
||||||
|
// `run-s check:!(format) "check:format -- ${joinedFilenames}" "_lint -- ${joinedFilenames}"`;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Generated
+18
-11
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-fiber-traverse",
|
"name": "react-fiber-traverse",
|
||||||
"version": "0.0.3",
|
"version": "0.0.8",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -3775,13 +3775,20 @@
|
|||||||
"css-what": "2.1",
|
"css-what": "2.1",
|
||||||
"domutils": "1.5.1",
|
"domutils": "1.5.1",
|
||||||
"nth-check": "~1.0.1"
|
"nth-check": "~1.0.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"css-what": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"css-what": {
|
"css-what": {
|
||||||
"version": "2.1.3",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/css-what/-/css-what-3.2.0.tgz",
|
||||||
"integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==",
|
"integrity": "sha512-lukqnlbswsPmDZ5+ViDBCcrk+1fyPBA+ZoHSAQhRuEeXBKUb3Lj2kcTwMqoiFrJAnEeO9u3Oc8X617SUm3apYQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"cssom": {
|
"cssom": {
|
||||||
"version": "0.3.8",
|
"version": "0.3.8",
|
||||||
@@ -6007,9 +6014,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"handlebars": {
|
"handlebars": {
|
||||||
"version": "4.1.2",
|
"version": "4.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz",
|
||||||
"integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==",
|
"integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"neo-async": "^2.6.0",
|
"neo-async": "^2.6.0",
|
||||||
@@ -8886,9 +8893,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"normalize-url": {
|
"normalize-url": {
|
||||||
"version": "4.3.0",
|
"version": "4.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz",
|
||||||
"integrity": "sha512-0NLtR71o4k6GLP+mr6Ty34c5GA6CMoEsncKJxvQd8NzPxaHRJNnb5gZE8R1XF4CPIS7QPHLJ74IFszwtNVAHVQ==",
|
"integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"npm-prefix": {
|
"npm-prefix": {
|
||||||
|
|||||||
+7
-6
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-fiber-traverse",
|
"name": "react-fiber-traverse",
|
||||||
"version": "0.0.3",
|
"version": "0.0.8",
|
||||||
"description": "Traverse and other utils on top of React fiber tree",
|
"description": "Traverse and other utils on top of React fiber tree",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"module": "dist/react-fiber-traverse.esm.js",
|
"module": "dist/react-fiber-traverse.esm.js",
|
||||||
@@ -24,7 +24,8 @@
|
|||||||
"compile": "tsc -p tsconfig.base.json",
|
"compile": "tsc -p tsconfig.base.json",
|
||||||
"docs": "npx typedoc ./src/",
|
"docs": "npx typedoc ./src/",
|
||||||
"format": "prettier --write \"**/*.{js,ts,tsx}\"",
|
"format": "prettier --write \"**/*.{js,ts,tsx}\"",
|
||||||
"lint": "eslint . --ext .js,.ts",
|
"_lint": "eslint --ext .js,.ts,.jsx,.tsx",
|
||||||
|
"lint": "npm run _lint -- .",
|
||||||
"postbundle": "del compiled && cp-cli ./index.js ./dist/index.js",
|
"postbundle": "del compiled && cp-cli ./index.js ./dist/index.js",
|
||||||
"postversion": "git push && git push --tags && npm publish",
|
"postversion": "git push && git push --tags && npm publish",
|
||||||
"release": "npm version -m 'Release v%s'",
|
"release": "npm version -m 'Release v%s'",
|
||||||
@@ -36,13 +37,12 @@
|
|||||||
"test:src:watch": "npm run test:src -- --watch",
|
"test:src:watch": "npm run test:src -- --watch",
|
||||||
"test:umd": "jest --config ./scripts/jest/config.umd.js",
|
"test:umd": "jest --config ./scripts/jest/config.umd.js",
|
||||||
"test:umdprod": "jest --config ./scripts/jest/config.umdprod.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",
|
"test:src:debug": "node --inspect ./node_modules/jest/bin/jest.js --runInBand --config ./scripts/jest/config.src.js",
|
||||||
"version": "run-s test authors && git add ."
|
"version": "run-s test authors docs && git add ."
|
||||||
},
|
},
|
||||||
"husky": {
|
"husky": {
|
||||||
"hooks": {
|
"hooks": {
|
||||||
"pre-commit": "lint-staged",
|
"pre-commit": "lint-staged"
|
||||||
"post-commit": "npm run fix:format"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -66,6 +66,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.5.4",
|
"@babel/runtime": "^7.5.4",
|
||||||
|
"css-what": "^3.2.0",
|
||||||
"prop-types": "^15.7.2"
|
"prop-types": "^15.7.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
+108
-52
@@ -1,94 +1,150 @@
|
|||||||
import { FiberNode } from "./mocked-types";
|
import { FiberNode } from "./mocked-types";
|
||||||
|
import { traverseGenerator, TTraverseConfig } from "./traverse";
|
||||||
import { isNodeNotHtmlLike } from "./utils";
|
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(
|
function findNodeByComponentName(
|
||||||
node: FiberNode | null,
|
node: FiberNode | null,
|
||||||
expectedName: string
|
expectedName: string,
|
||||||
|
traverseConfig?: TTraverseConfig
|
||||||
): FiberNode | null {
|
): FiberNode | null {
|
||||||
if (node === null) {
|
if (node === null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNodeNotHtmlLike(node) && node.type.name === expectedName) {
|
const nodeIterator = traverseGenerator(node, traverseConfig);
|
||||||
return node;
|
for (const tmpNode of nodeIterator) {
|
||||||
}
|
if (isNodeNotHtmlLike(tmpNode) && tmpNode.type.name === expectedName) {
|
||||||
|
return tmpNode;
|
||||||
{
|
|
||||||
const returnVal = findNodeByComponentName(node.child, expectedName);
|
|
||||||
if (returnVal !== null) {
|
|
||||||
return returnVal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const returnVal = findNodeByComponentName(node.sibling, expectedName);
|
|
||||||
if (returnVal !== null) {
|
|
||||||
return returnVal;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
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(
|
function findNodeByComponent(
|
||||||
node: FiberNode | null,
|
node: FiberNode | null,
|
||||||
expectedClassOrFunction: React.ComponentType
|
expectedClassOrFunction: React.ComponentType,
|
||||||
|
traverseConfig?: TTraverseConfig
|
||||||
): FiberNode | null {
|
): FiberNode | null {
|
||||||
if (node === null) {
|
if (node === null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNodeNotHtmlLike(node) && node.type === expectedClassOrFunction) {
|
const nodeIterator = traverseGenerator(node, traverseConfig);
|
||||||
return node;
|
for (const tmpNode of nodeIterator) {
|
||||||
}
|
if (
|
||||||
|
isNodeNotHtmlLike(tmpNode) &&
|
||||||
{
|
tmpNode.type === expectedClassOrFunction
|
||||||
const returnVal = findNodeByComponent(node.child, expectedClassOrFunction);
|
) {
|
||||||
if (returnVal !== null) {
|
return tmpNode;
|
||||||
return returnVal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const returnVal = findNodeByComponent(
|
|
||||||
node.sibling,
|
|
||||||
expectedClassOrFunction
|
|
||||||
);
|
|
||||||
if (returnVal !== null) {
|
|
||||||
return returnVal;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
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(
|
function findNodeByComponentRef(
|
||||||
node: FiberNode | null,
|
node: FiberNode | null,
|
||||||
expectedClassInstance: React.Component
|
expectedClassInstance: React.Component,
|
||||||
|
traverseConfig?: TTraverseConfig
|
||||||
): FiberNode | null {
|
): FiberNode | null {
|
||||||
if (node === null) {
|
if (node === null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNodeNotHtmlLike(node) && node.stateNode === expectedClassInstance) {
|
const nodeIterator = traverseGenerator(node, traverseConfig);
|
||||||
return node;
|
for (const tmpNode of nodeIterator) {
|
||||||
}
|
if (
|
||||||
|
isNodeNotHtmlLike(tmpNode) &&
|
||||||
{
|
tmpNode.stateNode === expectedClassInstance
|
||||||
const returnVal = findNodeByComponentRef(node.child, expectedClassInstance);
|
) {
|
||||||
if (returnVal !== null) {
|
return tmpNode;
|
||||||
return returnVal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const returnVal = findNodeByComponentRef(
|
|
||||||
node.sibling,
|
|
||||||
expectedClassInstance
|
|
||||||
);
|
|
||||||
if (returnVal !== null) {
|
|
||||||
return returnVal;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { findNodeByComponentName, findNodeByComponent, findNodeByComponentRef };
|
export {
|
||||||
|
findNodeByComponentName,
|
||||||
|
findNodesByComponentName,
|
||||||
|
findAllNodesByComponentName,
|
||||||
|
findNodeByComponent,
|
||||||
|
findNodeByComponentRef
|
||||||
|
};
|
||||||
|
|||||||
+7
-1
@@ -4,11 +4,17 @@ import {
|
|||||||
findNodeByComponentRef,
|
findNodeByComponentRef,
|
||||||
findNodeByComponentName
|
findNodeByComponentName
|
||||||
} from "./findNode";
|
} from "./findNode";
|
||||||
|
import { matchGenerator, matchAll, matchFirst } from "./match";
|
||||||
|
import * as Utils from "./utils";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
traverse,
|
traverse,
|
||||||
traverseGenerator,
|
traverseGenerator,
|
||||||
findNodeByComponent,
|
findNodeByComponent,
|
||||||
findNodeByComponentRef,
|
findNodeByComponentRef,
|
||||||
findNodeByComponentName
|
findNodeByComponentName,
|
||||||
|
matchGenerator,
|
||||||
|
matchAll,
|
||||||
|
matchFirst,
|
||||||
|
Utils
|
||||||
};
|
};
|
||||||
|
|||||||
+141
@@ -0,0 +1,141 @@
|
|||||||
|
import * as CSSWhat from "css-what";
|
||||||
|
import { traverseGenerator } from "./traverse";
|
||||||
|
import { FiberNode } from "./mocked-types";
|
||||||
|
import { isNodeNotHtmlLike } from "./utils";
|
||||||
|
|
||||||
|
function* matchGenerator(
|
||||||
|
node: FiberNode,
|
||||||
|
match: string | CSSWhat.Selector[][]
|
||||||
|
): IterableIterator<FiberNode> {
|
||||||
|
// Either parse match string or allow parsed match object as it is
|
||||||
|
let matchParsed: CSSWhat.Selector[][];
|
||||||
|
if (typeof match === "string") {
|
||||||
|
matchParsed = CSSWhat.parse(match, {
|
||||||
|
lowerCaseTags: false,
|
||||||
|
lowerCaseAttributeNames: false
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
matchParsed = match;
|
||||||
|
}
|
||||||
|
// If selector is a combination of multiple basic selectors (a, b),
|
||||||
|
// pass them separately to matchGenerator and combine their results one after another
|
||||||
|
const selectorsCount = matchParsed.length;
|
||||||
|
if (selectorsCount > 1) {
|
||||||
|
for (const selectorParsed of matchParsed) {
|
||||||
|
yield* matchGenerator(node, [selectorParsed]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For simple selector (matchParsed.length == 0), actual logic starts here
|
||||||
|
{
|
||||||
|
const parsedSelector = matchParsed[0];
|
||||||
|
if (parsedSelector.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let currentMatchingNodes: FiberNode[] = [node];
|
||||||
|
let currentMatchingSelectorPartIndex = 0;
|
||||||
|
let lastRelationshipSelectorPart: CSSWhat.Selector | undefined = undefined;
|
||||||
|
|
||||||
|
while (currentMatchingSelectorPartIndex < parsedSelector.length) {
|
||||||
|
const nextMatchingNodes: FiberNode[] = [];
|
||||||
|
|
||||||
|
for (const currentNode of currentMatchingNodes) {
|
||||||
|
const currentMatchingSelectorPart: CSSWhat.Selector =
|
||||||
|
parsedSelector[currentMatchingSelectorPartIndex];
|
||||||
|
if (["tag"].includes(currentMatchingSelectorPart.type)) {
|
||||||
|
const startParams = {
|
||||||
|
skipSelfForStartNode: true,
|
||||||
|
skipSiblingForStartNode: true
|
||||||
|
};
|
||||||
|
|
||||||
|
let nextParams: {
|
||||||
|
skipChild?: boolean;
|
||||||
|
skipSibling?: boolean;
|
||||||
|
} = {};
|
||||||
|
if (
|
||||||
|
lastRelationshipSelectorPart === undefined ||
|
||||||
|
lastRelationshipSelectorPart.type === "descendant"
|
||||||
|
) {
|
||||||
|
nextParams = { skipChild: false, skipSibling: false };
|
||||||
|
} else if (lastRelationshipSelectorPart.type === "child") {
|
||||||
|
// visit only first level of child
|
||||||
|
nextParams = { skipChild: true };
|
||||||
|
} else if (lastRelationshipSelectorPart.type === "sibling") {
|
||||||
|
// visit only siblings of start node
|
||||||
|
nextParams = { skipChild: true, skipSibling: true };
|
||||||
|
startParams.skipSiblingForStartNode = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const traverseIterator = traverseGenerator(currentNode, startParams);
|
||||||
|
|
||||||
|
// Handle supported non-traversal parts here
|
||||||
|
if (currentMatchingSelectorPart.type == "tag") {
|
||||||
|
let tmpNode: FiberNode;
|
||||||
|
while (
|
||||||
|
!({ value: tmpNode } = traverseIterator.next(nextParams)).done
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
isNodeNotHtmlLike(tmpNode) &&
|
||||||
|
tmpNode.type.name === currentMatchingSelectorPart.name
|
||||||
|
) {
|
||||||
|
nextMatchingNodes.push(tmpNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// traverseIterator.throw &&
|
||||||
|
// traverseIterator.throw(new Error("cleanup"));
|
||||||
|
} else if (
|
||||||
|
["descendant", "child"].includes(currentMatchingSelectorPart.type)
|
||||||
|
) {
|
||||||
|
// Handle traversal parts here - Save for look back in next part
|
||||||
|
lastRelationshipSelectorPart = currentMatchingSelectorPart;
|
||||||
|
// Preserve currentMatchingNodes
|
||||||
|
nextMatchingNodes.push(...currentMatchingNodes);
|
||||||
|
} else {
|
||||||
|
// For unhandled parts
|
||||||
|
lastRelationshipSelectorPart = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currentMatchingNodes = nextMatchingNodes;
|
||||||
|
currentMatchingSelectorPartIndex += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const tmpNode of currentMatchingNodes) {
|
||||||
|
yield tmpNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function matchAll(
|
||||||
|
node: FiberNode,
|
||||||
|
match: string | CSSWhat.Selector[][]
|
||||||
|
): Array<FiberNode> {
|
||||||
|
return [...matchGenerator(node, match)];
|
||||||
|
}
|
||||||
|
|
||||||
|
function matchFirst(
|
||||||
|
node: FiberNode,
|
||||||
|
match: string | CSSWhat.Selector[][]
|
||||||
|
): FiberNode | null {
|
||||||
|
const matchIterator = matchGenerator(node, match);
|
||||||
|
const firstResult = matchIterator.next();
|
||||||
|
|
||||||
|
// Cancel generator
|
||||||
|
matchIterator.throw && matchIterator.throw(new Error("Cleanup"));
|
||||||
|
|
||||||
|
// If match found, return that
|
||||||
|
if (!firstResult.done) {
|
||||||
|
return firstResult.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Else return null
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { matchGenerator, matchAll, matchFirst };
|
||||||
@@ -44,16 +44,6 @@ export interface FiberNodeForInstrinsicElement {
|
|||||||
stateNode: HTMLElement;
|
stateNode: HTMLElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FiberNodeForInstrinsicElement {
|
|
||||||
child: FiberNode | null;
|
|
||||||
sibling: FiberNode | null;
|
|
||||||
|
|
||||||
elementType: keyof JSX.IntrinsicElements;
|
|
||||||
type: keyof JSX.IntrinsicElements;
|
|
||||||
|
|
||||||
stateNode: HTMLElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface FiberNodeForTextNode {
|
export interface FiberNodeForTextNode {
|
||||||
child: null;
|
child: null;
|
||||||
sibling: FiberNode | null;
|
sibling: FiberNode | null;
|
||||||
|
|||||||
+112
-20
@@ -1,47 +1,114 @@
|
|||||||
// import { isNodeSimple } from './utils';
|
// import { isNodeSimple } from './utils';
|
||||||
import { FiberNode } from "./mocked-types";
|
import { FiberNode } from "./mocked-types";
|
||||||
|
|
||||||
function traverse(node: FiberNode, fn: (node: FiberNode) => any) {
|
interface TTraverseConfig {
|
||||||
fn.call(null, node);
|
order?: Array<"self" | "child" | "sibling">;
|
||||||
|
skipSiblingForStartNode?: boolean;
|
||||||
if (node.child !== null) {
|
skipSelfForStartNode?: boolean;
|
||||||
traverse(node.child, fn);
|
|
||||||
}
|
|
||||||
if (node.sibling !== null) {
|
|
||||||
traverse(node.sibling, fn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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(
|
function* traverseGenerator(
|
||||||
node: FiberNode,
|
node: FiberNode,
|
||||||
{
|
{
|
||||||
order = ["self", "child", "sibling"]
|
order = ["self", "child", "sibling"],
|
||||||
}: { order?: Array<"self" | "child" | "sibling"> } = {}
|
skipSiblingForStartNode = true,
|
||||||
|
skipSelfForStartNode = false
|
||||||
|
}: TTraverseConfig = {}
|
||||||
): IterableIterator<FiberNode> {
|
): IterableIterator<FiberNode> {
|
||||||
let skipChild = false,
|
let skipChild = false,
|
||||||
skipSibling = false;
|
skipSibling = skipSiblingForStartNode,
|
||||||
|
skipSelf = skipSelfForStartNode;
|
||||||
|
|
||||||
function* traverseSelf() {
|
function* traverseSelf() {
|
||||||
const controlInput:
|
if (!skipSelf) {
|
||||||
| { skipChild: boolean; skipSibling: boolean }
|
const controlInput:
|
||||||
| undefined = yield node;
|
| { skipChild?: boolean; skipSibling?: boolean }
|
||||||
|
| undefined = yield node;
|
||||||
|
|
||||||
if (controlInput !== undefined) {
|
if (controlInput !== undefined) {
|
||||||
({ skipChild = skipChild, skipSibling = skipSibling } = controlInput);
|
({ skipChild = skipChild, skipSibling = skipSibling } = controlInput);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function* traverseChild() {
|
function* traverseChild() {
|
||||||
if (!skipChild && node.child !== null) {
|
if (!skipChild && node.child !== null) {
|
||||||
const nextNode = node.child;
|
const nextNode = node.child;
|
||||||
yield* traverseGenerator(nextNode, { order });
|
yield* traverseGenerator(nextNode, {
|
||||||
|
order,
|
||||||
|
skipSiblingForStartNode: false,
|
||||||
|
skipSelfForStartNode: false
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function* traverseSibling() {
|
function* traverseSibling() {
|
||||||
if (!skipSibling && node.sibling !== null) {
|
if (!skipSibling && node.sibling !== null) {
|
||||||
const nextNode = node.sibling;
|
const nextNode = node.sibling;
|
||||||
yield* traverseGenerator(nextNode, { order });
|
yield* traverseGenerator(nextNode, {
|
||||||
|
order,
|
||||||
|
skipSiblingForStartNode: false,
|
||||||
|
skipSelfForStartNode: false
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,4 +129,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 };
|
||||||
|
|||||||
+14
-7
@@ -7,6 +7,7 @@ import {
|
|||||||
FiberNodeDOMContainer
|
FiberNodeDOMContainer
|
||||||
} from "./mocked-types";
|
} from "./mocked-types";
|
||||||
|
|
||||||
|
// Support null in all of these
|
||||||
function isNodeHtmlLike(node: FiberNode): node is FiberNodeisHTMLLike {
|
function isNodeHtmlLike(node: FiberNode): node is FiberNodeisHTMLLike {
|
||||||
return typeof node.type === "string" || node.type === null;
|
return typeof node.type === "string" || node.type === null;
|
||||||
}
|
}
|
||||||
@@ -30,8 +31,8 @@ function isNodeComponentClass(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isConstructorHtmlLike(
|
function isConstructorHtmlLike(
|
||||||
ctr: React.ElementType
|
ctr: React.ElementType | null
|
||||||
): ctr is Exclude<React.ElementType, React.ComponentType> {
|
): ctr is Exclude<React.ElementType | null, React.ComponentType> {
|
||||||
if (typeof ctr === "string" || ctr === null) {
|
if (typeof ctr === "string" || ctr === null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -39,7 +40,7 @@ function isConstructorHtmlLike(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isConstructorComponentClass(
|
function isConstructorComponentClass(
|
||||||
ctr: React.ElementType
|
ctr: React.ElementType | null
|
||||||
): ctr is React.ComponentClass {
|
): ctr is React.ComponentClass {
|
||||||
if (isConstructorHtmlLike(ctr)) {
|
if (isConstructorHtmlLike(ctr)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -56,15 +57,20 @@ function isConstructorComponentClass(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isConstructorFunctionComponent(
|
function isConstructorFunctionComponent(
|
||||||
ctr: React.ElementType
|
ctr: React.ElementType | null
|
||||||
): ctr is React.FunctionComponent {
|
): ctr is React.FunctionComponent {
|
||||||
return !isConstructorComponentClass(ctr);
|
return typeof ctr === "function" && !isConstructorComponentClass(ctr);
|
||||||
}
|
}
|
||||||
|
|
||||||
function doesElementContainRootFiberNode(
|
function doesElementContainRootFiberNode(
|
||||||
element: Element
|
element: Element
|
||||||
): element is FiberNodeDOMContainer {
|
): element is FiberNodeDOMContainer {
|
||||||
return element.hasOwnProperty("_reactRootContainer");
|
return (
|
||||||
|
element.hasOwnProperty("_reactRootContainer") &&
|
||||||
|
(element as (Element & {
|
||||||
|
_reactRootContainer: any;
|
||||||
|
}))._reactRootContainer.hasOwnProperty("_internalRoot")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,7 +89,7 @@ function getRootFiberNodeFromDOM(startElement?: Element): FiberNode | null {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let returnFiberNode = null;
|
let returnFiberNode = null;
|
||||||
for (const childNode of startElement.children) {
|
for (const childNode of [].slice.call(startElement.children)) {
|
||||||
returnFiberNode = getRootFiberNodeFromDOM(childNode);
|
returnFiberNode = getRootFiberNodeFromDOM(childNode);
|
||||||
if (returnFiberNode !== null) {
|
if (returnFiberNode !== null) {
|
||||||
return returnFiberNode;
|
return returnFiberNode;
|
||||||
@@ -101,5 +107,6 @@ export {
|
|||||||
isConstructorHtmlLike,
|
isConstructorHtmlLike,
|
||||||
isConstructorComponentClass,
|
isConstructorComponentClass,
|
||||||
isConstructorFunctionComponent,
|
isConstructorFunctionComponent,
|
||||||
|
doesElementContainRootFiberNode,
|
||||||
getRootFiberNodeFromDOM
|
getRootFiberNodeFromDOM
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,177 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
// Import stuff from src
|
||||||
|
import { findNodeByComponent } from "../src";
|
||||||
|
import { mountAndGetRootNode } from "./utils/mountInEnzyme";
|
||||||
|
import getWrappedComponent from "./utils/getWrappedComponent";
|
||||||
|
|
||||||
|
// Import test helpers and sample components
|
||||||
|
import CDepth1 from "./sample-components/depth-1-simple";
|
||||||
|
import FnDepth1 from "./sample-components/depth-1-fn-simple";
|
||||||
|
import { createClassComponent } from "./utils/createComponent";
|
||||||
|
|
||||||
|
describe("findNodeByComponent", () => {
|
||||||
|
let container: HTMLDivElement;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
container = document.body.appendChild(document.createElement("div"));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
document.body.removeChild(container);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("missing", () => {
|
||||||
|
it("should not work for top-level class with same component name", () => {
|
||||||
|
const WrappedC = getWrappedComponent(CDepth1);
|
||||||
|
const rootNode = mountAndGetRootNode(WrappedC, container);
|
||||||
|
|
||||||
|
const FakeCDepth1 = createClassComponent(CDepth1.name);
|
||||||
|
const found = findNodeByComponent(rootNode, FakeCDepth1);
|
||||||
|
|
||||||
|
expect(found).toBeFalsy();
|
||||||
|
expect(found).toBe(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for top-level class with different component name", () => {
|
||||||
|
const WrappedC = getWrappedComponent(CDepth1);
|
||||||
|
const rootNode = mountAndGetRootNode(WrappedC, container);
|
||||||
|
|
||||||
|
const FakeCDepth1 = createClassComponent("randomname");
|
||||||
|
const found = findNodeByComponent(rootNode, FakeCDepth1);
|
||||||
|
|
||||||
|
expect(found).toBeFalsy();
|
||||||
|
expect(found).toBe(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for 2nd-level class with same component name", () => {
|
||||||
|
class C1 extends React.Component {
|
||||||
|
render() {
|
||||||
|
return <C2 />;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class C2 extends React.Component {
|
||||||
|
render() {
|
||||||
|
return <div>C2 here</div>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const WrappedC = getWrappedComponent(C1);
|
||||||
|
const rootNode = mountAndGetRootNode(WrappedC, container);
|
||||||
|
|
||||||
|
const FakeC2 = createClassComponent(C2.name);
|
||||||
|
const found = findNodeByComponent(rootNode, FakeC2);
|
||||||
|
|
||||||
|
expect(found).toBeFalsy();
|
||||||
|
expect(found).toBe(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for 2nd-level class with different component name", () => {
|
||||||
|
class C1 extends React.Component {
|
||||||
|
render() {
|
||||||
|
return <C2 />;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class C2 extends React.Component {
|
||||||
|
render() {
|
||||||
|
return <div>C2 here</div>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const WrappedC = getWrappedComponent(C1);
|
||||||
|
const rootNode = mountAndGetRootNode(WrappedC, container);
|
||||||
|
|
||||||
|
const FakeC2 = createClassComponent("randomName");
|
||||||
|
const found = findNodeByComponent(rootNode, FakeC2);
|
||||||
|
|
||||||
|
expect(found).toBeFalsy();
|
||||||
|
expect(found).toBe(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for top-level function with same function name", () => {
|
||||||
|
const WrappedC = getWrappedComponent(FnDepth1);
|
||||||
|
const rootNode = mountAndGetRootNode(WrappedC, container);
|
||||||
|
|
||||||
|
const FakeFnDepth1 = createClassComponent(FnDepth1.name);
|
||||||
|
const found = findNodeByComponent(rootNode, FakeFnDepth1);
|
||||||
|
|
||||||
|
expect(found).toBeFalsy();
|
||||||
|
expect(found).toBe(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for top-level function with different function name", () => {
|
||||||
|
const WrappedC = getWrappedComponent(FnDepth1);
|
||||||
|
const rootNode = mountAndGetRootNode(WrappedC, container);
|
||||||
|
|
||||||
|
const FakeFnDepth1 = createClassComponent("randomName");
|
||||||
|
const found = findNodeByComponent(rootNode, FakeFnDepth1);
|
||||||
|
|
||||||
|
expect(found).toBeFalsy();
|
||||||
|
expect(found).toBe(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for 2nd-level function with same function name", () => {
|
||||||
|
function Fn1() {
|
||||||
|
return <Fn2 />;
|
||||||
|
}
|
||||||
|
function Fn2() {
|
||||||
|
return <div>Fn2 here</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const WrappedC = getWrappedComponent(Fn1);
|
||||||
|
const rootNode = mountAndGetRootNode(WrappedC, container);
|
||||||
|
|
||||||
|
const FakeFn2 = createClassComponent(Fn2.name);
|
||||||
|
const found = findNodeByComponent(rootNode, FakeFn2);
|
||||||
|
|
||||||
|
expect(found).toBeFalsy();
|
||||||
|
expect(found).toBe(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for 2nd-level function with different function name", () => {
|
||||||
|
function Fn1() {
|
||||||
|
return <Fn2 />;
|
||||||
|
}
|
||||||
|
function Fn2() {
|
||||||
|
return <div>Fn2 here</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const WrappedC = getWrappedComponent(Fn1);
|
||||||
|
const rootNode = mountAndGetRootNode(WrappedC, container);
|
||||||
|
|
||||||
|
const FakeFn2 = createClassComponent("randomName");
|
||||||
|
const found = findNodeByComponent(rootNode, FakeFn2);
|
||||||
|
|
||||||
|
expect(found).toBeFalsy();
|
||||||
|
expect(found).toBe(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for 5th-level function with same or diff fn name", () => {
|
||||||
|
function Fn1() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<span></span>
|
||||||
|
<Fn2></Fn2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Fn2() {
|
||||||
|
return <a href="google.com">Fn2 here</a>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const WrappedC = getWrappedComponent(Fn1);
|
||||||
|
const rootNode = mountAndGetRootNode(WrappedC, container);
|
||||||
|
|
||||||
|
const FakeFn2Same = createClassComponent(Fn2.name);
|
||||||
|
const FakeFn2Diff = createClassComponent("randomname");
|
||||||
|
const foundSame = findNodeByComponent(rootNode, FakeFn2Same);
|
||||||
|
const foundDiff = findNodeByComponent(rootNode, FakeFn2Diff);
|
||||||
|
|
||||||
|
expect(foundSame).toBeFalsy();
|
||||||
|
expect(foundSame).toBe(null);
|
||||||
|
expect(foundDiff).toBeFalsy();
|
||||||
|
expect(foundDiff).toBe(null);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
// Import stuff from src
|
||||||
|
import { findNodeByComponentRef } from "../src";
|
||||||
|
import { mountAndGetRootNode } from "./utils/mountInEnzyme";
|
||||||
|
import getWrappedComponent from "./utils/getWrappedComponent";
|
||||||
|
|
||||||
|
class RandomClass extends React.Component {
|
||||||
|
render() {
|
||||||
|
return <div></div>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Import test helpers and sample components
|
||||||
|
|
||||||
|
describe("findNodeByComponentRef", () => {
|
||||||
|
let container: HTMLDivElement;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
container = document.body.appendChild(document.createElement("div"));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
document.body.removeChild(container);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("negative", () => {
|
||||||
|
it("should not work for 2nd-level class", () => {
|
||||||
|
const C2Ref = React.createRef<C2>();
|
||||||
|
|
||||||
|
class C1 extends React.Component {
|
||||||
|
render() {
|
||||||
|
return <C2 ref={C2Ref} />;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class C2 extends React.Component {
|
||||||
|
render() {
|
||||||
|
return <div>C2 here</div>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const WrappedC = getWrappedComponent(C1);
|
||||||
|
const rootNode = mountAndGetRootNode(WrappedC, container);
|
||||||
|
|
||||||
|
if (C2Ref.current === null) {
|
||||||
|
throw new Error("Ref is not yet set");
|
||||||
|
}
|
||||||
|
|
||||||
|
const foundSame = findNodeByComponentRef(rootNode, new C2({}));
|
||||||
|
const foundDiff = findNodeByComponentRef(rootNode, new RandomClass({}));
|
||||||
|
|
||||||
|
expect(foundSame).toBeFalsy();
|
||||||
|
expect(foundSame).toBe(null);
|
||||||
|
expect(foundDiff).toBeFalsy();
|
||||||
|
expect(foundDiff).toBe(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should work for 5th-level class", () => {
|
||||||
|
const C2Ref = React.createRef<C2>();
|
||||||
|
|
||||||
|
class C1 extends React.Component {
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<span></span>
|
||||||
|
<C2 ref={C2Ref}></C2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class C2 extends React.Component {
|
||||||
|
render() {
|
||||||
|
return <a href="google.com">Fn2 here</a>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const WrappedC = getWrappedComponent(C1);
|
||||||
|
const rootNode = mountAndGetRootNode(WrappedC, container);
|
||||||
|
|
||||||
|
if (C2Ref.current === null) {
|
||||||
|
throw new Error("Ref is not yet set");
|
||||||
|
}
|
||||||
|
|
||||||
|
const foundSame = findNodeByComponentRef(rootNode, new C2({}));
|
||||||
|
const foundDiff = findNodeByComponentRef(rootNode, new RandomClass({}));
|
||||||
|
|
||||||
|
expect(foundSame).toBeFalsy();
|
||||||
|
expect(foundSame).toBe(null);
|
||||||
|
expect(foundDiff).toBeFalsy();
|
||||||
|
expect(foundDiff).toBe(null);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
// Import stuff from src
|
||||||
|
import {
|
||||||
|
// matchGenerator,
|
||||||
|
matchAll
|
||||||
|
// matchFirst
|
||||||
|
} from "../src";
|
||||||
|
|
||||||
|
import {
|
||||||
|
FiberNodeForComponentClass
|
||||||
|
// FiberNodeForInstrinsicElement,
|
||||||
|
// FiberNodeForFunctionComponent
|
||||||
|
} from "../src/mocked-types";
|
||||||
|
|
||||||
|
// Import test helpers and sample components
|
||||||
|
import { mountAndGetRootNode } from "./utils/mountInEnzyme";
|
||||||
|
import {
|
||||||
|
// createClassComponents,
|
||||||
|
// createFunctionComponents,
|
||||||
|
createClassComponent,
|
||||||
|
createClassComponents
|
||||||
|
} from "./utils/createComponent";
|
||||||
|
|
||||||
|
describe("matchGenerator", () => {
|
||||||
|
let container: HTMLDivElement;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
container = document.body.appendChild(document.createElement("div"));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
document.body.removeChild(container);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("basic", () => {
|
||||||
|
it("should work for depth=1 class", () => {
|
||||||
|
const C1 = createClassComponent("C1");
|
||||||
|
function CRoot() {
|
||||||
|
return <C1 />;
|
||||||
|
}
|
||||||
|
const rootNode = mountAndGetRootNode(CRoot, container);
|
||||||
|
|
||||||
|
const nodes = matchAll(rootNode, "C1");
|
||||||
|
|
||||||
|
// Can't be zero, in any case
|
||||||
|
expect(nodes.length).not.toBe(0);
|
||||||
|
// Check that only one node is yielded
|
||||||
|
expect(nodes.length).toBe(1);
|
||||||
|
// Check that type is correct
|
||||||
|
expect((nodes[0] as FiberNodeForComponentClass).type).toBe(C1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should work for depth=2 class", () => {
|
||||||
|
const [C1, C2] = createClassComponents(["C1", "C2"]);
|
||||||
|
function CRoot() {
|
||||||
|
return (
|
||||||
|
<C1>
|
||||||
|
<C2 />
|
||||||
|
</C1>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const rootNode = mountAndGetRootNode(CRoot, container);
|
||||||
|
|
||||||
|
const nodes = matchAll(rootNode, "C2");
|
||||||
|
|
||||||
|
// Can't be zero, in any case
|
||||||
|
expect(nodes.length).not.toBe(0);
|
||||||
|
// Check that only one node is yielded
|
||||||
|
expect(nodes.length).toBe(1);
|
||||||
|
// Check that type is correct
|
||||||
|
expect((nodes[0] as FiberNodeForComponentClass).type).toBe(C2);
|
||||||
|
expect((nodes[0] as FiberNodeForComponentClass).type).not.toBe(C1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should work for depth=2 class with descendant selector", () => {
|
||||||
|
const [C1, C2] = createClassComponents(["C1", "C2"]);
|
||||||
|
function CRoot() {
|
||||||
|
return (
|
||||||
|
<C1>
|
||||||
|
<C2 />
|
||||||
|
</C1>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const rootNode = mountAndGetRootNode(CRoot, container);
|
||||||
|
|
||||||
|
const nodes = matchAll(rootNode, "C1 C2");
|
||||||
|
|
||||||
|
// Can't be zero, in any case
|
||||||
|
expect(nodes.length).not.toBe(0);
|
||||||
|
// Check that only one node is yielded
|
||||||
|
expect(nodes.length).toBe(1);
|
||||||
|
// Check that type is correct
|
||||||
|
expect((nodes[0] as FiberNodeForComponentClass).type).toBe(C2);
|
||||||
|
expect((nodes[0] as FiberNodeForComponentClass).type).not.toBe(C1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should work for depth=2 class with child selector", () => {
|
||||||
|
const [C1, C2] = createClassComponents(["C1", "C2"]);
|
||||||
|
function CRoot() {
|
||||||
|
return (
|
||||||
|
<C1>
|
||||||
|
<C2 />
|
||||||
|
</C1>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const rootNode = mountAndGetRootNode(CRoot, container);
|
||||||
|
|
||||||
|
const nodes = matchAll(rootNode, "C1>C2");
|
||||||
|
|
||||||
|
// Can't be zero, in any case
|
||||||
|
expect(nodes.length).not.toBe(0);
|
||||||
|
// Check that only one node is yielded
|
||||||
|
expect(nodes.length).toBe(1);
|
||||||
|
// Check that type is correct
|
||||||
|
expect((nodes[0] as FiberNodeForComponentClass).type).toBe(C2);
|
||||||
|
expect((nodes[0] as FiberNodeForComponentClass).type).not.toBe(C1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work with child selector for nth-level descendant", () => {
|
||||||
|
const [C1, C2, C3] = createClassComponents(["C1", "C2", "C3"]);
|
||||||
|
function CRoot() {
|
||||||
|
return (
|
||||||
|
<C1>
|
||||||
|
<C2>
|
||||||
|
<C3 />
|
||||||
|
</C2>
|
||||||
|
</C1>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const rootNode = mountAndGetRootNode(CRoot, container);
|
||||||
|
|
||||||
|
const nodes = matchAll(rootNode, "C1>C3");
|
||||||
|
|
||||||
|
// No matcch found
|
||||||
|
expect(nodes.length).toBe(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -26,7 +26,7 @@ describe("traverseGenerator", () => {
|
|||||||
document.body.removeChild(container);
|
document.body.removeChild(container);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("basic", () => {
|
describe("ordered", () => {
|
||||||
it("order doesn't matter for 1 node if self is present - case 1", () => {
|
it("order doesn't matter for 1 node if self is present - case 1", () => {
|
||||||
const rootNode = mountAndGetRootNode(CDepth1, container);
|
const rootNode = mountAndGetRootNode(CDepth1, container);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,143 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
// Import stuff from src
|
||||||
|
import { FiberNodeForComponentClass, FiberNode } from "../src/mocked-types";
|
||||||
|
import { traverseGenerator } from "../src";
|
||||||
|
|
||||||
|
// Import test helpers and sample components
|
||||||
|
import { mountAndGetRootNode } from "./utils/mountInEnzyme";
|
||||||
|
import {
|
||||||
|
createClassComponents
|
||||||
|
// createFunctionComponents
|
||||||
|
} from "./utils/createComponent";
|
||||||
|
|
||||||
|
describe("traverseGenerator", () => {
|
||||||
|
let container: HTMLDivElement;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
container = document.body.appendChild(document.createElement("div"));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
document.body.removeChild(container);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("skipped", () => {
|
||||||
|
it("should traverse just top-level with skipChild", () => {
|
||||||
|
const [C2, C3, C4, C5] = createClassComponents(["C2", "C3", "C4", "C5"]);
|
||||||
|
class C1 extends React.Component {
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<C2>
|
||||||
|
<C3 />
|
||||||
|
</C2>
|
||||||
|
<C4>
|
||||||
|
<C5 />
|
||||||
|
</C4>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const rootNode = mountAndGetRootNode(C1, container);
|
||||||
|
|
||||||
|
const nodeIterator = traverseGenerator(rootNode);
|
||||||
|
|
||||||
|
// Consume generator
|
||||||
|
let nodes: Array<FiberNode> = [];
|
||||||
|
const genArgs = { skipChild: true };
|
||||||
|
for (
|
||||||
|
let result = nodeIterator.next();
|
||||||
|
!result.done;
|
||||||
|
result = nodeIterator.next(genArgs)
|
||||||
|
) {
|
||||||
|
const currentNode = result.value;
|
||||||
|
nodes.push(currentNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(nodes.length).toBe(1);
|
||||||
|
expect(
|
||||||
|
nodes.map(tmpNode => (tmpNode as FiberNodeForComponentClass).type)
|
||||||
|
).toEqual([C1]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should traverse just first 2 levels with inner skipChild", () => {
|
||||||
|
const [C2, C3, C4, C5] = createClassComponents(["C2", "C3", "C4", "C5"]);
|
||||||
|
class C1 extends React.Component {
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<C2>
|
||||||
|
<C3 />
|
||||||
|
</C2>
|
||||||
|
<C4>
|
||||||
|
<C5 />
|
||||||
|
</C4>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const rootNode = mountAndGetRootNode(C1, container);
|
||||||
|
|
||||||
|
const nodeIterator = traverseGenerator(rootNode);
|
||||||
|
|
||||||
|
// Consume generator
|
||||||
|
let nodes: Array<FiberNode> = [];
|
||||||
|
const genArgs = { skipChild: true };
|
||||||
|
for (
|
||||||
|
let result = nodeIterator.next();
|
||||||
|
!result.done;
|
||||||
|
result = nodeIterator.next(nodes.length > 1 ? genArgs : undefined)
|
||||||
|
) {
|
||||||
|
const currentNode = result.value;
|
||||||
|
nodes.push(currentNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(nodes.length).toBe(3);
|
||||||
|
expect(
|
||||||
|
nodes.map(tmpNode => (tmpNode as FiberNodeForComponentClass).type)
|
||||||
|
).toEqual([C1, C2, C4]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should traverse one branch correctly with skipSibling", () => {
|
||||||
|
const [C2, C3, C4, C5] = createClassComponents(["C2", "C3", "C4", "C5"]);
|
||||||
|
class C1 extends React.Component {
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<C2>
|
||||||
|
<C3 />
|
||||||
|
</C2>
|
||||||
|
<C4>
|
||||||
|
<C5 />
|
||||||
|
</C4>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const rootNode = mountAndGetRootNode(C1, container);
|
||||||
|
|
||||||
|
const nodeIterator = traverseGenerator(rootNode);
|
||||||
|
|
||||||
|
// Consume generator
|
||||||
|
let nodes: Array<FiberNode> = [];
|
||||||
|
const genArgs = { skipSibling: true };
|
||||||
|
for (
|
||||||
|
let result = nodeIterator.next();
|
||||||
|
!result.done;
|
||||||
|
result = nodeIterator.next(genArgs)
|
||||||
|
) {
|
||||||
|
const currentNode = result.value;
|
||||||
|
nodes.push(currentNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(nodes.length).toBe(3);
|
||||||
|
expect(
|
||||||
|
nodes.map(tmpNode => (tmpNode as FiberNodeForComponentClass).type)
|
||||||
|
).toEqual([C1, C2, C3]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
// import * as React from "react";
|
||||||
|
|
||||||
|
// Import stuff from src
|
||||||
|
import { doesElementContainRootFiberNode } from "../src/utils";
|
||||||
|
|
||||||
|
// Import test helpers and sample components
|
||||||
|
import { mountAndGetRootNode } from "./utils/mountInEnzyme";
|
||||||
|
import { createFunctionComponent } from "./utils/createComponent";
|
||||||
|
|
||||||
|
describe("traverse", () => {
|
||||||
|
let container: HTMLDivElement;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
container = document.body.appendChild(document.createElement("div"));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
try {
|
||||||
|
document.body.removeChild(container);
|
||||||
|
} catch (error) {
|
||||||
|
if (!(error instanceof DOMException)) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("doesElementContainRootFiberNode", () => {
|
||||||
|
it("should work for direct element", () => {
|
||||||
|
const fn1 = createFunctionComponent("fn1");
|
||||||
|
const containerInner = container.appendChild(
|
||||||
|
document.createElement("span")
|
||||||
|
);
|
||||||
|
mountAndGetRootNode(fn1, containerInner);
|
||||||
|
|
||||||
|
const resultPositive = doesElementContainRootFiberNode(containerInner);
|
||||||
|
|
||||||
|
expect(resultPositive).not.toBeFalsy();
|
||||||
|
expect(resultPositive).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for parent element", () => {
|
||||||
|
const fn1 = createFunctionComponent("fn1");
|
||||||
|
const containerInner = container.appendChild(
|
||||||
|
document.createElement("span")
|
||||||
|
);
|
||||||
|
mountAndGetRootNode(fn1, containerInner);
|
||||||
|
|
||||||
|
const resultNegative = doesElementContainRootFiberNode(container);
|
||||||
|
|
||||||
|
expect(resultNegative).toBeFalsy();
|
||||||
|
expect(resultNegative).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for child element", () => {
|
||||||
|
const fn1 = createFunctionComponent("fn1");
|
||||||
|
const containerInner = container.appendChild(
|
||||||
|
document.createElement("span")
|
||||||
|
);
|
||||||
|
mountAndGetRootNode(fn1, container);
|
||||||
|
|
||||||
|
const resultNegative = doesElementContainRootFiberNode(containerInner);
|
||||||
|
|
||||||
|
expect(resultNegative).toBeFalsy();
|
||||||
|
expect(resultNegative).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should work for body", () => {
|
||||||
|
const fn1 = createFunctionComponent("fn1");
|
||||||
|
mountAndGetRootNode(fn1, document.body);
|
||||||
|
|
||||||
|
const resultPositive = doesElementContainRootFiberNode(document.body);
|
||||||
|
|
||||||
|
expect(resultPositive).not.toBeFalsy();
|
||||||
|
expect(resultPositive).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
// import * as React from "react";
|
||||||
|
|
||||||
|
// Import stuff from src
|
||||||
|
import { getRootFiberNodeFromDOM } from "../src/utils";
|
||||||
|
|
||||||
|
// Import test helpers and sample components
|
||||||
|
import { mountAndGetRootNode } from "./utils/mountInEnzyme";
|
||||||
|
import { createClassComponent } from "./utils/createComponent";
|
||||||
|
|
||||||
|
describe("traverse", () => {
|
||||||
|
let container: HTMLDivElement;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
container = document.body.appendChild(document.createElement("div"));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
try {
|
||||||
|
document.body.removeChild(container);
|
||||||
|
} catch (error) {
|
||||||
|
if (!(error instanceof DOMException)) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("getRootFiberNodeFromDOM", () => {
|
||||||
|
it("should work for direct element", () => {
|
||||||
|
const C1 = createClassComponent("C1");
|
||||||
|
const containerInner = container.appendChild(
|
||||||
|
document.createElement("span")
|
||||||
|
);
|
||||||
|
mountAndGetRootNode(C1, containerInner);
|
||||||
|
|
||||||
|
const resultPositive = getRootFiberNodeFromDOM(containerInner);
|
||||||
|
|
||||||
|
expect(resultPositive).not.toBeFalsy();
|
||||||
|
expect(resultPositive).not.toBe(null);
|
||||||
|
expect((resultPositive as any).child.child.type).toBe(C1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should work for parent element", () => {
|
||||||
|
const C1 = createClassComponent("C1");
|
||||||
|
const containerInner = container.appendChild(
|
||||||
|
document.createElement("span")
|
||||||
|
);
|
||||||
|
mountAndGetRootNode(C1, containerInner);
|
||||||
|
|
||||||
|
const resultPositive = getRootFiberNodeFromDOM(container);
|
||||||
|
|
||||||
|
expect(resultPositive).not.toBeFalsy();
|
||||||
|
expect(resultPositive).not.toBe(null);
|
||||||
|
expect((resultPositive as any).child.child.type).toBe(C1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should work without any element - default args", () => {
|
||||||
|
const C1 = createClassComponent("C1");
|
||||||
|
const containerInner = container.appendChild(
|
||||||
|
document.createElement("span")
|
||||||
|
);
|
||||||
|
mountAndGetRootNode(C1, containerInner);
|
||||||
|
|
||||||
|
const resultPositive = getRootFiberNodeFromDOM();
|
||||||
|
|
||||||
|
expect(resultPositive).not.toBeFalsy();
|
||||||
|
expect(resultPositive).not.toBe(null);
|
||||||
|
expect((resultPositive as any).child.child.type).toBe(C1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for child element", () => {
|
||||||
|
const C1 = createClassComponent("C1");
|
||||||
|
const containerInner = container.appendChild(
|
||||||
|
document.createElement("span")
|
||||||
|
);
|
||||||
|
mountAndGetRootNode(C1, container);
|
||||||
|
|
||||||
|
const resultNegative = getRootFiberNodeFromDOM(containerInner);
|
||||||
|
|
||||||
|
expect(resultNegative).toBeFalsy();
|
||||||
|
expect(resultNegative).toBe(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should work for body", () => {
|
||||||
|
const C1 = createClassComponent("C1");
|
||||||
|
mountAndGetRootNode(C1, document.body);
|
||||||
|
|
||||||
|
const resultPositive = getRootFiberNodeFromDOM(document.body);
|
||||||
|
|
||||||
|
expect(resultPositive).not.toBeFalsy();
|
||||||
|
expect(resultPositive).not.toBe(null);
|
||||||
|
expect((resultPositive as any).child.child.type).toBe(C1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
// import * as React from "react";
|
||||||
|
|
||||||
|
// Import stuff from src
|
||||||
|
import { isConstructorComponentClass } from "../src/utils";
|
||||||
|
import {
|
||||||
|
createFunctionComponent,
|
||||||
|
createClassComponent
|
||||||
|
} from "./utils/createComponent";
|
||||||
|
|
||||||
|
// Import test helpers and sample components
|
||||||
|
|
||||||
|
describe("utils", () => {
|
||||||
|
let container: HTMLDivElement;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
container = document.body.appendChild(document.createElement("div"));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
document.body.removeChild(container);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("isConstructorComponentClass", () => {
|
||||||
|
it("should work for class components", () => {
|
||||||
|
const C1 = createClassComponent("C1");
|
||||||
|
|
||||||
|
const resultPositive = isConstructorComponentClass(C1);
|
||||||
|
|
||||||
|
expect(resultPositive).not.toBeFalsy();
|
||||||
|
expect(resultPositive).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for any class", () => {
|
||||||
|
const C1 = class {};
|
||||||
|
|
||||||
|
const resultNegative = isConstructorComponentClass(C1 as any);
|
||||||
|
|
||||||
|
expect(resultNegative).toBeFalsy();
|
||||||
|
expect(resultNegative).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for any function", () => {
|
||||||
|
const fn1 = function() {};
|
||||||
|
|
||||||
|
const resultNegative = isConstructorComponentClass(fn1 as any);
|
||||||
|
|
||||||
|
expect(resultNegative).toBeFalsy();
|
||||||
|
expect(resultNegative).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for function components", () => {
|
||||||
|
const fn1 = createFunctionComponent();
|
||||||
|
|
||||||
|
const resultNegative = isConstructorComponentClass(fn1);
|
||||||
|
|
||||||
|
expect(resultNegative).toBeFalsy();
|
||||||
|
expect(resultNegative).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for string", () => {
|
||||||
|
const resultNegative = isConstructorComponentClass("div");
|
||||||
|
|
||||||
|
expect(resultNegative).toBeFalsy();
|
||||||
|
expect(resultNegative).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for null", () => {
|
||||||
|
const resultNegative = isConstructorComponentClass(null);
|
||||||
|
|
||||||
|
expect(resultNegative).toBeFalsy();
|
||||||
|
expect(resultNegative).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
// import * as React from "react";
|
||||||
|
|
||||||
|
// Import stuff from src
|
||||||
|
import { isConstructorFunctionComponent } from "../src/utils";
|
||||||
|
import {
|
||||||
|
createFunctionComponent,
|
||||||
|
createClassComponent
|
||||||
|
} from "./utils/createComponent";
|
||||||
|
|
||||||
|
// Import test helpers and sample components
|
||||||
|
|
||||||
|
describe("utils", () => {
|
||||||
|
let container: HTMLDivElement;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
container = document.body.appendChild(document.createElement("div"));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
document.body.removeChild(container);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("isConstructorFunctionComponent", () => {
|
||||||
|
it("should work for any function - current limitation", () => {
|
||||||
|
const fn1 = function() {};
|
||||||
|
|
||||||
|
const resultPositive = isConstructorFunctionComponent(fn1 as any);
|
||||||
|
|
||||||
|
expect(resultPositive).not.toBeFalsy();
|
||||||
|
expect(resultPositive).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should work for function components", () => {
|
||||||
|
const fn1 = createFunctionComponent();
|
||||||
|
|
||||||
|
const resultPositive = isConstructorFunctionComponent(fn1);
|
||||||
|
|
||||||
|
expect(resultPositive).not.toBeFalsy();
|
||||||
|
expect(resultPositive).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for string", () => {
|
||||||
|
const resultNegative = isConstructorFunctionComponent("div");
|
||||||
|
|
||||||
|
expect(resultNegative).toBeFalsy();
|
||||||
|
expect(resultNegative).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for null", () => {
|
||||||
|
const resultNegative = isConstructorFunctionComponent(null);
|
||||||
|
|
||||||
|
expect(resultNegative).toBeFalsy();
|
||||||
|
expect(resultNegative).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should work for any class - current limitation", () => {
|
||||||
|
const C1 = class {};
|
||||||
|
|
||||||
|
const resultPositive = isConstructorFunctionComponent(C1 as any);
|
||||||
|
|
||||||
|
expect(resultPositive).not.toBeFalsy();
|
||||||
|
expect(resultPositive).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for class components", () => {
|
||||||
|
const C1 = createClassComponent("C1");
|
||||||
|
|
||||||
|
const resultNegative = isConstructorFunctionComponent(C1);
|
||||||
|
|
||||||
|
expect(resultNegative).toBeFalsy();
|
||||||
|
expect(resultNegative).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
// import * as React from "react";
|
||||||
|
|
||||||
|
// Import stuff from src
|
||||||
|
import { isConstructorHtmlLike } from "../src/utils";
|
||||||
|
import {
|
||||||
|
createFunctionComponent,
|
||||||
|
createClassComponent
|
||||||
|
} from "./utils/createComponent";
|
||||||
|
|
||||||
|
// Import test helpers and sample components
|
||||||
|
|
||||||
|
describe("utils", () => {
|
||||||
|
let container: HTMLDivElement;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
container = document.body.appendChild(document.createElement("div"));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
document.body.removeChild(container);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("isConstructorHtmlLike", () => {
|
||||||
|
it("should work for string", () => {
|
||||||
|
const resultPositive = isConstructorHtmlLike("div");
|
||||||
|
|
||||||
|
expect(resultPositive).not.toBeFalsy();
|
||||||
|
expect(resultPositive).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should work for null", () => {
|
||||||
|
const resultPositive = isConstructorHtmlLike(null);
|
||||||
|
|
||||||
|
expect(resultPositive).not.toBeFalsy();
|
||||||
|
expect(resultPositive).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for any function", () => {
|
||||||
|
const fn1 = function() {};
|
||||||
|
|
||||||
|
const resultNegative = isConstructorHtmlLike(fn1 as any);
|
||||||
|
|
||||||
|
expect(resultNegative).toBeFalsy();
|
||||||
|
expect(resultNegative).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for function components", () => {
|
||||||
|
const fn1 = createFunctionComponent();
|
||||||
|
|
||||||
|
const resultNegative = isConstructorHtmlLike(fn1);
|
||||||
|
|
||||||
|
expect(resultNegative).toBeFalsy();
|
||||||
|
expect(resultNegative).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for any class", () => {
|
||||||
|
const C1 = class {};
|
||||||
|
|
||||||
|
const resultNegative = isConstructorHtmlLike(C1 as any);
|
||||||
|
|
||||||
|
expect(resultNegative).toBeFalsy();
|
||||||
|
expect(resultNegative).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for class components", () => {
|
||||||
|
const C1 = createClassComponent("C1");
|
||||||
|
|
||||||
|
const resultNegative = isConstructorHtmlLike(C1);
|
||||||
|
|
||||||
|
expect(resultNegative).toBeFalsy();
|
||||||
|
expect(resultNegative).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
// import * as React from "react";
|
||||||
|
|
||||||
|
// Import stuff from src
|
||||||
|
import { isNodeComponentClass } from "../src/utils";
|
||||||
|
import { mountAndGetRootNode } from "./utils/mountInEnzyme";
|
||||||
|
import {
|
||||||
|
createFunctionComponent,
|
||||||
|
createClassComponent
|
||||||
|
} from "./utils/createComponent";
|
||||||
|
|
||||||
|
// Import test helpers and sample components
|
||||||
|
|
||||||
|
describe("utils", () => {
|
||||||
|
let container: HTMLDivElement;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
container = document.body.appendChild(document.createElement("div"));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
document.body.removeChild(container);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("isNodeComponentClass", () => {
|
||||||
|
it("should work for class component", () => {
|
||||||
|
const C1 = createClassComponent("C1");
|
||||||
|
const rootNode = mountAndGetRootNode(C1, container);
|
||||||
|
|
||||||
|
const result = isNodeComponentClass(rootNode);
|
||||||
|
|
||||||
|
expect(result).not.toBeFalsy();
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for function component", () => {
|
||||||
|
const fn1 = createFunctionComponent("fn1");
|
||||||
|
const rootNode = mountAndGetRootNode(fn1, container);
|
||||||
|
|
||||||
|
const result = isNodeComponentClass(rootNode);
|
||||||
|
|
||||||
|
expect(result).toBeFalsy();
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for html like component - div", () => {
|
||||||
|
const rootNode = mountAndGetRootNode("div", container);
|
||||||
|
|
||||||
|
const result = isNodeComponentClass(rootNode);
|
||||||
|
|
||||||
|
expect(result).toBeFalsy();
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for html like component - svg", () => {
|
||||||
|
const rootNode = mountAndGetRootNode("svg", container);
|
||||||
|
|
||||||
|
const result = isNodeComponentClass(rootNode);
|
||||||
|
|
||||||
|
expect(result).toBeFalsy();
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
// import * as React from "react";
|
||||||
|
|
||||||
|
// Import stuff from src
|
||||||
|
import { isNodeFunctionComponent } from "../src/utils";
|
||||||
|
import { mountAndGetRootNode } from "./utils/mountInEnzyme";
|
||||||
|
import {
|
||||||
|
createFunctionComponent,
|
||||||
|
createClassComponent
|
||||||
|
} from "./utils/createComponent";
|
||||||
|
|
||||||
|
// Import test helpers and sample components
|
||||||
|
|
||||||
|
describe("utils", () => {
|
||||||
|
let container: HTMLDivElement;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
container = document.body.appendChild(document.createElement("div"));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
document.body.removeChild(container);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("isNodeFunctionComponent", () => {
|
||||||
|
it("should work for function component", () => {
|
||||||
|
const fn1 = createFunctionComponent("fn1");
|
||||||
|
const rootNode = mountAndGetRootNode(fn1, container);
|
||||||
|
|
||||||
|
const result = isNodeFunctionComponent(rootNode);
|
||||||
|
|
||||||
|
expect(result).not.toBeFalsy();
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for class component", () => {
|
||||||
|
const C1 = createClassComponent("C1");
|
||||||
|
const rootNode = mountAndGetRootNode(C1, container);
|
||||||
|
|
||||||
|
const result = isNodeFunctionComponent(rootNode);
|
||||||
|
|
||||||
|
expect(result).toBeFalsy();
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for html like component - div", () => {
|
||||||
|
const rootNode = mountAndGetRootNode("div", container);
|
||||||
|
|
||||||
|
const result = isNodeFunctionComponent(rootNode);
|
||||||
|
|
||||||
|
expect(result).toBeFalsy();
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should work for html like component - svg", () => {
|
||||||
|
const rootNode = mountAndGetRootNode("svg", container);
|
||||||
|
|
||||||
|
const result = isNodeFunctionComponent(rootNode);
|
||||||
|
|
||||||
|
expect(result).toBeFalsy();
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
// Import stuff from src
|
||||||
|
import { isNodeHtmlLike, isNodeNotHtmlLike } from "../src/utils";
|
||||||
|
import { mountAndGetRootNode } from "./utils/mountInEnzyme";
|
||||||
|
import { FiberNodeForInstrinsicElement } from "../src/mocked-types";
|
||||||
|
import {
|
||||||
|
createFunctionComponent,
|
||||||
|
createClassComponent
|
||||||
|
} from "./utils/createComponent";
|
||||||
|
|
||||||
|
// Import test helpers and sample components
|
||||||
|
|
||||||
|
describe("utils", () => {
|
||||||
|
let container: HTMLDivElement;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
container = document.body.appendChild(document.createElement("div"));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
document.body.removeChild(container);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("isNodeHtmlLike", () => {
|
||||||
|
it("should work for div", () => {
|
||||||
|
const rootNode = mountAndGetRootNode("div", container);
|
||||||
|
|
||||||
|
const resultPositive = isNodeHtmlLike(rootNode);
|
||||||
|
const resultNegative = isNodeNotHtmlLike(rootNode);
|
||||||
|
|
||||||
|
expect(resultPositive).not.toBeFalsy();
|
||||||
|
expect(resultPositive).toBe(true);
|
||||||
|
expect(resultNegative).toBeFalsy();
|
||||||
|
expect(resultNegative).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should work for svg root element", () => {
|
||||||
|
const rootNode = mountAndGetRootNode("svg", container);
|
||||||
|
|
||||||
|
const resultPositive = isNodeHtmlLike(rootNode);
|
||||||
|
const resultNegative = isNodeNotHtmlLike(rootNode);
|
||||||
|
|
||||||
|
expect(resultPositive).not.toBeFalsy();
|
||||||
|
expect(resultPositive).toBe(true);
|
||||||
|
expect(resultNegative).toBeFalsy();
|
||||||
|
expect(resultNegative).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should work for svg inner elements", () => {
|
||||||
|
function SomeSVG() {
|
||||||
|
return (
|
||||||
|
<svg>
|
||||||
|
<circle cx={5} />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const rootNode = mountAndGetRootNode(SomeSVG, container);
|
||||||
|
|
||||||
|
expect(isNodeHtmlLike(rootNode)).toBeFalsy();
|
||||||
|
|
||||||
|
const circleNode = (rootNode.child as FiberNodeForInstrinsicElement)
|
||||||
|
.child as FiberNodeForInstrinsicElement;
|
||||||
|
expect(circleNode).not.toBe(null);
|
||||||
|
expect(circleNode.type).toBe("circle");
|
||||||
|
|
||||||
|
const resultPositive = isNodeHtmlLike(circleNode);
|
||||||
|
const resultNegative = isNodeNotHtmlLike(circleNode);
|
||||||
|
|
||||||
|
expect(resultPositive).not.toBeFalsy();
|
||||||
|
expect(resultPositive).toBe(true);
|
||||||
|
expect(resultNegative).toBeFalsy();
|
||||||
|
expect(resultNegative).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for function component", () => {
|
||||||
|
const fn1 = createFunctionComponent("fn1");
|
||||||
|
const rootNode = mountAndGetRootNode(fn1, container);
|
||||||
|
|
||||||
|
const resultPositive = isNodeNotHtmlLike(rootNode);
|
||||||
|
const resultNegative = isNodeHtmlLike(rootNode);
|
||||||
|
|
||||||
|
expect(resultPositive).not.toBeFalsy();
|
||||||
|
expect(resultPositive).toBe(true);
|
||||||
|
expect(resultNegative).toBeFalsy();
|
||||||
|
expect(resultNegative).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not work for class component", () => {
|
||||||
|
const C1 = createClassComponent("C1");
|
||||||
|
const rootNode = mountAndGetRootNode(C1, container);
|
||||||
|
|
||||||
|
const resultPositive = isNodeNotHtmlLike(rootNode);
|
||||||
|
const resultNegative = isNodeHtmlLike(rootNode);
|
||||||
|
|
||||||
|
expect(resultPositive).not.toBeFalsy();
|
||||||
|
expect(resultPositive).toBe(true);
|
||||||
|
expect(resultNegative).toBeFalsy();
|
||||||
|
expect(resultNegative).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { mount } from "enzyme";
|
import { mount } from "enzyme";
|
||||||
import { FiberNode, FiberNodeForComponentClass } from "../../src/mocked-types";
|
import { FiberNode, FiberNodeForComponentClass } from "../../src/mocked-types";
|
||||||
import { isConstructorFunctionComponent } from "../../src/utils";
|
import { isConstructorComponentClass } from "../../src/utils";
|
||||||
import getWrappedComponent from "./getWrappedComponent";
|
import getWrappedComponent from "./getWrappedComponent";
|
||||||
|
|
||||||
export class RootNodeNotFoundError extends Error {
|
export class RootNodeNotFoundError extends Error {
|
||||||
@@ -13,14 +13,14 @@ export class RootNodeNotFoundError extends Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function mountAndGetRootNode(
|
export function mountAndGetRootNode(
|
||||||
SomeComponent: React.ComponentType,
|
SomeComponent: React.ElementType,
|
||||||
container: HTMLElement
|
container: HTMLElement
|
||||||
): FiberNode {
|
): FiberNode {
|
||||||
const rootRef = React.createRef<React.Component>();
|
const rootRef = React.createRef<React.Component>();
|
||||||
|
|
||||||
let ToMount = undefined;
|
let ToMount: React.ComponentClass | undefined = undefined;
|
||||||
// Wrap function components in ComponentClass to be able to set ref
|
// Wrap function components in ComponentClass to be able to set ref
|
||||||
if (isConstructorFunctionComponent(SomeComponent)) {
|
if (!isConstructorComponentClass(SomeComponent)) {
|
||||||
ToMount = getWrappedComponent(SomeComponent);
|
ToMount = getWrappedComponent(SomeComponent);
|
||||||
} else {
|
} else {
|
||||||
ToMount = SomeComponent;
|
ToMount = SomeComponent;
|
||||||
@@ -41,7 +41,7 @@ export function mountAndGetRootNode(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Unwrap function components to return expected root node
|
// Unwrap function components to return expected root node
|
||||||
if (isConstructorFunctionComponent(SomeComponent)) {
|
if (!isConstructorComponentClass(SomeComponent)) {
|
||||||
return (rootNode as FiberNodeForComponentClass).child as FiberNode;
|
return (rootNode as FiberNodeForComponentClass).child as FiberNode;
|
||||||
} else {
|
} else {
|
||||||
return rootNode;
|
return rootNode;
|
||||||
|
|||||||
+2
-1
@@ -17,7 +17,8 @@
|
|||||||
"removeComments": true,
|
"removeComments": true,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"target": "es6"
|
"target": "es5",
|
||||||
|
"downlevelIteration": true
|
||||||
},
|
},
|
||||||
"exclude": ["node_modules", "dist"],
|
"exclude": ["node_modules", "dist"],
|
||||||
"include": ["src"]
|
"include": ["src"]
|
||||||
|
|||||||
Reference in New Issue
Block a user