_intersectAndDispatch (callbackName, mouseEvent) { const event = SyntheticMouseEvent.getPooled(null, null, mouseEvent, mouseEvent.target) const intersections = this._getIntersections( tempVector2.set(event.clientX, event.clientY)) ReactUpdates.batchedUpdates(() => { for (let i = 0; i < intersections.length; ++i) { const intersection = intersections[i] if (event.isDefaultPrevented() || event.isPropagationStopped()) { return } const object = intersection.object this.dispatchEvent(object, callbackName, event, intersection) } }) return { event, intersections, } }
/** * @see ReactMount._renderNewRootComponent * * Cloned because it uses * @see React3Renderer.instantiateReactComponent * * @param nextElement * @param {THREE.Object3D | HTMLCanvasElement} container * @param shouldReuseMarkup * @param context * @returns {*} * @private */ _renderNewRootComponent(nextElement, container, shouldReuseMarkup, context) { // Various parts of our code (such as ReactCompositeComponent's // _renderValidatedComponent) assume that calls to render aren't nested; // verify that that's the case. if (process.env.NODE_ENV !== 'production') { warning(ReactCurrentOwner.current === null, '_renderNewRootComponent(): Render methods should be a pure function ' + 'of props and state; triggering nested component updates from ' + 'render is not allowed. If necessary, trigger nested updates in ' + 'componentDidUpdate. Check the render method of %s.', (ReactCurrentOwner.current && ReactCurrentOwner.current.getName()) || 'ReactCompositeComponent'); } const componentInstance = this.instantiateReactComponent(nextElement, false); if (!ReactUpdates.ReactReconcileTransaction) { // If the ReactReconcileTransaction has not been injected // let's just use the defaults from ReactMount. ReactInjection.Updates.injectReconcileTransaction(ReactReconcileTransaction); ReactInjection.Updates.injectBatchingStrategy(ReactDefaultBatchingStrategy); } let devToolRemoved; if (process.env.NODE_ENV !== 'production') { devToolRemoved = removeDevTool(); } // The initial render is synchronous but any updates that happen during // rendering, in componentWillMount or componentDidMount, will be batched // according to the current batching strategy. ReactUpdates.batchedUpdates( this.batchedMountComponentIntoNode, componentInstance, container, shouldReuseMarkup, context ); if (process.env.NODE_ENV !== 'production') { if (devToolRemoved) { removeDevTool.restore(); } } const wrapperID = componentInstance._instance.rootID; this._instancesByReactRootID[wrapperID] = componentInstance; return componentInstance; }
_onMouseDown = (callbackName, mouseEvent) => { ReactUpdates.batchedUpdates(() => { const { event, intersections, } = this._intersectAndDispatch(callbackName, mouseEvent) if (event.isDefaultPrevented() || event.isPropagationStopped()) { this._intersectionsForClick = null } else { this._intersectionsForClick = intersections } }) }
_onMouseUp = (callbackName, mouseEvent) => { ReactUpdates.batchedUpdates(() => { const { event, intersections, } = this._intersectAndDispatch(callbackName, mouseEvent) if (!(event.isDefaultPrevented() || event.isPropagationStopped())) { if (this._intersectionsForClick === null) { return } // intersect current intersections with the intersections for click // call xzibit ASAP we have a good one son // it wasn't that good const intersectionUUIDMap = this._intersectionsForClick.reduce( (map, intersection) => { map[intersection.object.uuid] = intersection return map }, {}) for (let i = 0; i < intersections.length; ++i) { if (event.isDefaultPrevented() || event.isPropagationStopped()) { return } const intersection = intersections[i] const object = intersection.object const uuid = object.uuid if (intersectionUUIDMap[uuid]) { // oh boy oh boy here we go, we got a clicker this.dispatchEvent(object, 'onClick', this._createSyntheticMouseEvent('click', event), intersection) } } } }) this._intersectionsForClick = null }
unmountComponentAtNode(container) { // Various parts of our code (such as ReactCompositeComponent's // _renderValidatedComponent) assume that calls to render aren't nested; // verify that that's the case. (Strictly speaking, unmounting won't cause a // render but we still don't expect to be in a render call here.) if (process.env.NODE_ENV !== 'production') { warning( ReactCurrentOwner.current === null, 'unmountComponentAtNode(): Render methods should be a pure function ' + 'of props and state; triggering nested component updates from render ' + 'is not allowed. If necessary, trigger nested updates in ' + 'componentDidUpdate. Check the render method of %s.', (ReactCurrentOwner.current && ReactCurrentOwner.current.getName()) || 'ReactCompositeComponent' ); } const prevComponent = this.getTopLevelWrapperInContainer(container); if (!prevComponent) { // Check if the node being unmounted was rendered by React, but isn't a // root node. const containerHasNonRootReactChild = this.hasNonRootReactChild(container); // Check if the container itself is a React root node. const isContainerReactRoot = !!( container && container.userData && container.userData.markup && container.userData.markup[ID_PROPERTY_NAME] ); if (process.env.NODE_ENV !== 'production') { warning( !containerHasNonRootReactChild, 'unmountComponentAtNode(): The node you\'re attempting to unmount ' + 'was rendered by React and is not a top-level container. %s', ( isContainerReactRoot ? 'You may have accidentally passed in a React root node instead ' + 'of its container.' : 'Instead, have the parent component update its state and ' + 'rerender in order to remove this component.' ) ); } return false; } delete this._instancesByReactRootID[prevComponent._instance.rootID]; ReactUpdates.batchedUpdates( unmountComponentFromNode, prevComponent, container, false ); if (container && container.userData && container.userData._createdByReact3) { delete container.userData; } return true; }