UNPKG

6.1 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
8
9exports.propsOfNode = propsOfNode;
10exports.childrenOfNode = childrenOfNode;
11exports.hasClassName = hasClassName;
12exports.treeForEach = treeForEach;
13exports.treeFilter = treeFilter;
14exports.findParentNode = findParentNode;
15exports.pathToNode = pathToNode;
16exports.parentsOfNode = parentsOfNode;
17exports.nodeHasId = nodeHasId;
18exports.nodeMatchesObjectProps = nodeMatchesObjectProps;
19exports.getTextFromNode = getTextFromNode;
20
21var _object = require('object.assign');
22
23var _object2 = _interopRequireDefault(_object);
24
25var _arrayPrototype = require('array.prototype.flat');
26
27var _arrayPrototype2 = _interopRequireDefault(_arrayPrototype);
28
29var _object3 = require('object.entries');
30
31var _object4 = _interopRequireDefault(_object3);
32
33var _isSubset = require('is-subset');
34
35var _isSubset2 = _interopRequireDefault(_isSubset);
36
37var _functionPrototype = require('function.prototype.name');
38
39var _functionPrototype2 = _interopRequireDefault(_functionPrototype);
40
41var _getAdapter = require('./getAdapter');
42
43var _getAdapter2 = _interopRequireDefault(_getAdapter);
44
45function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
46
47function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
48
49function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
50
51function propsOfNode(node) {
52 return node && node.props || {};
53}
54
55function childrenOfNode(node) {
56 if (!node) return [];
57
58 var adapter = (0, _getAdapter2['default'])();
59 var adapterHasIsFragment = adapter.isFragment && typeof adapter.isFragment === 'function';
60
61 var renderedArray = Array.isArray(node.rendered) ? (0, _arrayPrototype2['default'])(node.rendered, 1) : [node.rendered];
62
63 // React adapters before 16 will not have isFragment
64 if (!adapterHasIsFragment) {
65 return renderedArray;
66 }
67
68 return (0, _arrayPrototype2['default'])(renderedArray.map(function (currentChild) {
69 // If the node is a Fragment, we want to return its children, not the fragment itself
70 if (adapter.isFragment(currentChild)) {
71 return childrenOfNode(currentChild);
72 }
73
74 return currentChild;
75 }), 1);
76}
77
78function hasClassName(node, className) {
79 var classes = propsOfNode(node).className || '';
80 classes = String(classes).replace(/\s/g, ' ');
81 return (' ' + String(classes) + ' ').indexOf(' ' + String(className) + ' ') > -1;
82}
83
84function treeForEach(tree, fn) {
85 if (tree !== null && tree !== false && typeof tree !== 'undefined') {
86 fn(tree);
87 }
88 childrenOfNode(tree).forEach(function (node) {
89 return treeForEach(node, fn);
90 });
91}
92
93function treeFilter(tree, fn) {
94 var results = [];
95 treeForEach(tree, function (node) {
96 if (fn(node)) {
97 results.push(node);
98 }
99 });
100 return results;
101}
102
103/**
104 * To support sibling selectors we need to be able to find
105 * the siblings of a node. The easiest way to do that is find
106 * the parent of the node and access its children.
107 *
108 * This would be unneeded if the RST spec included sibling pointers
109 * such as node.nextSibling and node.prevSibling
110 * @param {*} root
111 * @param {*} targetNode
112 */
113function findParentNode(root, targetNode) {
114 var results = treeFilter(root, function (node) {
115 if (!node.rendered) {
116 return false;
117 }
118
119 return childrenOfNode(node).indexOf(targetNode) !== -1;
120 });
121 return results[0] || null;
122}
123
124function pathFilter(path, fn) {
125 return path.filter(function (tree) {
126 return treeFilter(tree, fn).length !== 0;
127 });
128}
129
130function pathToNode(node, root) {
131 var queue = [root];
132 var path = [];
133
134 var hasNode = function hasNode(testNode) {
135 return node === testNode;
136 };
137
138 while (queue.length) {
139 var current = queue.pop();
140 var children = childrenOfNode(current);
141 if (current === node) return pathFilter(path, hasNode);
142
143 path.push(current);
144
145 if (children.length === 0) {
146 // leaf node. if it isn't the node we are looking for, we pop.
147 path.pop();
148 }
149 queue.push.apply(queue, _toConsumableArray(children));
150 }
151
152 return null;
153}
154
155function parentsOfNode(node, root) {
156 return pathToNode(node, root).reverse();
157}
158
159function nodeHasId(node, id) {
160 return propsOfNode(node).id === id;
161}
162
163var CAN_NEVER_MATCH = {};
164function replaceUndefined(v) {
165 return typeof v !== 'undefined' ? v : CAN_NEVER_MATCH;
166}
167function replaceUndefinedValues(obj) {
168 return (0, _object4['default'])(obj).reduce(function (acc, _ref) {
169 var _ref2 = _slicedToArray(_ref, 2),
170 k = _ref2[0],
171 v = _ref2[1];
172
173 return (0, _object2['default'])({}, acc, _defineProperty({}, k, replaceUndefined(v)));
174 }, {});
175}
176
177function nodeMatchesObjectProps(node, props) {
178 return (0, _isSubset2['default'])(propsOfNode(node), replaceUndefinedValues(props));
179}
180
181function getTextFromNode(node) {
182 if (node == null) {
183 return '';
184 }
185
186 if (typeof node === 'string' || typeof node === 'number') {
187 return String(node);
188 }
189
190 if (node.type && typeof node.type === 'function') {
191 return '<' + String(node.type.displayName || (0, _functionPrototype2['default'])(node.type)) + ' />';
192 }
193
194 return childrenOfNode(node).map(getTextFromNode).join('');
195}
\No newline at end of file