Compare commits

..
Author SHA1 Message Date
bendtherules 17046c9aa4 Merge branch 'master' of https://github.com/bendtherules/react-fiber-traverse into test-multi-react 2019-09-09 16:14:02 +05:30
bendtherules 144f4a861b travis - Name each matrix job 2019-09-01 21:55:51 +05:30
bendtherules adb1dae2c2 travis - Fix env var naming case 2019-09-01 21:46:04 +05:30
bendtherules c48057b6a4 travis.yml - Add multiple env for each react version
react and react-dom version combos mentioned together
2019-09-01 21:37:26 +05:30
27 changed files with 192 additions and 906 deletions
+18 -18
View File
@@ -1,36 +1,36 @@
{
"dist/react-fiber-traverse.cjs.development.js": {
"bundled": 19424,
"minified": 8388,
"gzipped": 2612
"bundled": 9674,
"minified": 4533,
"gzipped": 1335
},
"dist/react-fiber-traverse.cjs.production.js": {
"bundled": 19424,
"minified": 8388,
"gzipped": 2612
"bundled": 9674,
"minified": 4533,
"gzipped": 1335
},
"dist/react-fiber-traverse.esm.js": {
"bundled": 19124,
"minified": 8112,
"gzipped": 2537,
"bundled": 9312,
"minified": 4229,
"gzipped": 1245,
"treeshaked": {
"rollup": {
"code": 31,
"import_statements": 31
"code": 49,
"import_statements": 49
},
"webpack": {
"code": 1048
"code": 1066
}
}
},
"dist/react-fiber-traverse.umd.development.js": {
"bundled": 34569,
"minified": 11581,
"gzipped": 4230
"bundled": 34862,
"minified": 9669,
"gzipped": 3394
},
"dist/react-fiber-traverse.umd.production.js": {
"bundled": 34569,
"minified": 11581,
"gzipped": 4230
"bundled": 34862,
"minified": 9669,
"gzipped": 3394
}
}
+29
View File
@@ -1,6 +1,35 @@
language: node_js
matrix:
include:
- name: "react 16.0.x"
env: REACT_V=react@16.0.x REACT_DOM_V=react-dom@16.0.x
- name: "react 16.1.x"
env: REACT_V=react@16.1.x REACT_DOM_V=react-dom@16.1.x
- name: "react 16.2.x"
env: REACT_V=react@16.2.x REACT_DOM_V=react-dom@16.2.x
- name: "react 16.3.x"
env: REACT_V=react@16.3.x REACT_DOM_V=react-dom@16.3.x
- name: "react 16.4.x"
env: REACT_V=react@16.4.x REACT_DOM_V=react-dom@16.4.x
- name: "react 16.5.x"
env: REACT_V=react@16.5.x REACT_DOM_V=react-dom@16.5.x
- name: "react 16.6.x"
env: REACT_V=react@16.6.x REACT_DOM_V=react-dom@16.6.x
- name: "react 16.7.x"
env: REACT_V=react@16.7.x REACT_DOM_V=react-dom@16.7.x
- name: "react 16.8.x"
env: REACT_V=react@16.8.x REACT_DOM_V=react-dom@16.8.x
- name: "react 16.9.x"
env: REACT_V=react@16.9.x REACT_DOM_V=react-dom@16.9.x
notifications:
email: false
# Install reqd react and react-dom version for each matrix
before_script:
- echo $REACT_V $REACT_DOM_V # log react and react-dom versions
- npm i --no-save $REACT_V $REACT_DOM_V # install them
script:
- npm run test
- npx codecov
+1 -2
View File
@@ -13,6 +13,5 @@
"javascriptreact",
"typescript",
"typescriptreact"
],
"typescript.tsdk": "node_modules\\typescript\\lib"
]
}
-12
View File
@@ -6,7 +6,6 @@
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
@@ -15,14 +14,3 @@
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**
-30
View File
@@ -80,36 +80,6 @@ For the minified production version, make sure you have already included:
- [`React`](https://unpkg.com/react/umd/react.production.min.js)
- [`ReactDOM`](https://unpkg.com/react-dom/umd/react-dom.production.min.js)
## Overview
This package contains few utility functions which operate over react-fiber tree.
Overall characteristics are:
1. Only read-only operations
2. Support inversion of control
There are few categories of helpers, each with their variations:
1. Find node(s)
2. Traverse node
3. Others - Check node type, find root node, etc.
Little more info is present in docs section.
## Concerns and improvements
Currently, it assumes that nodes are created by `react 16.3+` with appropriate `react-dom`.
Because fiber nodes are internal to react and are supported by multiple renderers, this is an incorrect assumption to make. It should:
1. support diff versions of react (which have fiber node, but slight variations of it)
2. be renderer-agnostic (say, support react-fs-renderer) but with extra helpers for react-dom.
3. heavily tested with all these variations (to know when internals have changed).
## Docs
Docs are sparse at the moment. I plan on adding them soon.
Till then, the auto-generated (typedoc) docs available in [docs folder](./docs/globals.md) might be of some help.
## License
MIT
-1
View File
@@ -10,7 +10,6 @@
* ["findNode"](modules/_findnode_.md)
* ["index"](modules/_index_.md)
* ["match"](modules/_match_.md)
* ["mocked-types/index"](modules/_mocked_types_index_.md)
* ["traverse"](modules/_traverse_.md)
* ["utils"](modules/_utils_.md)
@@ -347,7 +347,7 @@ ___
**_reactRootContainer**: *object*
*Defined in [mocked-types/index.ts:4](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L4)*
*Defined in [mocked-types/index.ts:4](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L4)*
#### Type declaration:
@@ -24,7 +24,7 @@
**child**: *[FiberNode](../modules/_mocked_types_index_.md#fibernode) | null*
*Defined in [mocked-types/index.ts:28](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L28)*
*Defined in [mocked-types/index.ts:28](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L28)*
___
@@ -32,7 +32,7 @@ ___
**elementType**: *`ComponentClass`*
*Defined in [mocked-types/index.ts:31](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L31)*
*Defined in [mocked-types/index.ts:31](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L31)*
___
@@ -40,7 +40,7 @@ ___
**sibling**: *[FiberNode](../modules/_mocked_types_index_.md#fibernode) | null*
*Defined in [mocked-types/index.ts:29](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L29)*
*Defined in [mocked-types/index.ts:29](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L29)*
___
@@ -48,7 +48,7 @@ ___
**stateNode**: *`Component`*
*Defined in [mocked-types/index.ts:34](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L34)*
*Defined in [mocked-types/index.ts:34](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L34)*
___
@@ -56,4 +56,4 @@ ___
**type**: *`ComponentClass`*
*Defined in [mocked-types/index.ts:32](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L32)*
*Defined in [mocked-types/index.ts:32](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L32)*
@@ -24,7 +24,7 @@
**child**: *[FiberNode](../modules/_mocked_types_index_.md#fibernode) | null*
*Defined in [mocked-types/index.ts:18](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L18)*
*Defined in [mocked-types/index.ts:18](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L18)*
___
@@ -32,7 +32,7 @@ ___
**elementType**: *`FunctionComponent`*
*Defined in [mocked-types/index.ts:21](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L21)*
*Defined in [mocked-types/index.ts:21](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L21)*
___
@@ -40,7 +40,7 @@ ___
**sibling**: *[FiberNode](../modules/_mocked_types_index_.md#fibernode) | null*
*Defined in [mocked-types/index.ts:19](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L19)*
*Defined in [mocked-types/index.ts:19](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L19)*
___
@@ -48,7 +48,7 @@ ___
**stateNode**: *null*
*Defined in [mocked-types/index.ts:24](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L24)*
*Defined in [mocked-types/index.ts:24](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L24)*
___
@@ -56,4 +56,4 @@ ___
**type**: *`FunctionComponent`*
*Defined in [mocked-types/index.ts:22](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L22)*
*Defined in [mocked-types/index.ts:22](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L22)*
@@ -24,9 +24,9 @@
**child**: *[FiberNode](../modules/_mocked_types_index_.md#fibernode) | null*
*Defined in [mocked-types/index.ts:38](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L38)*
*Defined in [mocked-types/index.ts:38](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L38)*
*Defined in [mocked-types/index.ts:48](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L48)*
*Defined in [mocked-types/index.ts:48](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L48)*
___
@@ -34,9 +34,9 @@ ___
**elementType**: *keyof IntrinsicElements*
*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:41](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L41)*
*Defined in [mocked-types/index.ts:51](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L51)*
*Defined in [mocked-types/index.ts:51](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L51)*
___
@@ -44,9 +44,9 @@ ___
**sibling**: *[FiberNode](../modules/_mocked_types_index_.md#fibernode) | null*
*Defined in [mocked-types/index.ts:39](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L39)*
*Defined in [mocked-types/index.ts:39](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L39)*
*Defined in [mocked-types/index.ts:49](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L49)*
*Defined in [mocked-types/index.ts:49](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L49)*
___
@@ -54,9 +54,9 @@ ___
**stateNode**: *`HTMLElement`*
*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:44](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L44)*
*Defined in [mocked-types/index.ts:54](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L54)*
*Defined in [mocked-types/index.ts:54](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L54)*
___
@@ -64,6 +64,6 @@ ___
**type**: *keyof IntrinsicElements*
*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:42](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L42)*
*Defined in [mocked-types/index.ts:52](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L52)*
*Defined in [mocked-types/index.ts:52](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L52)*
@@ -24,7 +24,7 @@
**child**: *null*
*Defined in [mocked-types/index.ts:58](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L58)*
*Defined in [mocked-types/index.ts:58](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L58)*
___
@@ -32,7 +32,7 @@ ___
**elementType**: *null*
*Defined in [mocked-types/index.ts:61](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L61)*
*Defined in [mocked-types/index.ts:61](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L61)*
___
@@ -40,7 +40,7 @@ ___
**sibling**: *[FiberNode](../modules/_mocked_types_index_.md#fibernode) | null*
*Defined in [mocked-types/index.ts:59](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L59)*
*Defined in [mocked-types/index.ts:59](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L59)*
___
@@ -48,7 +48,7 @@ ___
**stateNode**: *`Text`*
*Defined in [mocked-types/index.ts:64](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L64)*
*Defined in [mocked-types/index.ts:64](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L64)*
___
@@ -56,4 +56,4 @@ ___
**type**: *null*
*Defined in [mocked-types/index.ts:62](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L62)*
*Defined in [mocked-types/index.ts:62](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L62)*
@@ -1,41 +0,0 @@
> **[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)*
+6 -92
View File
@@ -8,53 +8,17 @@
### Functions
* [findAllNodesByComponentName](_findnode_.md#findallnodesbycomponentname)
* [findNodeByComponent](_findnode_.md#findnodebycomponent)
* [findNodeByComponentName](_findnode_.md#findnodebycomponentname)
* [findNodeByComponentRef](_findnode_.md#findnodebycomponentref)
* [findNodesByComponentName](_findnode_.md#findnodesbycomponentname)
## Functions
### findAllNodesByComponentName
**findAllNodesByComponentName**(`node`: [FiberNode](_mocked_types_index_.md#fibernode) | null, `expectedName`: string, `traverseConfig?`: [TTraverseConfig](../interfaces/_traverse_.ttraverseconfig.md)): *`Array<FiberNode>`*
*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 |
`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*
**findNodeByComponent**(`node`: [FiberNode](_mocked_types_index_.md#fibernode) | null, `expectedClassOrFunction`: `React.ComponentType`): *[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.
*Defined in [findNode.ts:32](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/findNode.ts#L32)*
**Parameters:**
@@ -62,7 +26,6 @@ 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*
@@ -70,24 +33,9 @@ ___
### 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*
**findNodeByComponentName**(`node`: [FiberNode](_mocked_types_index_.md#fibernode) | null, `expectedName`: string): *[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.
*Defined in [findNode.ts:4](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/findNode.ts#L4)*
**Parameters:**
@@ -95,7 +43,6 @@ 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*
@@ -103,23 +50,9 @@ ___
### findNodeByComponentRef
**findNodeByComponentRef**(`node`: [FiberNode](_mocked_types_index_.md#fibernode) | null, `expectedClassInstance`: `Component`, `traverseConfig?`: [TTraverseConfig](../interfaces/_traverse_.ttraverseconfig.md)): *[FiberNode](_mocked_types_index_.md#fibernode) | null*
**findNodeByComponentRef**(`node`: [FiberNode](_mocked_types_index_.md#fibernode) | null, `expectedClassInstance`: `Component`): *[FiberNode](_mocked_types_index_.md#fibernode) | null*
*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).
*Defined in [findNode.ts:63](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/findNode.ts#L63)*
**Parameters:**
@@ -127,24 +60,5 @@ Name | Type |
------ | ------ |
`node` | [FiberNode](_mocked_types_index_.md#fibernode) \| null |
`expectedClassInstance` | `Component` |
`traverseConfig?` | [TTraverseConfig](../interfaces/_traverse_.ttraverseconfig.md) |
**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>`*
-64
View File
@@ -1,64 +0,0 @@
> **[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>`*
+2 -2
View File
@@ -25,7 +25,7 @@
Ƭ **FiberNode**: *[FiberNodeForComponentClass](../interfaces/_mocked_types_index_.fibernodeforcomponentclass.md) | [FiberNodeForFunctionComponent](../interfaces/_mocked_types_index_.fibernodeforfunctioncomponent.md) | [FiberNodeForInstrinsicElement](../interfaces/_mocked_types_index_.fibernodeforinstrinsicelement.md) | [FiberNodeForTextNode](../interfaces/_mocked_types_index_.fibernodefortextnode.md)*
*Defined in [mocked-types/index.ts:11](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L11)*
*Defined in [mocked-types/index.ts:11](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L11)*
___
@@ -33,4 +33,4 @@ ___
Ƭ **FiberNodeisHTMLLike**: *[FiberNodeForInstrinsicElement](../interfaces/_mocked_types_index_.fibernodeforinstrinsicelement.md) | [FiberNodeForTextNode](../interfaces/_mocked_types_index_.fibernodefortextnode.md)*
*Defined in [mocked-types/index.ts:67](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/mocked-types/index.ts#L67)*
*Defined in [mocked-types/index.ts:67](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/mocked-types/index.ts#L67)*
+3 -80
View File
@@ -6,10 +6,6 @@
## Index
### Interfaces
* [TTraverseConfig](../interfaces/_traverse_.ttraverseconfig.md)
### Functions
* [traverse](_traverse_.md#traverse)
@@ -19,21 +15,9 @@
### traverse
**traverse**(`node`: [FiberNode](_mocked_types_index_.md#fibernode), `fn`: function, `traverseConfig?`: [TTraverseConfig](../interfaces/_traverse_.ttraverseconfig.md)): *void*
**traverse**(`node`: [FiberNode](_mocked_types_index_.md#fibernode), `fn`: function): *void*
*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);
```
*Defined in [traverse.ts:4](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/traverse.ts#L4)*
**Parameters:**
@@ -49,8 +33,6 @@ Name | Type |
------ | ------ |
`node` | [FiberNode](_mocked_types_index_.md#fibernode) |
`Optional` **traverseConfig**: *[TTraverseConfig](../interfaces/_traverse_.ttraverseconfig.md)*
**Returns:** *void*
___
@@ -59,64 +41,7 @@ ___
**traverseGenerator**(`node`: [FiberNode](_mocked_types_index_.md#fibernode), `__namedParameters`: object): *`IterableIterator<FiberNode>`*
*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());
```
-----
*Defined in [traverse.ts:15](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/traverse.ts#L15)*
**Parameters:**
@@ -127,7 +52,5 @@ nodeIterator.throw(new Error());
Name | Type | Default |
------ | ------ | ------ |
`order` | "self" \| "child" \| "sibling"[] | ["self", "child", "sibling"] |
`skipSelfForStartNode` | boolean | false |
`skipSiblingForStartNode` | boolean | true |
**Returns:** *`IterableIterator<FiberNode>`*
+9 -9
View File
@@ -24,7 +24,7 @@
**doesElementContainRootFiberNode**(`element`: `Element`): *boolean*
*Defined in [utils.ts:65](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/utils.ts#L65)*
*Defined in [utils.ts:65](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/utils.ts#L65)*
**Parameters:**
@@ -40,7 +40,7 @@ ___
**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)*
*Defined in [utils.ts:82](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/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.
@@ -59,7 +59,7 @@ ___
**isConstructorComponentClass**(`ctr`: `React.ElementType` | null): *boolean*
*Defined in [utils.ts:42](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/utils.ts#L42)*
*Defined in [utils.ts:42](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/utils.ts#L42)*
**Parameters:**
@@ -75,7 +75,7 @@ ___
**isConstructorFunctionComponent**(`ctr`: `React.ElementType` | null): *boolean*
*Defined in [utils.ts:59](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/utils.ts#L59)*
*Defined in [utils.ts:59](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/utils.ts#L59)*
**Parameters:**
@@ -91,7 +91,7 @@ ___
**isConstructorHtmlLike**(`ctr`: `React.ElementType` | null): *boolean*
*Defined in [utils.ts:33](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/utils.ts#L33)*
*Defined in [utils.ts:33](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/utils.ts#L33)*
**Parameters:**
@@ -107,7 +107,7 @@ ___
**isNodeComponentClass**(`node`: [FiberNode](_mocked_types_index_.md#fibernode)): *boolean*
*Defined in [utils.ts:27](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/utils.ts#L27)*
*Defined in [utils.ts:27](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/utils.ts#L27)*
**Parameters:**
@@ -123,7 +123,7 @@ ___
**isNodeFunctionComponent**(`node`: [FiberNode](_mocked_types_index_.md#fibernode)): *boolean*
*Defined in [utils.ts:21](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/utils.ts#L21)*
*Defined in [utils.ts:21](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/utils.ts#L21)*
**Parameters:**
@@ -139,7 +139,7 @@ ___
**isNodeHtmlLike**(`node`: [FiberNode](_mocked_types_index_.md#fibernode)): *boolean*
*Defined in [utils.ts:11](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/utils.ts#L11)*
*Defined in [utils.ts:11](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/utils.ts#L11)*
**Parameters:**
@@ -155,7 +155,7 @@ ___
**isNodeNotHtmlLike**(`node`: [FiberNode](_mocked_types_index_.md#fibernode)): *boolean*
*Defined in [utils.ts:15](https://github.com/bendtherules/react-fiber-traverse/blob/c92c64b/src/utils.ts#L15)*
*Defined in [utils.ts:15](https://github.com/bendtherules/react-fiber-traverse/blob/18ea2e7/src/utils.ts#L15)*
**Parameters:**
+11 -18
View File
@@ -1,6 +1,6 @@
{
"name": "react-fiber-traverse",
"version": "0.0.8",
"version": "0.0.7",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -3775,20 +3775,13 @@
"css-what": "2.1",
"domutils": "1.5.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": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-3.2.0.tgz",
"integrity": "sha512-lukqnlbswsPmDZ5+ViDBCcrk+1fyPBA+ZoHSAQhRuEeXBKUb3Lj2kcTwMqoiFrJAnEeO9u3Oc8X617SUm3apYQ=="
"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
},
"cssom": {
"version": "0.3.8",
@@ -6014,9 +6007,9 @@
}
},
"handlebars": {
"version": "4.5.3",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz",
"integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==",
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz",
"integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==",
"dev": true,
"requires": {
"neo-async": "^2.6.0",
@@ -6293,9 +6286,9 @@
"dev": true
},
"https-proxy-agent": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz",
"integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==",
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz",
"integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==",
"dev": true,
"requires": {
"agent-base": "^4.3.0",
+2 -3
View File
@@ -1,6 +1,6 @@
{
"name": "react-fiber-traverse",
"version": "0.0.8",
"version": "0.0.7",
"description": "Traverse and other utils on top of React fiber tree",
"main": "dist/index.js",
"module": "dist/react-fiber-traverse.esm.js",
@@ -37,7 +37,7 @@
"test:src:watch": "npm run test:src -- --watch",
"test:umd": "jest --config ./scripts/jest/config.umd.js",
"test:umdprod": "jest --config ./scripts/jest/config.umdprod.js",
"test:src:debug": "node --inspect ./node_modules/jest/bin/jest.js --runInBand --config ./scripts/jest/config.src.js",
"test:src:debug": "node --inspect ./node_modules/jest/bin/jest.js --config ./scripts/jest/config.src.js",
"version": "run-s test authors docs && git add ."
},
"husky": {
@@ -66,7 +66,6 @@
},
"dependencies": {
"@babel/runtime": "^7.5.4",
"css-what": "^3.2.0",
"prop-types": "^15.7.2"
},
"devDependencies": {
+52 -108
View File
@@ -1,150 +1,94 @@
import { FiberNode } from "./mocked-types";
import { traverseGenerator, TTraverseConfig } from "./traverse";
import { isNodeNotHtmlLike } from "./utils";
/**
* Find node by component name, till first match.
*
* Matches against class and function name, doesn't match html-like nodes.
* Returns null if no match is found.
*
* @example
* ```js
* // returns FiberNode for first usage of 'AccordionMenu'
* findNodeByComponentName(startNode, "AccordionMenu");
* ```
*
* @note Highest chance of collision, least data access needed.
* Different components with same name will collide.
* Needs access to component name.
*
*/
function findNodeByComponentName(
node: FiberNode | null,
expectedName: string,
traverseConfig?: TTraverseConfig
expectedName: string
): FiberNode | null {
if (node === null) {
return null;
}
const nodeIterator = traverseGenerator(node, traverseConfig);
for (const tmpNode of nodeIterator) {
if (isNodeNotHtmlLike(tmpNode) && tmpNode.type.name === expectedName) {
return tmpNode;
if (isNodeNotHtmlLike(node) && node.type.name === expectedName) {
return node;
}
{
const returnVal = findNodeByComponentName(node.child, expectedName);
if (returnVal !== null) {
return returnVal;
}
}
{
const returnVal = findNodeByComponentName(node.sibling, expectedName);
if (returnVal !== null) {
return returnVal;
}
}
return null;
}
function* findNodesByComponentName(
node: FiberNode | null,
expectedName: string,
traverseConfig?: TTraverseConfig
): IterableIterator<FiberNode> {
if (node === null) {
return null;
}
const nodeIterator = traverseGenerator(node, traverseConfig);
for (const tmpNode of nodeIterator) {
if (isNodeNotHtmlLike(tmpNode) && tmpNode.type.name === expectedName) {
yield tmpNode;
}
}
}
function findAllNodesByComponentName(
node: FiberNode | null,
expectedName: string,
traverseConfig?: TTraverseConfig
): Array<FiberNode> {
return [...findNodesByComponentName(node, expectedName, traverseConfig)];
}
/**
* Find node by component (i.e. class or function by reference), till first match.
*
* Matches against class and function by reference.
* Returns null if no match is found.
*
* @example
* ```js
* // returns FiberNode for first usage of AccordionMenu
* findNodeByComponent(startNode, AccordionMenu);
* ```
*
* @note Medium chance of collision, medium data access needed.
* This is safer than findNodeByComponentName, as different components with the same name won't collide.
* But, two instances of the same component will still collide.
* Needs access to component class or function.
*
*/
function findNodeByComponent(
node: FiberNode | null,
expectedClassOrFunction: React.ComponentType,
traverseConfig?: TTraverseConfig
expectedClassOrFunction: React.ComponentType
): FiberNode | null {
if (node === null) {
return null;
}
const nodeIterator = traverseGenerator(node, traverseConfig);
for (const tmpNode of nodeIterator) {
if (
isNodeNotHtmlLike(tmpNode) &&
tmpNode.type === expectedClassOrFunction
) {
return tmpNode;
if (isNodeNotHtmlLike(node) && node.type === expectedClassOrFunction) {
return node;
}
{
const returnVal = findNodeByComponent(node.child, expectedClassOrFunction);
if (returnVal !== null) {
return returnVal;
}
}
{
const returnVal = findNodeByComponent(
node.sibling,
expectedClassOrFunction
);
if (returnVal !== null) {
return returnVal;
}
}
return null;
}
/**
* Find node by component instance ref, till first match.
*
* Matches against class instances by reference.
* Returns null if no match is found.
*
* @example
* ```js
* // menuRef=createRef(); <AccordionMenu ref={menuRef}>
* findNodeByComponentRef(startNode, menuRef.current);
* ```
*
* @note Least chance of collision, maximum data access needed.
* Needs access to component instance (through React ref usually).
*
*/
function findNodeByComponentRef(
node: FiberNode | null,
expectedClassInstance: React.Component,
traverseConfig?: TTraverseConfig
expectedClassInstance: React.Component
): FiberNode | null {
if (node === null) {
return null;
}
const nodeIterator = traverseGenerator(node, traverseConfig);
for (const tmpNode of nodeIterator) {
if (
isNodeNotHtmlLike(tmpNode) &&
tmpNode.stateNode === expectedClassInstance
) {
return tmpNode;
if (isNodeNotHtmlLike(node) && node.stateNode === expectedClassInstance) {
return node;
}
{
const returnVal = findNodeByComponentRef(node.child, expectedClassInstance);
if (returnVal !== null) {
return returnVal;
}
}
{
const returnVal = findNodeByComponentRef(
node.sibling,
expectedClassInstance
);
if (returnVal !== null) {
return returnVal;
}
}
return null;
}
export {
findNodeByComponentName,
findNodesByComponentName,
findAllNodesByComponentName,
findNodeByComponent,
findNodeByComponentRef
};
export { findNodeByComponentName, findNodeByComponent, findNodeByComponentRef };
-4
View File
@@ -4,7 +4,6 @@ import {
findNodeByComponentRef,
findNodeByComponentName
} from "./findNode";
import { matchGenerator, matchAll, matchFirst } from "./match";
import * as Utils from "./utils";
export {
@@ -13,8 +12,5 @@ export {
findNodeByComponent,
findNodeByComponentRef,
findNodeByComponentName,
matchGenerator,
matchAll,
matchFirst,
Utils
};
-141
View File
@@ -1,141 +0,0 @@
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 };
+10
View File
@@ -44,6 +44,16 @@ export interface FiberNodeForInstrinsicElement {
stateNode: HTMLElement;
}
export interface FiberNodeForInstrinsicElement {
child: FiberNode | null;
sibling: FiberNode | null;
elementType: keyof JSX.IntrinsicElements;
type: keyof JSX.IntrinsicElements;
stateNode: HTMLElement;
}
export interface FiberNodeForTextNode {
child: null;
sibling: FiberNode | null;
+20 -112
View File
@@ -1,114 +1,47 @@
// import { isNodeSimple } from './utils';
import { FiberNode } from "./mocked-types";
interface TTraverseConfig {
order?: Array<"self" | "child" | "sibling">;
skipSiblingForStartNode?: boolean;
skipSelfForStartNode?: boolean;
function traverse(node: FiberNode, fn: (node: FiberNode) => any) {
fn.call(null, node);
if (node.child !== null) {
traverse(node.child, fn);
}
if (node.sibling !== null) {
traverse(node.sibling, fn);
}
}
/**
* Traverse nodes recursively using generators.
*
* This is the advanced traverse function, which can be used used
* to write other variants of traversal and find.
*
* Type signature for generator.next first argument is `{ skipChild?: boolean; skipSibling?: boolean } | void `
* Throw any error into the generator to finish the generator and let it cleanup its internals.
*
* It allows inversion of control -
* so, application code can decide to
* 1. change order of traversal,
* 2. skip some elements,
* 3. cancel traversal mid-way.
*
* @example
* ```js
* // Basic use (for-of)
*
* const nodeIterator = traverseGenerator(rootNode);
* for (const node of nodeIterator) {
* // do something with each node here
* }
* ```
* ------
*
* @example
* ```js
* // Breadth-first
*
* // note the order below
* const nodeIterator = traverseGenerator(rootNode, ["self", "sibling", "child"]);
* // rest - same as above
* ```
* -----
*
* @example
* ```js
* // Get first 3 nodes and then stop the generator
*
* const nodeIterator = traverseGenerator(rootNode);
*
* var count = 0;
* var next;
* while (
* count < 3 &&
* !(next = nodeIterator.next()).done
* ) {
* count++;
* const node = next.value;
* // do something with each node here
* }
*
* // Finish generator, to prevent memory leak
* nodeIterator.throw(new Error());
* ```
* -----
*
*/
function* traverseGenerator(
node: FiberNode,
{
order = ["self", "child", "sibling"],
skipSiblingForStartNode = true,
skipSelfForStartNode = false
}: TTraverseConfig = {}
order = ["self", "child", "sibling"]
}: { order?: Array<"self" | "child" | "sibling"> } = {}
): IterableIterator<FiberNode> {
let skipChild = false,
skipSibling = skipSiblingForStartNode,
skipSelf = skipSelfForStartNode;
skipSibling = false;
function* traverseSelf() {
if (!skipSelf) {
const controlInput:
| { skipChild?: boolean; skipSibling?: boolean }
| undefined = yield node;
const controlInput:
| { skipChild: boolean; skipSibling: boolean }
| undefined = yield node;
if (controlInput !== undefined) {
({ skipChild = skipChild, skipSibling = skipSibling } = controlInput);
}
if (controlInput !== undefined) {
({ skipChild = skipChild, skipSibling = skipSibling } = controlInput);
}
}
function* traverseChild() {
if (!skipChild && node.child !== null) {
const nextNode = node.child;
yield* traverseGenerator(nextNode, {
order,
skipSiblingForStartNode: false,
skipSelfForStartNode: false
});
yield* traverseGenerator(nextNode, { order });
}
}
function* traverseSibling() {
if (!skipSibling && node.sibling !== null) {
const nextNode = node.sibling;
yield* traverseGenerator(nextNode, {
order,
skipSiblingForStartNode: false,
skipSelfForStartNode: false
});
yield* traverseGenerator(nextNode, { order });
}
}
@@ -129,29 +62,4 @@ function* 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 };
export { traverse, traverseGenerator };
+1 -1
View File
@@ -89,7 +89,7 @@ function getRootFiberNodeFromDOM(startElement?: Element): FiberNode | null {
}
let returnFiberNode = null;
for (const childNode of [].slice.call(startElement.children)) {
for (const childNode of startElement.children) {
returnFiberNode = getRootFiberNodeFromDOM(childNode);
if (returnFiberNode !== null) {
return returnFiberNode;
-139
View File
@@ -1,139 +0,0 @@
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);
});
});
});
+1 -2
View File
@@ -17,8 +17,7 @@
"removeComments": true,
"sourceMap": true,
"strict": true,
"target": "es5",
"downlevelIteration": true
"target": "es6"
},
"exclude": ["node_modules", "dist"],
"include": ["src"]