transforms/findDOMNode.js (125 lines of code) (raw):

/** * Copyright 2015-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * */ 'use strict'; function getDOMNodeToFindDOMNode(file, api, options) { const j = api.jscodeshift; require('./utils/array-polyfills'); const ReactUtils = require('./utils/ReactUtils')(j); const printOptions = options.printOptions || { quote: 'single', trailingComma: true }; const root = j(file.source); const createReactFindDOMNodeCall = arg => j.callExpression( j.memberExpression( j.identifier('React'), j.identifier('findDOMNode'), false ), [arg] ); const updateRefCall = (path, refName) => { j(path) .find(j.CallExpression, { callee: { object: { type: 'Identifier', name: refName }, property: { type: 'Identifier', name: 'getDOMNode' } } }) .forEach(callPath => j(callPath).replaceWith( createReactFindDOMNodeCall(j.identifier(refName)) ) ); }; const updateToFindDOMNode = classPath => { var sum = 0; // this.getDOMNode() sum += j(classPath) .find(j.CallExpression, { callee: { object: { type: 'ThisExpression' }, property: { type: 'Identifier', name: 'getDOMNode' } } }) .forEach(path => j(path).replaceWith(createReactFindDOMNodeCall(j.thisExpression())) ) .size(); // this.refs.xxx.getDOMNode() or this.refs.xxx.refs.yyy.getDOMNode() sum += j(classPath) .find(j.MemberExpression, { object: { type: 'MemberExpression', object: { type: 'MemberExpression', object: { type: 'ThisExpression' }, property: { type: 'Identifier', name: 'refs' } } } }) .closest(j.CallExpression) .filter( path => path.value.callee.property && path.value.callee.property.type === 'Identifier' && path.value.callee.property.name === 'getDOMNode' ) .forEach(path => j(path).replaceWith( createReactFindDOMNodeCall(path.value.callee.object) ) ) .size(); // someVariable.getDOMNode() wherre `someVariable = this.refs.xxx` sum += j(classPath) .findVariableDeclarators() .filter(path => { const init = path.value.init; const value = init && init.object; return ( value && value.type === 'MemberExpression' && value.object && value.object.type === 'ThisExpression' && value.property && value.property.type === 'Identifier' && value.property.name === 'refs' && init.property && init.property.type === 'Identifier' ); }) .forEach(path => j(path) .closest(j.FunctionExpression) .forEach(fnPath => updateRefCall(fnPath, path.value.id.name)) ) .size(); return sum > 0; }; if (options['explicit-require'] === false || ReactUtils.hasReact(root)) { const apply = path => path.filter(updateToFindDOMNode); const didTransform = apply(ReactUtils.findReactCreateClass(root)).size() + apply(ReactUtils.findReactCreateClassModuleExports(root)).size() + apply(ReactUtils.findReactCreateClassExportDefault(root)).size() > 0; if (didTransform) { return root.toSource(printOptions); } } return null; } module.exports = getDOMNodeToFindDOMNode;