@babel/types#JSXAttribute TypeScript Examples
The following examples show how to use
@babel/types#JSXAttribute.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: jsx.ts From react-optimized-image with MIT License | 6 votes |
getAttribute = (path: NodePath<JSXElement>, attributeName: string): NodePath<JSXAttribute> | undefined => {
if (path.node.openingElement.attributes) {
let attribue;
path.get('openingElement').traverse({
JSXAttribute(attributePath) {
if (attributePath.node.name.name === attributeName) {
attribue = attributePath;
attributePath.stop();
}
},
});
return attribue;
}
return undefined;
}
Example #2
Source File: traverse.ts From react-optimized-image with MIT License | 6 votes |
getRequireArguments = (
types: Babel['types'],
path: NodePath<JSXAttribute>,
): CallExpression['arguments'] | undefined => {
// check for inline-require statement
if (
path.node.value &&
path.node.value.type === 'JSXExpressionContainer' &&
path.node.value.expression.type === 'CallExpression' &&
path.node.value.expression.callee.type === 'Identifier' &&
path.node.value.expression.callee.name === 'require' &&
path.node.value.expression.arguments.length > 0
) {
return path.node.value.expression.arguments;
}
// check for import reference
if (
path.node.value &&
path.node.value.type === 'JSXExpressionContainer' &&
path.node.value.expression.type === 'Identifier'
) {
const variableName = path.node.value.expression.name;
const binding = path.scope.getBinding(variableName);
if (
binding &&
binding.kind === 'module' &&
isImport(binding.path) &&
binding.path.parent.type === 'ImportDeclaration'
) {
return [types.stringLiteral(binding.path.parent.source.value)];
}
}
}
Example #3
Source File: traverse.ts From react-optimized-image with MIT License | 6 votes |
getRelevantRequireString = (types: Babel['types'], path: NodePath<JSXAttribute>): string | undefined => {
const args = getRequireArguments(types, path);
if (args && args.length > 0) {
// stringle string
if (args[0].type === 'StringLiteral') {
return args[0].value;
}
// concatenated string
if (args[0].type === 'BinaryExpression' && args[0].right.type === 'StringLiteral') {
return args[0].right.value;
}
// template literal
if (args[0].type === 'TemplateLiteral' && args[0].quasis.length > 0) {
return args[0].quasis[args[0].quasis.length - 1].value.raw;
}
}
}
Example #4
Source File: index.ts From plasmic with MIT License | 6 votes |
getRawNamedAttrs = (jsxElement: JSXElement) => {
const attrs = new Map<string, JSXAttribute>();
for (const attr of jsxElement.openingElement.attributes) {
if (attr.type !== "JSXAttribute") {
continue;
}
assert(L.isString(attr.name.name));
attrs.set(attr.name.name, attr);
}
return attrs;
}
Example #5
Source File: plasmic-parser.ts From plasmic with MIT License | 6 votes |
tryGetNodeIdFromAttr = (attr: JSXAttribute | JSXSpreadAttribute) => {
if (attr.type === "JSXAttribute") {
if (isAttribute(attr, "className") && attr.value) {
let nodeId: string | undefined = undefined;
traverse(attr.value, {
noScope: true,
CallExpression: function (path) {
const member = tryExtractPropertyNameOfMemberExpression(
path.node.callee,
helperObject
);
const m = member?.match(/^cls(.+)$/);
if (m) {
nodeId = m[1];
path.stop();
}
},
});
return nodeId;
}
} else {
// spread
if (
attr.argument.type === "CallExpression" &&
attr.argument.callee.type === "MemberExpression"
) {
const member = tryExtractPropertyNameOfMemberExpression(
attr.argument.callee,
helperObject
);
const m = member?.match(/^props(.+)$/);
if (m) {
return m[1];
}
}
}
return undefined;
}
Example #6
Source File: utils.ts From plasmic with MIT License | 6 votes |
getAttrName = (attr: JSXAttribute) => {
const name = attr.name;
return name.type === "JSXIdentifier"
? name.name
: `${name.namespace.name}.${name.name.name}`;
}
Example #7
Source File: utils.ts From plasmic with MIT License | 6 votes |
isAttribute = (
attr: JSXAttribute | JSXSpreadAttribute,
expectedName: string
) => {
return attr.type === "JSXAttribute" && getAttrName(attr) === expectedName;
}
Example #8
Source File: visitor.ts From react-dev-inspector with MIT License | 6 votes |
doJSXOpeningElement: NodeHandler<
JSXOpeningElement,
{ relativePath: string }
> = (node, option) => {
const { stop } = doJSXPathName(node.name)
if (stop) return { stop }
const { relativePath } = option
const line = node.loc?.start.line
const column = node.loc?.start.column
const lineAttr: JSXAttribute | null = isNil(line)
? null
: jsxAttribute(
jsxIdentifier('data-inspector-line'),
stringLiteral(line.toString()),
)
const columnAttr: JSXAttribute | null = isNil(column)
? null
: jsxAttribute(
jsxIdentifier('data-inspector-column'),
stringLiteral(column.toString()),
)
const relativePathAttr: JSXAttribute = jsxAttribute(
jsxIdentifier('data-inspector-relative-path'),
stringLiteral(relativePath),
)
const attributes = [lineAttr, columnAttr, relativePathAttr] as JSXAttribute[]
// Make sure that there are exist together
if (attributes.every(Boolean)) {
node.attributes.unshift(...attributes)
}
return { result: node }
}
Example #9
Source File: jsxConverter.ts From react-native-decompiler with GNU Affero General Public License v3.0 | 5 votes |
private parseJsx(node: Expression): JSXText | JSXExpressionContainer | JSXSpreadChild | JSXElement | JSXFragment {
if (isStringLiteral(node)) {
return jsxText(node.value);
}
if (isCallExpression(node)) {
const args = node.arguments;
let name: JSXIdentifier | JSXMemberExpression | undefined;
if (isIdentifier(args[0]) || isStringLiteral(args[0])) {
name = jsxIdentifier(isIdentifier(args[0]) ? args[0].name : args[0].value);
} else if (isMemberExpression(args[0]) && isIdentifier(args[0].object) && isIdentifier(args[0].property)) {
name = jsxMemberExpression(jsxIdentifier(args[0].object.name), jsxIdentifier(args[0].property.name));
} else {
this.debugLog(`fail to parse component ${args[0].type} inside callExpression`);
return jsxExpressionContainer(node);
}
let props: JSXAttribute[] = [];
if (isObjectExpression(args[1])) {
props = args[1].properties.map((prop) => {
if (!isObjectProperty(prop) || !isIdentifier(prop.key)) return null;
if (isStringLiteral(prop.value)) {
return jsxAttribute(jsxIdentifier(prop.key.name), prop.value);
}
if (isBooleanLiteral(prop.value) && prop.value.value) {
return jsxAttribute(jsxIdentifier(prop.key.name), null);
}
if (isExpression(prop.value)) {
return jsxAttribute(jsxIdentifier(prop.key.name), jsxExpressionContainer(prop.value));
}
return null;
}).filter((e): e is JSXAttribute => e != null);
}
const children = args.slice(2).map((e) => (isExpression(e) ? this.parseJsx(e) : null)).filter((e): e is JSXElement => e != null);
if (children.length) {
return jsxElement(jsxOpeningElement(name, props), jsxClosingElement(name), children);
}
return jsxElement(jsxOpeningElement(name, props, true), null, []);
}
this.debugLog(`fail to parse component ${node.type}`);
return jsxExpressionContainer(node);
}
Example #10
Source File: img.ts From react-optimized-image with MIT License | 5 votes |
buildRawSrcAttribute = (
types: Babel['types'],
requireArgs: CallExpression['arguments'],
config: ImageConfig,
globalQuery: Record<string, string>,
): JSXAttribute => {
const properties: ObjectProperty[] = [];
['fallback', ...(config.webp ? ['webp'] : [])].forEach((type) => {
const typeProperties: ObjectProperty[] = [];
const query: Record<string, string> = type === 'webp' ? { ...globalQuery, webp: '' } : { ...globalQuery };
(config.sizes && config.sizes.length > 0 ? config.sizes : ['original']).forEach(
(size: number | string, index: number, allSizes: Array<number | string>) => {
const sizeProperties: ObjectProperty[] = [];
// only inline image if there is 1 size and no fallback
if (
typeof query.url === 'undefined' &&
typeof query.inline === 'undefined' &&
((type === 'fallback' && config.webp) || allSizes.length > 1 || (config.densities || [1]).length > 1)
) {
query.url = '';
}
(config.densities || [1]).forEach((density) => {
const sizeQuery: Record<string, string> = {
...query,
...(typeof size === 'number' ? { width: `${size * density}` } : {}),
};
sizeProperties.push(
types.objectProperty(
types.numericLiteral(density),
buildRequireStatement(types, clone(requireArgs), sizeQuery),
),
);
});
typeProperties.push(
types.objectProperty(
typeof size === 'string' ? types.identifier(size) : types.numericLiteral(size),
types.objectExpression(sizeProperties),
),
);
},
);
properties.push(types.objectProperty(types.identifier(type), types.objectExpression(typeProperties)));
});
return types.jsxAttribute(
types.jsxIdentifier('rawSrc'),
types.jsxExpressionContainer(types.objectExpression(properties)),
);
}
Example #11
Source File: jsxConverter.ts From react-native-decompiler with GNU Affero General Public License v3.0 | 5 votes |
private parseJsx(node: Expression): JSXText | JSXExpressionContainer | JSXSpreadChild | JSXElement | JSXFragment {
if (isStringLiteral(node)) {
return jsxText(node.value);
}
if (isCallExpression(node)) {
const args = node.arguments;
let name: JSXIdentifier | JSXMemberExpression | undefined;
if (isIdentifier(args[0]) || isStringLiteral(args[0])) {
name = jsxIdentifier(isIdentifier(args[0]) ? args[0].name : args[0].value);
} else if (isMemberExpression(args[0]) && isIdentifier(args[0].object) && isIdentifier(args[0].property)) {
name = jsxMemberExpression(jsxIdentifier(args[0].object.name), jsxIdentifier(args[0].property.name));
} else {
this.debugLog(`fail to parse component ${args[0].type} inside callExpression`);
return jsxExpressionContainer(node);
}
let props: JSXAttribute[] = [];
if (isObjectExpression(args[1])) {
props = args[1].properties.map((prop) => {
if (!isObjectProperty(prop) || !isIdentifier(prop.key)) return null;
if (isStringLiteral(prop.value)) {
return jsxAttribute(jsxIdentifier(prop.key.name), prop.value);
}
if (isBooleanLiteral(prop.value) && prop.value.value) {
return jsxAttribute(jsxIdentifier(prop.key.name), null);
}
if (isExpression(prop.value)) {
return jsxAttribute(jsxIdentifier(prop.key.name), jsxExpressionContainer(prop.value));
}
return null;
}).filter((e): e is JSXAttribute => e != null);
}
const children = args.slice(2).map((e) => (isExpression(e) ? this.parseJsx(e) : null)).filter((e): e is JSXElement => e != null);
if (children.length) {
return jsxElement(jsxOpeningElement(name, props), jsxClosingElement(name), children);
}
return jsxElement(jsxOpeningElement(name, props, true), null, []);
}
this.debugLog(`fail to parse component ${node.type}`);
return jsxExpressionContainer(node);
}
Example #12
Source File: index.ts From tailchat with GNU General Public License v3.0 | 5 votes |
async function loader(this: LoaderContext<any>, source: string): Promise<void> {
const done = this.async();
const { available } = this.getOptions();
if (!available) {
// skip if not
done(null, source);
return;
}
const ast = parse(source, {
sourceType: 'module',
plugins: ['jsx', 'typescript'],
});
const filepath = this.resourcePath;
if (filepath.includes('node_modules')) {
done(null, source);
return;
}
traverse(ast, {
JSXOpeningElement(path) {
const location = path.node.loc;
if (!location) {
return;
}
if (Array.isArray(location)) {
return;
}
const name = path.node.name;
if (isJSXIdentifier(name) && name.name === 'Fragment') {
return;
}
if (isJSXMemberExpression(name) && name.property.name === 'Fragment') {
return;
}
const line = location.start.line;
const col = location.start.column;
const attrs = path.node.attributes;
for (let i = 0; i < attrs.length; i++) {
const attr = attrs[i];
if (attr.type === 'JSXAttribute' && attr.name.name === TRACE_ID) {
// existed
return;
}
}
const traceId = `${filepath}:${line}:${col}`;
attrs.push(jsxAttribute(jsxIdentifier(TRACE_ID), stringLiteral(traceId)));
},
});
const code = generate(ast).code;
done(null, code);
}
Example #13
Source File: index.ts From tailchat with GNU General Public License v3.0 | 5 votes |
export default function sourceRef(): Plugin {
return {
name: 'source-ref',
transform(code, id) {
const filepath = id;
const ast = parse(code, {
sourceType: 'module',
plugins: ['jsx', 'typescript'],
});
traverse(ast, {
JSXOpeningElement(path) {
const location = path.node.loc;
if (!location) {
return;
}
if (Array.isArray(location)) {
return;
}
const name = path.node.name;
if (isJSXIdentifier(name) && name.name === 'Fragment') {
return;
}
if (
isJSXMemberExpression(name) &&
name.property.name === 'Fragment'
) {
return;
}
const line = location.start.line;
const col = location.start.column;
const attrs = path.node.attributes;
for (let i = 0; i < attrs.length; i++) {
const attr = attrs[i];
if (attr.type === 'JSXAttribute' && attr.name.name === TRACE_ID) {
// existed
return;
}
}
const traceId = `${filepath}:${line}:${col}`;
attrs.push(
jsxAttribute(jsxIdentifier(TRACE_ID), stringLiteral(traceId))
);
},
});
const res = generate(ast);
return { code: res.code, map: res.map };
},
};
}
Example #14
Source File: jsxConverter.ts From react-native-decompiler with GNU Affero General Public License v3.0 | 5 votes |
private parseJsx(node: Expression): JSXText | JSXExpressionContainer | JSXSpreadChild | JSXElement | JSXFragment {
if (isStringLiteral(node)) {
return jsxText(node.value);
}
if (isCallExpression(node)) {
const args = node.arguments;
let name: JSXIdentifier | JSXMemberExpression | undefined;
if (isIdentifier(args[0]) || isStringLiteral(args[0])) {
name = jsxIdentifier(isIdentifier(args[0]) ? args[0].name : args[0].value);
} else if (isMemberExpression(args[0]) && isIdentifier(args[0].object) && isIdentifier(args[0].property)) {
name = jsxMemberExpression(jsxIdentifier(args[0].object.name), jsxIdentifier(args[0].property.name));
} else {
this.debugLog(`fail to parse component ${args[0].type} inside callExpression`);
return jsxExpressionContainer(node);
}
let props: JSXAttribute[] = [];
if (isObjectExpression(args[1])) {
props = args[1].properties.map((prop) => {
if (!isObjectProperty(prop) || !isIdentifier(prop.key)) return null;
if (isStringLiteral(prop.value)) {
return jsxAttribute(jsxIdentifier(prop.key.name), prop.value);
}
if (isBooleanLiteral(prop.value) && prop.value.value) {
return jsxAttribute(jsxIdentifier(prop.key.name), null);
}
if (isExpression(prop.value)) {
return jsxAttribute(jsxIdentifier(prop.key.name), jsxExpressionContainer(prop.value));
}
return null;
}).filter((e): e is JSXAttribute => e != null);
}
const children = args.slice(2).map((e) => (isExpression(e) ? this.parseJsx(e) : null)).filter((e): e is JSXElement => e != null);
if (children.length) {
return jsxElement(jsxOpeningElement(name, props), jsxClosingElement(name), children);
}
return jsxElement(jsxOpeningElement(name, props, true), null, []);
}
this.debugLog(`fail to parse component ${node.type}`);
return jsxExpressionContainer(node);
}
Example #15
Source File: jsxConverter.ts From react-native-decompiler with GNU Affero General Public License v3.0 | 5 votes |
private parseJsx(node: Expression): JSXText | JSXExpressionContainer | JSXSpreadChild | JSXElement | JSXFragment {
if (isStringLiteral(node)) {
return jsxText(node.value);
}
if (isCallExpression(node)) {
const args = node.arguments;
let name: JSXIdentifier | JSXMemberExpression | undefined;
if (isIdentifier(args[0]) || isStringLiteral(args[0])) {
name = jsxIdentifier(isIdentifier(args[0]) ? args[0].name : args[0].value);
} else if (isMemberExpression(args[0]) && isIdentifier(args[0].object) && isIdentifier(args[0].property)) {
name = jsxMemberExpression(jsxIdentifier(args[0].object.name), jsxIdentifier(args[0].property.name));
} else {
this.debugLog(`fail to parse component ${args[0].type} inside callExpression`);
return jsxExpressionContainer(node);
}
let props: JSXAttribute[] = [];
if (isObjectExpression(args[1])) {
props = args[1].properties.map((prop) => {
if (!isObjectProperty(prop) || !isIdentifier(prop.key)) return null;
if (isStringLiteral(prop.value)) {
return jsxAttribute(jsxIdentifier(prop.key.name), prop.value);
}
if (isBooleanLiteral(prop.value) && prop.value.value) {
return jsxAttribute(jsxIdentifier(prop.key.name), null);
}
if (isExpression(prop.value)) {
return jsxAttribute(jsxIdentifier(prop.key.name), jsxExpressionContainer(prop.value));
}
return null;
}).filter((e): e is JSXAttribute => e != null);
}
const children = args.slice(2).map((e) => (isExpression(e) ? this.parseJsx(e) : null)).filter((e): e is JSXElement => e != null);
if (children.length) {
return jsxElement(jsxOpeningElement(name, props), jsxClosingElement(name), children);
}
return jsxElement(jsxOpeningElement(name, props, true), null, []);
}
this.debugLog(`fail to parse component ${node.type}`);
return jsxExpressionContainer(node);
}
Example #16
Source File: svg.ts From react-optimized-image with MIT License | 5 votes |
buildRawSrcAttribute = (types: Babel['types'], requireArgs: CallExpression['arguments']): JSXAttribute => {
return types.jsxAttribute(
types.jsxIdentifier('rawSrc'),
types.jsxExpressionContainer(buildRequireStatement(types, clone(requireArgs), { include: '' })),
);
}
Example #17
Source File: index.ts From plasmic with MIT License | 4 votes |
mergeAttributes = (
newNode: PlasmicTagOrComponent,
editedNode: PlasmicTagOrComponent,
baseNode: PlasmicTagOrComponent,
codeVersions: CodeVersions
) => {
const { newVersion, editedVersion } = codeVersions;
assert(editedNode.jsxElement.nameInId === newNode.jsxElement.nameInId);
assert(editedNode.jsxElement.nameInId === baseNode.jsxElement.nameInId);
const newNodePropsWithIdSpreador = newVersion.tryGetPropsIdSpreador(newNode);
const editedHasPropsWithIdSpreador = editedVersion.hasPropsIdSpreador(
editedNode
);
const newNamedAttrs = getRawNamedAttrs(newNode.jsxElement.rawNode);
const editedNamedAttrs = getRawNamedAttrs(editedNode.jsxElement.rawNode);
const baseNamedAttrs = getRawNamedAttrs(baseNode.jsxElement.rawNode);
const conflictResolution = (
name: string,
baseAttr: JSXAttribute | undefined,
editedAttr: JSXAttribute,
newAttr: JSXAttribute
) => {
// If attribute match, then emit either version is ok. Emitting it at the
// place where the edited version emitted at is probably safer, and less
// disturbing.
if (nodesDeepEqualIgnoreComments(editedAttr, newAttr)) {
return "emit-edited";
}
if (!baseAttr) {
// We don't know how to handle the conflict. Merge them and let developer
// handle it.
return "emit-merged";
}
if (nodesDeepEqualIgnoreComments(baseAttr, editedAttr)) {
// User didn't edit it. Emit the new version.
return "emit-new";
}
if (
name.startsWith("on") ||
(name === "value" &&
tagName(newNode.jsxElement.rawNode) === "PlasmicSlot") ||
nodesDeepEqualIgnoreComments(baseAttr, newAttr)
) {
// Plasmic doesn't change it. Emit the edited version then.
return "emit-edited";
}
// Both Plasmic and developer edited it. Emit both.
return "emit-merged";
};
const emitAttrInEditedNode = (attrName: string) => {
const editedAttr = ensure(editedNamedAttrs.get(attrName));
const newAttr = newNamedAttrs.get(attrName);
const baseAttr = baseNamedAttrs.get(attrName);
if (newAttr) {
const res = conflictResolution(attrName, baseAttr, editedAttr, newAttr);
if (res === "emit-new") {
// We emit the newAttr in place to minimize diff.
return newAttr;
} else if (res === "emit-merged") {
const value = mergeAttributeValue(
attrName,
newNode,
editedNode,
baseNode,
codeVersions
);
return babel.types.jsxAttribute(newAttr.name, value);
}
assert(res === "emit-edited");
return editedAttr;
} else if (!baseAttr) {
// user added attribute in edited version. Emit the edited attribute
// without any transformation.
return serializeNamedAttribute(
editedAttr.name,
findParsedNamedAttrs(editedNode, attrName),
codeVersions
);
} else {
// Attribute deleted in new version. However, user may have modified it.
// Delete it only if there is no modification; otherwise, keep it for user
// to fix the compilation failure.
return nodesDeepEqualIgnoreComments(baseAttr, editedAttr)
? undefined
: serializeNamedAttribute(
editedAttr.name,
findParsedNamedAttrs(editedNode, attrName),
codeVersions
);
}
};
const mergedAttrs: Array<JSXAttribute | JSXSpreadAttribute> = [];
newNamedAttrs.forEach((attr, name) => {
const editedAttr = editedNamedAttrs.get(name);
const baseAttr = baseNamedAttrs.get(name);
if (!baseAttr && !editedAttr) {
// newly added attribute in new version
mergedAttrs.push(
serializeNamedAttribute(
attr.name,
findParsedNamedAttrs(newNode, name),
codeVersions
)
);
}
});
for (const attrInEditedNode of editedNode.jsxElement.attrs) {
if (L.isArray(attrInEditedNode)) {
const toEmit = emitAttrInEditedNode(attrInEditedNode[0]);
if (toEmit) {
mergedAttrs.push(toEmit);
}
} else {
const serializedSpreador = serializeJsxSpreadAttribute(
attrInEditedNode,
!!newNodePropsWithIdSpreador,
newNode.jsxElement.nameInId,
codeVersions
);
if (serializedSpreador) {
mergedAttrs.push(serializedSpreador);
}
}
}
let classNameAt = mergedAttrs.findIndex((attr) =>
isAttribute(attr, "className")
);
// insert className if missing in edited version, mostly to support old code.
if (classNameAt === -1) {
const newClassNameAttr = newNamedAttrs.get("className");
if (newClassNameAttr) {
mergedAttrs.splice(0, 0, newClassNameAttr);
classNameAt = 0;
}
}
if (newNodePropsWithIdSpreador && !editedHasPropsWithIdSpreador) {
// insert the new spreador right after className if any, always
const insertSpreadorAt = classNameAt === -1 ? 0 : classNameAt + 1;
mergedAttrs.splice(insertSpreadorAt, 0, newNodePropsWithIdSpreador);
}
return mergedAttrs;
}