12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- import propName from './propName';
- const DEFAULT_OPTIONS = {
- ignoreCase: true,
- };
- /**
- * Returns the JSXAttribute itself or undefined, indicating the prop
- * is not present on the JSXOpeningElement.
- *
- */
- export default function getProp(props = [], prop = '', options = DEFAULT_OPTIONS) {
- function getName(name) { return options.ignoreCase ? name.toUpperCase() : name; }
- const propToFind = getName(prop);
- function isPropToFind(property) {
- return property.type === 'Property'
- && property.key.type === 'Identifier'
- && propToFind === getName(property.key.name);
- }
- const foundAttribute = props.find((attribute) => {
- // If the props contain a spread prop, try to find the property in the object expression.
- if (attribute.type === 'JSXSpreadAttribute') {
- return attribute.argument.type === 'ObjectExpression'
- && propToFind !== getName('key') // https://github.com/reactjs/rfcs/pull/107
- && attribute.argument.properties.some(isPropToFind);
- }
- return propToFind === getName(propName(attribute));
- });
- if (foundAttribute && foundAttribute.type === 'JSXSpreadAttribute') {
- return propertyToJSXAttribute(foundAttribute.argument.properties.find(isPropToFind));
- }
- return foundAttribute;
- }
- function propertyToJSXAttribute(node) {
- const { key, value } = node;
- return {
- type: 'JSXAttribute',
- name: { type: 'JSXIdentifier', name: key.name, ...getBaseProps(key) },
- value: value.type === 'Literal'
- ? adjustRangeOfNode(value)
- : { type: 'JSXExpressionContainer', expression: adjustExpressionRange(value), ...getBaseProps(value) },
- ...getBaseProps(node),
- };
- }
- function adjustRangeOfNode(node) {
- const [start, end] = node.range || [node.start, node.end];
- return {
- ...node,
- end: undefined,
- range: [start, end],
- start: undefined,
- };
- }
- function adjustExpressionRange({ expressions, quasis, ...expression }) {
- return {
- ...adjustRangeOfNode(expression),
- ...(expressions ? { expressions: expressions.map(adjustRangeOfNode) } : {}),
- ...(quasis ? { quasis: quasis.map(adjustRangeOfNode) } : {}),
- };
- }
- function getBaseProps({ loc, ...node }) {
- const { range } = adjustRangeOfNode(node);
- return {
- loc: getBaseLocation(loc),
- range,
- };
- }
- function getBaseLocation({
- start,
- end,
- source,
- filename,
- }) {
- return {
- start,
- end,
- ...(source !== undefined ? { source } : {}),
- ...(filename !== undefined ? { filename } : {}),
- };
- }
|