@fluentui/react-northstar
Version:
A themable React component library.
219 lines (215 loc) • 6.97 kB
JavaScript
import _createClass from "@babel/runtime/helpers/esm/createClass";
import { ForwardRef } from 'react-is';
import { getReactFiberFromNode } from '../../utils/getReactFiberFromNode';
var isDOMNode = function isDOMNode(e) {
return e && typeof e.tagName === 'string' && e.nodeType === Node.ELEMENT_NODE;
};
export var FiberNavigator = /*#__PURE__*/function () {
function FiberNavigator() {
this.__fiber = void 0;
} // TODO: Fibers can become stale.
// The only current fiber is the one found on the DOM node.
// There is no way to start at a React Component fiber, go the DOM node,
// get the current fiber, and find your way back to the React Component fiber.
// Probably need to remove fromFiber and re-implement using only DOM node weak map.
var _proto = FiberNavigator.prototype;
/**
* Hooks state is represented by a recursive structure where:
* - `memoizedState` is a current value if applicable
* - `next` is next hook in order
* @param node - fiber
*/
_proto.findDebugHookState = function findDebugHookState(node) {
if (node && node.memoizedState && node.memoizedState.current && node.memoizedState.current.fluentUIDebug) {
return node.memoizedState.current;
}
if (node === null || node.next === null) {
return null;
}
return this.findDebugHookState(node.next);
};
//
// Methods
//
_proto.isEqual = function isEqual(fiberNav) {
// TODO: do equality check on __fiber instead, however, see fromFiber TODO :/
return !!fiberNav && fiberNav.instance === this.instance;
};
_proto.find = function find(condition, move) {
var fiber = FiberNavigator.fromFiber(this.__fiber);
while (fiber) {
if (condition(fiber)) {
return fiber;
}
fiber = move(fiber);
}
return null;
};
_proto.findOwner = function findOwner(condition) {
return this.find(condition, function (fiber) {
return fiber.owner;
});
};
_proto.findParent = function findParent(condition) {
return this.find(condition, function (fiber) {
return fiber.parent;
});
}
//
// Component Types
//
;
_createClass(FiberNavigator, [{
key: "key",
get: function get() {
return this.__fiber.key;
}
}, {
key: "name",
get: function get() {
if (this.isClassComponent || this.isFunctionComponent) {
return this.__fiber.type.displayName || this.__fiber.type.name;
}
if (this.isForwardRef) {
var _this$__fiber$type$re, _this$__fiber$type$re2;
return this.__fiber.type.displayName || this.__fiber.type.name || ((_this$__fiber$type$re = this.__fiber.type.return) == null ? void 0 : _this$__fiber$type$re.displayName) || ((_this$__fiber$type$re2 = this.__fiber.type.return) == null ? void 0 : _this$__fiber$type$re2.name);
}
if (this.isHostComponent) {
return this.__fiber.stateNode.constructor.name;
}
return null;
}
}, {
key: "parent",
get: function get() {
return FiberNavigator.fromFiber(this.__fiber.return);
}
}, {
key: "owner",
get: function get() {
return FiberNavigator.fromFiber(this.__fiber._debugOwner);
}
}, {
key: "domNode",
get: function get() {
var fiber = this.__fiber;
do {
if (isDOMNode(fiber.stateNode)) {
return fiber.stateNode;
}
fiber = fiber.child;
} while (fiber);
return null;
}
}, {
key: "instance",
get: function get() {
if (this.isClassComponent) {
return this.__fiber.stateNode;
}
if (this.isFunctionComponent || this.isForwardRef) {
// assumes functional component w/useRef
return this.findDebugHookState(this.__fiber.memoizedState);
}
return null;
}
}, {
key: "props",
get: function get() {
return this.__fiber.memoizedProps;
}
}, {
key: "state",
get: function get() {
return this.__fiber.memoizedState;
}
}, {
key: "reactComponent",
get: function get() {
return this.isHostComponent ? this.owner.elementType : this.elementType;
}
}, {
key: "elementType",
get: function get() {
return this.__fiber.elementType;
}
}, {
key: "fluentUIDebug",
get: function get() {
return this.instance && this.instance.fluentUIDebug ? this.instance.fluentUIDebug : null;
}
}, {
key: "jsxString",
get: function get() {
return "<" + this.name + " />";
}
}, {
key: "isClassComponent",
get: function get() {
var _this$__fiber$type$pr;
// React.Component subclasses have this flag
// https://reactjs.org/docs/implementation-notes.html
return typeof this.__fiber.type === 'function' && !!((_this$__fiber$type$pr = this.__fiber.type.prototype) != null && _this$__fiber$type$pr.isReactComponent);
}
}, {
key: "isFunctionComponent",
get: function get() {
var _this$__fiber$type$pr2;
// React.Component subclasses have this flag
// https://reactjs.org/docs/implementation-notes.html
return typeof this.__fiber.type === 'function' && !((_this$__fiber$type$pr2 = this.__fiber.type.prototype) != null && _this$__fiber$type$pr2.isReactComponent);
}
}, {
key: "isForwardRef",
get: function get() {
var _this$__fiber$type;
return ((_this$__fiber$type = this.__fiber.type) == null ? void 0 : _this$__fiber$type.$$typeof) === ForwardRef;
}
}, {
key: "isHostComponent",
get: function get() {
// Host components are platform components (i.e. 'div' on web)
// https://github.com/acdlite/react-fiber-architecture#type-and-key
return typeof this.__fiber.type === 'string';
}
//
// What this fiber component renders
//
}, {
key: "isDOMComponent",
get: function get() {
return !!this.__fiber.child && FiberNavigator.fromFiber(this.__fiber.child).isHostComponent;
}
// https://github.com/facebook/react/blob/16.8.6/packages/react-dom/src/test-utils/ReactTestUtils.js#L193
}, {
key: "isCompositeComponent",
get: function get() {
return this.isDOMComponent ? false : !!this.instance && !!this.instance.render && !!this.instance.setState;
}
}]);
return FiberNavigator;
}();
FiberNavigator.fromFiber = function (fiber) {
if (!fiber) return null;
var fiberNavigator = new FiberNavigator();
Object.defineProperty(fiberNavigator, '__fiber', {
value: fiber,
enumerable: false,
writable: false,
configurable: false
});
return fiberNavigator;
};
FiberNavigator.fromDOMNode = function (domNode) {
var fiber = getReactFiberFromNode(domNode);
if (!fiber) return null;
var fiberNavigator = new FiberNavigator();
Object.defineProperty(fiberNavigator, '__fiber', {
value: fiber,
enumerable: false,
writable: false,
configurable: false
});
return fiberNavigator;
};
//# sourceMappingURL=FiberNavigator.js.map