Initial commit: GamePortrait 竖屏版 - 深色豪华主题

This commit is contained in:
li
2026-01-16 17:47:53 +08:00
commit 40976e4b45
26611 changed files with 2843638 additions and 0 deletions
+304
View File
@@ -0,0 +1,304 @@
import { join } from 'path';
import { addSideEffect, addDefault, addNamed } from '@babel/helper-module-imports';
function transCamel(_str, symbol) {
const str = _str[0].toLowerCase() + _str.substr(1);
return str.replace(/([A-Z])/g, $1 => `${symbol}${$1.toLowerCase()}`);
}
function winPath(path) {
return path.replace(/\\/g, '/');
}
function normalizeCustomName(originCustomName) {
// If set to a string, treat it as a JavaScript source file path.
if (typeof originCustomName === 'string') {
// eslint-disable-next-line import/no-dynamic-require
const customNameExports = require(originCustomName);
return typeof customNameExports === 'function' ? customNameExports : customNameExports.default;
}
return originCustomName;
}
export default class Plugin {
constructor(
libraryName,
libraryDirectory,
style,
styleLibraryDirectory,
customStyleName,
camel2DashComponentName,
camel2UnderlineComponentName,
fileName,
customName,
transformToDefaultImport,
types,
index = 0,
) {
this.libraryName = libraryName;
this.libraryDirectory = typeof libraryDirectory === 'undefined' ? 'lib' : libraryDirectory;
this.camel2DashComponentName =
typeof camel2DashComponentName === 'undefined' ? true : camel2DashComponentName;
this.camel2UnderlineComponentName = camel2UnderlineComponentName;
this.style = style || false;
this.styleLibraryDirectory = styleLibraryDirectory;
this.customStyleName = normalizeCustomName(customStyleName);
this.fileName = fileName || '';
this.customName = normalizeCustomName(customName);
this.transformToDefaultImport =
typeof transformToDefaultImport === 'undefined' ? true : transformToDefaultImport;
this.types = types;
this.pluginStateKey = `importPluginState${index}`;
}
getPluginState(state) {
if (!state[this.pluginStateKey]) {
state[this.pluginStateKey] = {}; // eslint-disable-line
}
return state[this.pluginStateKey];
}
importMethod(methodName, file, pluginState) {
if (!pluginState.selectedMethods[methodName]) {
const { style, libraryDirectory } = this;
const transformedMethodName = this.camel2UnderlineComponentName // eslint-disable-line
? transCamel(methodName, '_')
: this.camel2DashComponentName
? transCamel(methodName, '-')
: methodName;
const path = winPath(
this.customName
? this.customName(transformedMethodName, file)
: join(this.libraryName, libraryDirectory, transformedMethodName, this.fileName), // eslint-disable-line
);
pluginState.selectedMethods[methodName] = this.transformToDefaultImport // eslint-disable-line
? addDefault(file.path, path, { nameHint: methodName })
: addNamed(file.path, methodName, path);
if (this.customStyleName) {
const stylePath = winPath(this.customStyleName(transformedMethodName, file));
addSideEffect(file.path, `${stylePath}`);
} else if (this.styleLibraryDirectory) {
const stylePath = winPath(
join(this.libraryName, this.styleLibraryDirectory, transformedMethodName, this.fileName),
);
addSideEffect(file.path, `${stylePath}`);
} else if (style === true) {
addSideEffect(file.path, `${path}/style`);
} else if (style === 'css') {
addSideEffect(file.path, `${path}/style/css`);
} else if (typeof style === 'function') {
const stylePath = style(path, file);
if (stylePath) {
addSideEffect(file.path, stylePath);
}
}
}
return { ...pluginState.selectedMethods[methodName] };
}
buildExpressionHandler(node, props, path, state) {
const file = (path && path.hub && path.hub.file) || (state && state.file);
const { types } = this;
const pluginState = this.getPluginState(state);
props.forEach(prop => {
if (!types.isIdentifier(node[prop])) return;
if (
pluginState.specified[node[prop].name] &&
types.isImportSpecifier(path.scope.getBinding(node[prop].name).path)
) {
node[prop] = this.importMethod(pluginState.specified[node[prop].name], file, pluginState); // eslint-disable-line
}
});
}
buildDeclaratorHandler(node, prop, path, state) {
const file = (path && path.hub && path.hub.file) || (state && state.file);
const { types } = this;
const pluginState = this.getPluginState(state);
const checkScope = targetNode =>
pluginState.specified[targetNode.name] && // eslint-disable-line
path.scope.hasBinding(targetNode.name) && // eslint-disable-line
path.scope.getBinding(targetNode.name).path.type === 'ImportSpecifier'; // eslint-disable-line
if (types.isIdentifier(node[prop]) && checkScope(node[prop])) {
node[prop] = this.importMethod(pluginState.specified[node[prop].name], file, pluginState); // eslint-disable-line
} else if (types.isSequenceExpression(node[prop])) {
node[prop].expressions.forEach((expressionNode, index) => {
if (types.isIdentifier(expressionNode) && checkScope(expressionNode)) {
node[prop].expressions[index] = this.importMethod(
pluginState.specified[expressionNode.name],
file,
pluginState,
); // eslint-disable-line
}
});
}
}
ProgramEnter(path, state) {
const pluginState = this.getPluginState(state);
pluginState.specified = Object.create(null);
pluginState.libraryObjs = Object.create(null);
pluginState.selectedMethods = Object.create(null);
pluginState.pathsToRemove = [];
}
ProgramExit(path, state) {
this.getPluginState(state).pathsToRemove.forEach(p => !p.removed && p.remove());
}
ImportDeclaration(path, state) {
const { node } = path;
// path maybe removed by prev instances.
if (!node) return;
const { value } = node.source;
const { libraryName } = this;
const { types } = this;
const pluginState = this.getPluginState(state);
if (value === libraryName) {
node.specifiers.forEach(spec => {
if (types.isImportSpecifier(spec)) {
pluginState.specified[spec.local.name] = spec.imported.name;
} else {
pluginState.libraryObjs[spec.local.name] = true;
}
});
pluginState.pathsToRemove.push(path);
}
}
CallExpression(path, state) {
const { node } = path;
const file = (path && path.hub && path.hub.file) || (state && state.file);
const { name } = node.callee;
const { types } = this;
const pluginState = this.getPluginState(state);
if (types.isIdentifier(node.callee)) {
if (pluginState.specified[name]) {
node.callee = this.importMethod(pluginState.specified[name], file, pluginState);
}
}
node.arguments = node.arguments.map(arg => {
const { name: argName } = arg;
if (
pluginState.specified[argName] &&
path.scope.hasBinding(argName) &&
path.scope.getBinding(argName).path.type === 'ImportSpecifier'
) {
return this.importMethod(pluginState.specified[argName], file, pluginState);
}
return arg;
});
}
MemberExpression(path, state) {
const { node } = path;
const file = (path && path.hub && path.hub.file) || (state && state.file);
const pluginState = this.getPluginState(state);
// multiple instance check.
if (!node.object || !node.object.name) return;
if (pluginState.libraryObjs[node.object.name]) {
// antd.Button -> _Button
path.replaceWith(this.importMethod(node.property.name, file, pluginState));
} else if (pluginState.specified[node.object.name] && path.scope.hasBinding(node.object.name)) {
const { scope } = path.scope.getBinding(node.object.name);
// global variable in file scope
if (scope.path.parent.type === 'File') {
node.object = this.importMethod(pluginState.specified[node.object.name], file, pluginState);
}
}
}
Property(path, state) {
const { node } = path;
this.buildDeclaratorHandler(node, 'value', path, state);
}
VariableDeclarator(path, state) {
const { node } = path;
this.buildDeclaratorHandler(node, 'init', path, state);
}
ArrayExpression(path, state) {
const { node } = path;
const props = node.elements.map((_, index) => index);
this.buildExpressionHandler(node.elements, props, path, state);
}
LogicalExpression(path, state) {
const { node } = path;
this.buildExpressionHandler(node, ['left', 'right'], path, state);
}
ConditionalExpression(path, state) {
const { node } = path;
this.buildExpressionHandler(node, ['test', 'consequent', 'alternate'], path, state);
}
IfStatement(path, state) {
const { node } = path;
this.buildExpressionHandler(node, ['test'], path, state);
this.buildExpressionHandler(node.test, ['left', 'right'], path, state);
}
ExpressionStatement(path, state) {
const { node } = path;
const { types } = this;
if (types.isAssignmentExpression(node.expression)) {
this.buildExpressionHandler(node.expression, ['right'], path, state);
}
}
ReturnStatement(path, state) {
const { node } = path;
this.buildExpressionHandler(node, ['argument'], path, state);
}
ExportDefaultDeclaration(path, state) {
const { node } = path;
this.buildExpressionHandler(node, ['declaration'], path, state);
}
BinaryExpression(path, state) {
const { node } = path;
this.buildExpressionHandler(node, ['left', 'right'], path, state);
}
NewExpression(path, state) {
const { node } = path;
this.buildExpressionHandler(node, ['callee'], path, state);
const argumentsProps = node.arguments.map((_, index) => index);
this.buildExpressionHandler(node.arguments, argumentsProps, path, state);
}
SwitchStatement(path, state) {
const { node } = path;
this.buildExpressionHandler(node, ['discriminant'], path, state);
}
SwitchCase(path, state) {
const { node } = path;
this.buildExpressionHandler(node, ['test'], path, state);
}
ClassDeclaration(path, state) {
const { node } = path;
this.buildExpressionHandler(node, ['superClass'], path, state);
}
SequenceExpression(path, state) {
const { node } = path;
const expressionsProps = node.expressions.map((_, index) => index);
this.buildExpressionHandler(node.expressions, expressionsProps, path, state);
}
}
+120
View File
@@ -0,0 +1,120 @@
import assert from 'assert';
import Plugin from './Plugin';
export default function ({ types }) {
let plugins = null;
// Only for test
// eslint-disable-next-line no-underscore-dangle
global.__clearBabelAntdPlugin = () => {
plugins = null;
};
function applyInstance(method, args, context) {
// eslint-disable-next-line no-restricted-syntax
for (const plugin of plugins) {
if (plugin[method]) {
plugin[method].apply(plugin, [...args, context]);
}
}
}
const Program = {
enter(path, { opts = {} }) {
// Init plugin instances once.
if (!plugins) {
if (Array.isArray(opts)) {
plugins = opts.map(
(
{
libraryName,
libraryDirectory,
style,
styleLibraryDirectory,
customStyleName,
camel2DashComponentName,
camel2UnderlineComponentName,
fileName,
customName,
transformToDefaultImport,
},
index,
) => {
assert(libraryName, 'libraryName should be provided');
return new Plugin(
libraryName,
libraryDirectory,
style,
styleLibraryDirectory,
customStyleName,
camel2DashComponentName,
camel2UnderlineComponentName,
fileName,
customName,
transformToDefaultImport,
types,
index,
);
},
);
} else {
assert(opts.libraryName, 'libraryName should be provided');
plugins = [
new Plugin(
opts.libraryName,
opts.libraryDirectory,
opts.style,
opts.styleLibraryDirectory,
opts.customStyleName,
opts.camel2DashComponentName,
opts.camel2UnderlineComponentName,
opts.fileName,
opts.customName,
opts.transformToDefaultImport,
types,
),
];
}
}
applyInstance('ProgramEnter', arguments, this); // eslint-disable-line
},
exit() {
applyInstance('ProgramExit', arguments, this); // eslint-disable-line
},
};
const methods = [
'ImportDeclaration',
'CallExpression',
'MemberExpression',
'Property',
'VariableDeclarator',
'ArrayExpression',
'LogicalExpression',
'ConditionalExpression',
'IfStatement',
'ExpressionStatement',
'ReturnStatement',
'ExportDefaultDeclaration',
'BinaryExpression',
'NewExpression',
'ClassDeclaration',
'SwitchStatement',
'SwitchCase',
'SequenceExpression',
];
const ret = {
visitor: { Program },
};
// eslint-disable-next-line no-restricted-syntax
for (const method of methods) {
ret.visitor[method] = function () {
// eslint-disable-line
applyInstance(method, arguments, ret.visitor); // eslint-disable-line
};
}
return ret;
}